varlock 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/auto-load.js +2 -2
  2. package/dist/chunk-3I5FHXMJ.js +162 -0
  3. package/dist/chunk-3I5FHXMJ.js.map +1 -0
  4. package/dist/{chunk-EQGPMXDI.js → chunk-3LT4WWHG.js} +6 -5
  5. package/dist/chunk-3LT4WWHG.js.map +1 -0
  6. package/dist/{chunk-UGUCGDKH.js → chunk-AJCLNVYI.js} +6 -5
  7. package/dist/chunk-AJCLNVYI.js.map +1 -0
  8. package/dist/chunk-AKWP77PS.js +387 -0
  9. package/dist/chunk-AKWP77PS.js.map +1 -0
  10. package/dist/{chunk-GCEP6UVQ.js → chunk-BIIYEXRU.js} +4 -4
  11. package/dist/{chunk-GCEP6UVQ.js.map → chunk-BIIYEXRU.js.map} +1 -1
  12. package/dist/chunk-CHQDS2PI.js +138 -0
  13. package/dist/chunk-CHQDS2PI.js.map +1 -0
  14. package/dist/chunk-D5YM4IWS.js +79 -0
  15. package/dist/chunk-D5YM4IWS.js.map +1 -0
  16. package/dist/{chunk-WHSHSZQR.js → chunk-EBOBYFMY.js} +4 -4
  17. package/dist/{chunk-WHSHSZQR.js.map → chunk-EBOBYFMY.js.map} +1 -1
  18. package/dist/{chunk-4KSIULUK.js → chunk-EPWHAD6X.js} +5 -4
  19. package/dist/chunk-EPWHAD6X.js.map +1 -0
  20. package/dist/{chunk-B6SVDIAN.js → chunk-G2GPGCAP.js} +1435 -202
  21. package/dist/chunk-G2GPGCAP.js.map +1 -0
  22. package/dist/chunk-GXNQVEXD.js +15 -0
  23. package/dist/chunk-GXNQVEXD.js.map +1 -0
  24. package/dist/{chunk-BEV4WCAI.js → chunk-GYK3QFZB.js} +8 -4
  25. package/dist/chunk-GYK3QFZB.js.map +1 -0
  26. package/dist/{chunk-TQDVHRUW.js → chunk-LQ25CRHF.js} +7 -136
  27. package/dist/chunk-LQ25CRHF.js.map +1 -0
  28. package/dist/{chunk-4MCJ5H6K.js → chunk-MOXREUY6.js} +3 -3
  29. package/dist/{chunk-4MCJ5H6K.js.map → chunk-MOXREUY6.js.map} +1 -1
  30. package/dist/chunk-N5O4Z32O.js +74 -0
  31. package/dist/chunk-N5O4Z32O.js.map +1 -0
  32. package/dist/{chunk-MC4SUVBY.js → chunk-P4WZ2JXY.js} +5 -5
  33. package/dist/{chunk-MC4SUVBY.js.map → chunk-P4WZ2JXY.js.map} +1 -1
  34. package/dist/{chunk-WKQ6WUA7.js → chunk-TY6CHCQK.js} +6 -5
  35. package/dist/chunk-TY6CHCQK.js.map +1 -0
  36. package/dist/{chunk-JTK7LTYE.js → chunk-U3UHTU2X.js} +8 -17
  37. package/dist/chunk-U3UHTU2X.js.map +1 -0
  38. package/dist/{chunk-CHWXFSUK.js → chunk-WUI34NTD.js} +5 -5
  39. package/dist/{chunk-CHWXFSUK.js.map → chunk-WUI34NTD.js.map} +1 -1
  40. package/dist/cli/cli-executable.js +177 -26
  41. package/dist/cli/cli-executable.js.map +1 -1
  42. package/dist/config-item-I7ZL2FXU.js +5 -0
  43. package/dist/{config-item-VMLNH4QK.js.map → config-item-I7ZL2FXU.js.map} +1 -1
  44. package/dist/dotenv-compat.js +2 -2
  45. package/dist/{env-graph-BI5ASRYd.d.ts → env-graph-CwJhXKDk.d.ts} +51 -1
  46. package/dist/explain.command-IQOZKKSF.js +12 -0
  47. package/dist/explain.command-IQOZKKSF.js.map +1 -0
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.js +6 -5
  50. package/dist/index.js.map +1 -1
  51. package/dist/init.command-NVADFQ55.js +12 -0
  52. package/dist/{init.command-C2WNQ4UP.js.map → init.command-NVADFQ55.js.map} +1 -1
  53. package/dist/install-plugin.command-WE66PLU2.js +11 -0
  54. package/dist/install-plugin.command-WE66PLU2.js.map +1 -0
  55. package/dist/lib/exec-sync-varlock.d.ts +7 -0
  56. package/dist/lib/exec-sync-varlock.js +1 -1
  57. package/dist/load.command-NKKZAEE5.js +12 -0
  58. package/dist/{load.command-5X3BSCLF.js.map → load.command-NKKZAEE5.js.map} +1 -1
  59. package/dist/plugin-lib.d.ts +2 -2
  60. package/dist/printenv.command-TY5KCVC3.js +12 -0
  61. package/dist/{printenv.command-XZEQ3CZB.js.map → printenv.command-TY5KCVC3.js.map} +1 -1
  62. package/dist/run.command-PI2VAO7M.js +13 -0
  63. package/dist/{run.command-FE26WTNO.js.map → run.command-PI2VAO7M.js.map} +1 -1
  64. package/dist/runtime/env.d.ts +1 -1
  65. package/dist/scan.command-YIYJ6NTJ.js +14 -0
  66. package/dist/{scan.command-2M4RN4ZP.js.map → scan.command-YIYJ6NTJ.js.map} +1 -1
  67. package/dist/telemetry.command-WYD4SOWI.js +11 -0
  68. package/dist/{telemetry.command-SPOD3GAJ.js.map → telemetry.command-WYD4SOWI.js.map} +1 -1
  69. package/dist/typegen.command-5WQGI3CE.js +12 -0
  70. package/dist/{typegen.command-RUNVYBAM.js.map → typegen.command-5WQGI3CE.js.map} +1 -1
  71. package/package.json +1 -1
  72. package/dist/chunk-4KSIULUK.js.map +0 -1
  73. package/dist/chunk-B6SVDIAN.js.map +0 -1
  74. package/dist/chunk-BEV4WCAI.js.map +0 -1
  75. package/dist/chunk-EQGPMXDI.js.map +0 -1
  76. package/dist/chunk-JMJCAFEL.js +0 -1434
  77. package/dist/chunk-JMJCAFEL.js.map +0 -1
  78. package/dist/chunk-JTK7LTYE.js.map +0 -1
  79. package/dist/chunk-K6M42GW2.js +0 -59
  80. package/dist/chunk-K6M42GW2.js.map +0 -1
  81. package/dist/chunk-TQDVHRUW.js.map +0 -1
  82. package/dist/chunk-UGUCGDKH.js.map +0 -1
  83. package/dist/chunk-WKQ6WUA7.js.map +0 -1
  84. package/dist/config-item-VMLNH4QK.js +0 -5
  85. package/dist/init.command-C2WNQ4UP.js +0 -11
  86. package/dist/load.command-5X3BSCLF.js +0 -11
  87. package/dist/printenv.command-XZEQ3CZB.js +0 -11
  88. package/dist/run.command-FE26WTNO.js +0 -12
  89. package/dist/scan.command-2M4RN4ZP.js +0 -12
  90. package/dist/telemetry.command-SPOD3GAJ.js +0 -10
  91. package/dist/typegen.command-RUNVYBAM.js +0 -11
package/dist/auto-load.js CHANGED
@@ -1,7 +1,7 @@
1
- import './chunk-BEV4WCAI.js';
1
+ import './chunk-GYK3QFZB.js';
2
2
  import './chunk-LVZSZAKN.js';
3
3
  import './chunk-MYHVSJ3X.js';
4
- import './chunk-K6M42GW2.js';
4
+ import './chunk-N5O4Z32O.js';
5
5
  import './chunk-BC7LU4LG.js';
6
6
  import './chunk-IMB5QAZS.js';
7
7
  import './chunk-XLYSNOR3.js';
@@ -0,0 +1,162 @@
1
+ import { define } from './chunk-4A54P4EM.js';
2
+ import { checkForSchemaErrors, checkForNoEnvFiles } from './chunk-EPWHAD6X.js';
3
+ import { loadVarlockEnvGraph } from './chunk-BIIYEXRU.js';
4
+ import { gracefulExit } from './chunk-CHQDS2PI.js';
5
+ import { CliExitError, formattedValue } from './chunk-LQ25CRHF.js';
6
+ import { StaticValueResolver, ansis_default } from './chunk-G2GPGCAP.js';
7
+ import { my_dash_default } from './chunk-6CCHLM3U.js';
8
+ import { redactString } from './chunk-XLYSNOR3.js';
9
+ import { __name } from './chunk-6PEHRAEP.js';
10
+
11
+ // src/cli/commands/explain.command.ts
12
+ var commandSpec = define({
13
+ name: "explain",
14
+ description: "Show detailed information about how a config item is resolved",
15
+ args: {
16
+ env: {
17
+ type: "string",
18
+ description: "Set the environment (e.g., production, development, etc)"
19
+ },
20
+ path: {
21
+ type: "string",
22
+ short: "p",
23
+ description: "Path to a specific .env file or directory to use as the entry point"
24
+ }
25
+ },
26
+ examples: `
27
+ Shows detailed information about all definitions, sources, and overrides
28
+ that feed into a single config item. Useful for debugging why a value
29
+ is not what you expect.
30
+
31
+ Examples:
32
+ varlock explain DATABASE_URL # Explain how DATABASE_URL is resolved
33
+ varlock explain --env production API_KEY # Explain in production context
34
+ `.trim()
35
+ });
36
+ function describeResolver(resolver, indent = "") {
37
+ if (resolver instanceof StaticValueResolver) {
38
+ return `${indent}static value`;
39
+ }
40
+ const fnName = resolver.fnName;
41
+ if (fnName && !fnName.startsWith("\0")) {
42
+ return `${indent}${fnName}()`;
43
+ }
44
+ return `${indent}(resolver)`;
45
+ }
46
+ __name(describeResolver, "describeResolver");
47
+ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
48
+ const positionals = (ctx.positionals ?? []).slice(ctx.commandPath?.length ?? 0);
49
+ if (!positionals.length) {
50
+ throw new CliExitError("Missing required argument: variable name", {
51
+ suggestion: "Run `varlock explain MY_VAR` to explain a config item"
52
+ });
53
+ }
54
+ const varName = positionals[0];
55
+ const envGraph = await loadVarlockEnvGraph({
56
+ currentEnvFallback: ctx.values.env,
57
+ entryFilePath: ctx.values.path
58
+ });
59
+ checkForSchemaErrors(envGraph);
60
+ checkForNoEnvFiles(envGraph);
61
+ if (!(varName in envGraph.configSchema)) {
62
+ throw new CliExitError(`Variable "${varName}" not found in schema`);
63
+ }
64
+ await envGraph.resolveEnvValues();
65
+ const item = envGraph.configSchema[varName];
66
+ const isSensitive = item.isSensitive;
67
+ console.log("");
68
+ console.log(ansis_default.bold.cyan(` ${item.key}`));
69
+ console.log("");
70
+ if (item.description) {
71
+ console.log(` ${ansis_default.gray("Description:")} ${item.description}`);
72
+ }
73
+ if (item.dataType) {
74
+ console.log(` ${ansis_default.gray("Type:")} ${item.dataType.name}`);
75
+ }
76
+ const props = [];
77
+ if (item.isRequired) props.push("required");
78
+ else props.push("optional");
79
+ if (isSensitive) props.push("sensitive");
80
+ else props.push("public");
81
+ console.log(` ${ansis_default.gray("Properties:")} ${props.join(", ")}`);
82
+ console.log("");
83
+ console.log(ansis_default.bold(" Resolved value"));
84
+ if (item.validationState === "error") {
85
+ console.log(` ${ansis_default.red(" (resolution failed)")}`);
86
+ for (const err of item.errors) {
87
+ console.log(` ${ansis_default.red(` - ${err.message}`)}`);
88
+ }
89
+ } else {
90
+ let valStr = formattedValue(item.resolvedValue, true);
91
+ if (isSensitive && item.resolvedValue && my_dash_default.isString(item.resolvedValue)) {
92
+ valStr = redactString(item.resolvedValue);
93
+ }
94
+ console.log(` ${valStr}`);
95
+ if (item.isCoerced) {
96
+ let rawStr = formattedValue(item.resolvedRawValue, true);
97
+ if (isSensitive && item.resolvedRawValue && my_dash_default.isString(item.resolvedRawValue)) {
98
+ rawStr = redactString(item.resolvedRawValue);
99
+ }
100
+ console.log(` ${ansis_default.gray.italic(`coerced from ${rawStr}`)}`);
101
+ }
102
+ }
103
+ console.log("");
104
+ console.log(ansis_default.bold(" Value source"));
105
+ if (item.isOverridden) {
106
+ console.log(` ${ansis_default.yellow("\u26A1 process.env override")} ${ansis_default.yellow.bold("(active)")}`);
107
+ const activeValueDef = item.activeValueDef;
108
+ if (activeValueDef) {
109
+ const sourceLabel = activeValueDef.source?.label || "internal";
110
+ const resolverDesc = activeValueDef.itemDef.resolver ? describeResolver(activeValueDef.itemDef.resolver) : "no value";
111
+ console.log(` ${ansis_default.gray("\u2514")} ${ansis_default.gray.italic(`would use ${resolverDesc} from ${sourceLabel} without override`)}`);
112
+ }
113
+ } else {
114
+ const activeValueDef = item.activeValueDef;
115
+ if (activeValueDef) {
116
+ const sourceLabel = activeValueDef.source?.label || "internal";
117
+ const resolverDesc = activeValueDef.itemDef.resolver ? describeResolver(activeValueDef.itemDef.resolver) : "no value";
118
+ console.log(` ${resolverDesc} from ${ansis_default.cyan(sourceLabel)}`);
119
+ } else {
120
+ console.log(` ${ansis_default.gray("(no value set)")}`);
121
+ }
122
+ }
123
+ const defs = item.defs;
124
+ if (defs.length) {
125
+ console.log("");
126
+ console.log(ansis_default.bold(" All definitions") + ansis_default.gray(` (${defs.length} source${defs.length > 1 ? "s" : ""}, highest priority first)`));
127
+ for (let i = 0; i < defs.length; i++) {
128
+ const def = defs[i];
129
+ const sourceLabel = def.source?.label || "internal (builtin)";
130
+ const sourceType = def.source?.type || "builtin";
131
+ const isActiveSource = !item.isOverridden && def === item.activeValueDef;
132
+ const marker = isActiveSource ? ansis_default.green(" \u2190 active") : "";
133
+ console.log(` ${ansis_default.gray(`${i + 1}.`)} ${ansis_default.cyan(sourceLabel)} ${ansis_default.gray(`(${sourceType})`)}${marker}`);
134
+ if (def.itemDef.resolver) {
135
+ console.log(` ${ansis_default.gray("value:")} ${describeResolver(def.itemDef.resolver)}`);
136
+ } else {
137
+ console.log(` ${ansis_default.gray("value:")} ${ansis_default.gray.italic("(none - decorators only)")}`);
138
+ }
139
+ const decNames = def.itemDef.decorators?.map((d) => `@${d.name}`).join(", ");
140
+ if (decNames) {
141
+ console.log(` ${ansis_default.gray("decorators:")} ${ansis_default.magenta(decNames)}`);
142
+ }
143
+ }
144
+ }
145
+ const docsLinks = item.docsLinks;
146
+ if (docsLinks.length) {
147
+ console.log("");
148
+ console.log(ansis_default.bold(" Documentation"));
149
+ for (const link of docsLinks) {
150
+ const label = link.description ? `${link.description}: ` : "";
151
+ console.log(` ${label}${ansis_default.underline(link.url)}`);
152
+ }
153
+ }
154
+ console.log("");
155
+ if (item.validationState === "error") {
156
+ gracefulExit(1);
157
+ }
158
+ }, "commandFn");
159
+
160
+ export { commandFn, commandSpec };
161
+ //# sourceMappingURL=chunk-3I5FHXMJ.js.map
162
+ //# sourceMappingURL=chunk-3I5FHXMJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/explain.command.ts"],"names":[],"mappings":"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","file":"chunk-3I5FHXMJ.js","sourcesContent":["import ansis from 'ansis';\nimport { define } from 'gunshi';\nimport { gracefulExit } from 'exit-hook';\n\nimport { loadVarlockEnvGraph } from '../../lib/load-graph';\nimport { formattedValue } from '../../lib/formatting';\nimport { redactString } from '../../runtime/lib/redaction';\nimport {\n checkForSchemaErrors, checkForNoEnvFiles,\n} from '../helpers/error-checks';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { CliExitError } from '../helpers/exit-error';\nimport { StaticValueResolver } from '../../env-graph/lib/resolver';\nimport _ from '@env-spec/utils/my-dash';\n\nexport const commandSpec = define({\n name: 'explain',\n description: 'Show detailed information about how a config item is resolved',\n args: {\n env: {\n type: 'string',\n description: 'Set the environment (e.g., production, development, etc)',\n },\n path: {\n type: 'string',\n short: 'p',\n description: 'Path to a specific .env file or directory to use as the entry point',\n },\n },\n examples: `\nShows detailed information about all definitions, sources, and overrides\nthat feed into a single config item. Useful for debugging why a value\nis not what you expect.\n\nExamples:\n varlock explain DATABASE_URL # Explain how DATABASE_URL is resolved\n varlock explain --env production API_KEY # Explain in production context\n`.trim(),\n});\n\nfunction describeResolver(resolver: any, indent = ''): string {\n if (resolver instanceof StaticValueResolver) {\n return `${indent}static value`;\n }\n const fnName = resolver.fnName;\n if (fnName && !fnName.startsWith('\\0')) {\n return `${indent}${fnName}()`;\n }\n return `${indent}(resolver)`;\n}\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n const positionals = (ctx.positionals ?? []).slice(ctx.commandPath?.length ?? 0);\n if (!positionals.length) {\n throw new CliExitError('Missing required argument: variable name', {\n suggestion: 'Run `varlock explain MY_VAR` to explain a config item',\n });\n }\n const varName = positionals[0];\n\n const envGraph = await loadVarlockEnvGraph({\n currentEnvFallback: ctx.values.env,\n entryFilePath: ctx.values.path,\n });\n\n checkForSchemaErrors(envGraph);\n checkForNoEnvFiles(envGraph);\n\n if (!(varName in envGraph.configSchema)) {\n throw new CliExitError(`Variable \"${varName}\" not found in schema`);\n }\n\n await envGraph.resolveEnvValues();\n\n const item = envGraph.configSchema[varName];\n const isSensitive = item.isSensitive;\n\n // Header\n console.log('');\n console.log(ansis.bold.cyan(` ${item.key}`));\n console.log('');\n\n // Description\n if (item.description) {\n console.log(` ${ansis.gray('Description:')} ${item.description}`);\n }\n\n // Type info\n if (item.dataType) {\n console.log(` ${ansis.gray('Type:')} ${item.dataType.name}`);\n }\n\n // Properties\n const props = [];\n if (item.isRequired) props.push('required');\n else props.push('optional');\n if (isSensitive) props.push('sensitive');\n else props.push('public');\n console.log(` ${ansis.gray('Properties:')} ${props.join(', ')}`);\n\n // Resolved value\n console.log('');\n console.log(ansis.bold(' Resolved value'));\n if (item.validationState === 'error') {\n console.log(` ${ansis.red(' (resolution failed)')}`);\n for (const err of item.errors) {\n console.log(` ${ansis.red(` - ${err.message}`)}`);\n }\n } else {\n let valStr = formattedValue(item.resolvedValue, true);\n if (isSensitive && item.resolvedValue && _.isString(item.resolvedValue)) {\n valStr = redactString(item.resolvedValue)!;\n }\n console.log(` ${valStr}`);\n if (item.isCoerced) {\n let rawStr = formattedValue(item.resolvedRawValue, true);\n if (isSensitive && item.resolvedRawValue && _.isString(item.resolvedRawValue)) {\n rawStr = redactString(item.resolvedRawValue)!;\n }\n console.log(` ${ansis.gray.italic(`coerced from ${rawStr}`)}`);\n }\n }\n\n // Value source\n console.log('');\n console.log(ansis.bold(' Value source'));\n\n if (item.isOverridden) {\n console.log(` ${ansis.yellow('⚡ process.env override')} ${ansis.yellow.bold('(active)')}`);\n const activeValueDef = item.activeValueDef;\n if (activeValueDef) {\n const sourceLabel = activeValueDef.source?.label || 'internal';\n const resolverDesc = activeValueDef.itemDef.resolver\n ? describeResolver(activeValueDef.itemDef.resolver)\n : 'no value';\n console.log(` ${ansis.gray('└')} ${ansis.gray.italic(`would use ${resolverDesc} from ${sourceLabel} without override`)}`);\n }\n } else {\n const activeValueDef = item.activeValueDef;\n if (activeValueDef) {\n const sourceLabel = activeValueDef.source?.label || 'internal';\n const resolverDesc = activeValueDef.itemDef.resolver\n ? describeResolver(activeValueDef.itemDef.resolver)\n : 'no value';\n console.log(` ${resolverDesc} from ${ansis.cyan(sourceLabel)}`);\n } else {\n console.log(` ${ansis.gray('(no value set)')}`);\n }\n }\n\n // All definitions\n const defs = item.defs;\n if (defs.length) {\n console.log('');\n console.log(ansis.bold(' All definitions') + ansis.gray(` (${defs.length} source${defs.length > 1 ? 's' : ''}, highest priority first)`));\n\n for (let i = 0; i < defs.length; i++) {\n const def = defs[i];\n const sourceLabel = def.source?.label || 'internal (builtin)';\n const sourceType = def.source?.type || 'builtin';\n\n const isActiveSource = !item.isOverridden && def === item.activeValueDef;\n const marker = isActiveSource ? ansis.green(' ← active') : '';\n\n console.log(` ${ansis.gray(`${i + 1}.`)} ${ansis.cyan(sourceLabel)} ${ansis.gray(`(${sourceType})`)}${marker}`);\n\n // Show resolver info\n if (def.itemDef.resolver) {\n console.log(` ${ansis.gray('value:')} ${describeResolver(def.itemDef.resolver)}`);\n } else {\n console.log(` ${ansis.gray('value:')} ${ansis.gray.italic('(none - decorators only)')}`);\n }\n\n // Show decorators from this definition\n const decNames = def.itemDef.decorators?.map((d) => `@${d.name}`).join(', ');\n if (decNames) {\n console.log(` ${ansis.gray('decorators:')} ${ansis.magenta(decNames)}`);\n }\n }\n }\n\n // Docs links\n const docsLinks = item.docsLinks;\n if (docsLinks.length) {\n console.log('');\n console.log(ansis.bold(' Documentation'));\n for (const link of docsLinks) {\n const label = link.description ? `${link.description}: ` : '';\n console.log(` ${label}${ansis.underline(link.url)}`);\n }\n }\n\n console.log('');\n\n if (item.validationState === 'error') {\n gracefulExit(1);\n }\n};\n"]}
@@ -1,7 +1,8 @@
1
- import { fmt } from './chunk-WHSHSZQR.js';
1
+ import { fmt } from './chunk-EBOBYFMY.js';
2
2
  import { define } from './chunk-4A54P4EM.js';
3
- import { CliExitError, gracefulExit } from './chunk-TQDVHRUW.js';
4
- import { getUserVarlockDir } from './chunk-B6SVDIAN.js';
3
+ import { gracefulExit } from './chunk-CHQDS2PI.js';
4
+ import { CliExitError } from './chunk-LQ25CRHF.js';
5
+ import { getUserVarlockDir } from './chunk-G2GPGCAP.js';
5
6
  import { __name } from './chunk-6PEHRAEP.js';
6
7
  import { join } from 'path';
7
8
  import { mkdir, readFile, writeFile } from 'fs/promises';
@@ -62,5 +63,5 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
62
63
  }, "commandFn");
63
64
 
64
65
  export { commandFn, commandSpec };
65
- //# sourceMappingURL=chunk-EQGPMXDI.js.map
66
- //# sourceMappingURL=chunk-EQGPMXDI.js.map
66
+ //# sourceMappingURL=chunk-3LT4WWHG.js.map
67
+ //# sourceMappingURL=chunk-3LT4WWHG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/telemetry.command.ts"],"names":[],"mappings":";;;;;;;;;;AAWO,IAAM,cAAc,MAAA,CAAO;AAAA,EAChC,IAAA,EAAM,WAAA;AAAA,EACN,WAAA,EAAa,0CAAA;AAAA,EACb,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,YAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,QAAA,EAAU;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,EAAA,CAAA,CAWR,IAAA;AACJ,CAAC;AAEM,IAAM,SAAA,iCAA6D,GAAA,KAAQ;AAEhF,EAAA,IAAI,CAAC,CAAC,QAAA,EAAU,SAAS,EAAE,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,EAAG;AACpD,IAAA,MAAM,IAAI,aAAa,8CAAA,EAAgD;AAAA,MACrE,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,SAAA,EAAW,aAAa,CAAA;AAEhD,EAAA,IAAI;AAEF,IAAA,IAAI,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AAC1B,MAAA,MAAM,KAAA,CAAM,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IAC5C;AAGA,IAAA,IAAI,SAA8B,EAAC;AACnC,IAAA,IAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,MAAA,MAAM,aAAA,GAAgB,MAAM,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AACxD,MAAA,MAAA,GAAS,IAAA,CAAK,MAAM,aAAa,CAAA;AAAA,IACnC;AAGA,IAAA,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,KAAS,SAAA,SAAkB,iBAAA,GAAoB,IAAA;AAAA,gBAClD,MAAA,CAAO,iBAAA;AACnB,IAAA,MAAM,UAAU,UAAA,EAAY,IAAA,CAAK,UAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAE3D,IAAA,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU;AAChC,MAAA,OAAA,CAAQ,IAAI,uDAAkD,CAAA;AAAA,IAChE,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAI,wDAAmD,CAAA;AAAA,IACjE;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,aAAA,EAAe,GAAA,CAAI,QAAA,CAAS,UAAU,CAAC,CAAA;AAAA,EACrD,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,mCAAmC,KAAK,CAAA;AACtD,IAAA,OAAO,aAAa,CAAC,CAAA;AAAA,EACvB;AACF,CAAA,EAvCmE,WAAA","file":"chunk-3LT4WWHG.js","sourcesContent":["import { join } from 'node:path';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { define } from 'gunshi';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { gracefulExit } from 'exit-hook';\nimport { fmt } from '../helpers/pretty-format';\nimport { CliExitError } from '../helpers/exit-error';\nimport { getUserVarlockDir } from '../../lib/user-config-dir';\n\n\nexport const commandSpec = define({\n name: 'telemetry',\n description: 'Enable/disable anonymous usage analytics',\n args: {\n mode: {\n type: 'positional',\n description: '\"enable\" or \"disable\"',\n },\n },\n examples: `\nOpts in/out of anonymous usage analytics. This command creates/updates a configuration\nfile at $XDG_CONFIG_HOME/varlock/config.json (or ~/.config/varlock/config.json) saving\nyour preference.\n\nExamples:\n varlock telemetry disable # Opt out of telemetry\n varlock telemetry enable # Opt in to telemetry\n\n💡 Tip: You can also temporarily opt out by setting VARLOCK_TELEMETRY_DISABLED=1\nFor more information, visit https://varlock.dev/guides/telemetry/\n `.trim(),\n});\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n // TODO: remove this when gunshi supports types/validation for positional args\n if (!['enable', 'disable'].includes(ctx.values.mode)) {\n throw new CliExitError('additional arg must be \"enable\" or \"disable\"', {\n forceExit: true,\n });\n }\n\n const configDir = getUserVarlockDir();\n const configPath = join(configDir, 'config.json');\n\n try {\n // Create .varlock directory if it doesn't exist\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n // Read existing config if it exists\n let config: Record<string, any> = {};\n if (existsSync(configPath)) {\n const configContent = await readFile(configPath, 'utf-8');\n config = JSON.parse(configContent);\n }\n\n // update config `telemetryDisabled` setting\n if (ctx.values.mode === 'disable') config.telemetryDisabled = true;\n else delete config.telemetryDisabled;\n await writeFile(configPath, JSON.stringify(config, null, 2));\n\n if (ctx.values.mode === 'enable') {\n console.log('✅ Successfully enabled anonymous usage analytics');\n } else {\n console.log('✅ Successfully disabled anonymous usage analytics');\n }\n console.log('> saved in:', fmt.filePath(configPath));\n } catch (error) {\n console.error('Failed to opt out of analytics:', error);\n return gracefulExit(1);\n }\n};\n"]}
@@ -1,7 +1,8 @@
1
1
  import { define } from './chunk-4A54P4EM.js';
2
- import { checkForSchemaErrors } from './chunk-4KSIULUK.js';
3
- import { loadVarlockEnvGraph } from './chunk-GCEP6UVQ.js';
4
- import { CliExitError, gracefulExit } from './chunk-TQDVHRUW.js';
2
+ import { checkForSchemaErrors } from './chunk-EPWHAD6X.js';
3
+ import { loadVarlockEnvGraph } from './chunk-BIIYEXRU.js';
4
+ import { gracefulExit } from './chunk-CHQDS2PI.js';
5
+ import { CliExitError } from './chunk-LQ25CRHF.js';
5
6
  import { __name } from './chunk-6PEHRAEP.js';
6
7
 
7
8
  // src/cli/commands/printenv.command.ts
@@ -63,5 +64,5 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
63
64
  }, "commandFn");
64
65
 
65
66
  export { commandFn, commandSpec };
66
- //# sourceMappingURL=chunk-UGUCGDKH.js.map
67
- //# sourceMappingURL=chunk-UGUCGDKH.js.map
67
+ //# sourceMappingURL=chunk-AJCLNVYI.js.map
68
+ //# sourceMappingURL=chunk-AJCLNVYI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/printenv.command.ts"],"names":[],"mappings":";;;;;;;;AAQO,IAAM,cAAc,MAAA,CAAO;AAAA,EAChC,IAAA,EAAM,UAAA;AAAA,EACN,WAAA,EAAa,2DAAA;AAAA,EACb,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,QAAA;AAAA,MACN,KAAA,EAAO,GAAA;AAAA,MACP,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,QAAA,EAAU;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,EAAA,CAAA,CAcR,IAAA;AACJ,CAAC;AAEM,IAAM,SAAA,iCAA6D,GAAA,KAAQ;AAGhF,EAAA,MAAM,WAAA,GAAA,CAAe,IAAI,WAAA,IAAe,IAAI,KAAA,CAAM,GAAA,CAAI,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA;AAC9E,EAAA,IAAI,CAAC,YAAY,MAAA,EAAQ;AACvB,IAAA,MAAM,IAAI,aAAa,0CAAA,EAA4C;AAAA,MACjE,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AACA,EAAA,MAAM,OAAA,GAAU,YAAY,CAAC,CAAA;AAE7B,EAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB;AAAA,IACzC,aAAA,EAAe,IAAI,MAAA,CAAO;AAAA,GAC3B,CAAA;AACD,EAAA,oBAAA,CAAqB,QAAQ,CAAA;AAE7B,EAAA,IAAI,EAAE,OAAA,IAAW,QAAA,CAAS,YAAA,CAAA,EAAe;AACvC,IAAA,MAAM,IAAI,YAAA,CAAa,CAAA,UAAA,EAAa,OAAO,CAAA,qBAAA,CAAuB,CAAA;AAAA,EACpE;AAGA,EAAA,MAAM,QAAA,CAAS,oBAAoB,OAAO,CAAA;AAE1C,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,YAAA,CAAa,OAAO,CAAA;AAC1C,EAAA,IAAI,IAAA,CAAK,oBAAoB,OAAA,EAAS;AACpC,IAAA,KAAA,MAAW,GAAA,IAAO,KAAK,MAAA,EAAQ;AAC7B,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,UAAA,EAAM,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AAAA,IACnC;AACA,IAAA,OAAO,aAAa,CAAC,CAAA;AAAA,EACvB;AAEA,EAAA,MAAM,QAAQ,IAAA,CAAK,aAAA;AACnB,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAAA,EAChB,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC3B;AACF,CAAA,EArCmE,WAAA","file":"chunk-AJCLNVYI.js","sourcesContent":["import { define } from 'gunshi';\nimport { gracefulExit } from 'exit-hook';\n\nimport { loadVarlockEnvGraph } from '../../lib/load-graph';\nimport { checkForSchemaErrors } from '../helpers/error-checks';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { CliExitError } from '../helpers/exit-error';\n\nexport const commandSpec = define({\n name: 'printenv',\n description: 'Print the resolved value of a single environment variable',\n args: {\n path: {\n type: 'string',\n short: 'p',\n description: 'Path to a specific .env file or directory (with trailing slash) to use as the entry point',\n },\n },\n examples: `\nPrints the resolved value of a single environment variable.\nUseful within larger shell commands where you need a single env var value.\n\nExamples:\n varlock printenv MY_VAR # Print the value of MY_VAR\n varlock printenv --path .env.prod MY_VAR # Use a specific .env file\n varlock printenv --path ./config/ MY_VAR # Use a specific directory\n\n📍 Note: Use sh -c to embed this in shell commands, e.g.:\n sh -c 'do-something --token $(varlock printenv MY_TOKEN)'\n\n💡 Tip: Unlike \\`varlock run -- echo $MY_VAR\\`, this works because the shell\n expansion happens after varlock has printed the value.\n `.trim(),\n});\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n // ctx.positionals includes the subcommand name(s) themselves, so we skip them\n // by slicing off ctx.commandPath.length entries (e.g. skips 'printenv' at index 0)\n const positionals = (ctx.positionals ?? []).slice(ctx.commandPath?.length ?? 0);\n if (!positionals.length) {\n throw new CliExitError('Missing required argument: variable name', {\n suggestion: 'Run `varlock printenv MY_VAR` to print the value of MY_VAR',\n });\n }\n const varName = positionals[0];\n\n const envGraph = await loadVarlockEnvGraph({\n entryFilePath: ctx.values.path,\n });\n checkForSchemaErrors(envGraph);\n\n if (!(varName in envGraph.configSchema)) {\n throw new CliExitError(`Variable \"${varName}\" not found in schema`);\n }\n\n // Resolve only the requested item and its transitive dependencies\n await envGraph.resolveItemWithDeps(varName);\n\n const item = envGraph.configSchema[varName];\n if (item.validationState === 'error') {\n for (const err of item.errors) {\n console.error(`🚨 ${err.message}`);\n }\n return gracefulExit(1);\n }\n\n const value = item.resolvedValue;\n if (value === undefined || value === null) {\n console.log('');\n } else {\n console.log(String(value));\n }\n};\n"]}
@@ -0,0 +1,387 @@
1
+ import { spawnAsync } from './chunk-GGBNUVWR.js';
2
+ import { detectJsPackageManager, logLines, fmt, installJsDependency } from './chunk-EBOBYFMY.js';
3
+ import { define } from './chunk-4A54P4EM.js';
4
+ import { gracefulExit } from './chunk-CHQDS2PI.js';
5
+ import { envSpecUpdater, ParsedEnvSpecStaticValue, tryCatch, parseEnvSpecDotEnvFile, Jt, Ct, ansis_default, prompts_default, pathExists } from './chunk-G2GPGCAP.js';
6
+ import { __name } from './chunk-6PEHRAEP.js';
7
+ import path2, { dirname } from 'path';
8
+ import fs3 from 'fs/promises';
9
+
10
+ async function checkIsFileGitIgnored(path3, warnIfNotGitRepo = false) {
11
+ try {
12
+ await spawnAsync("git", ["check-ignore", path3, "-q"], { cwd: dirname(path3) });
13
+ return true;
14
+ } catch (err) {
15
+ const errorOutput = err.data;
16
+ if (err.exitCode === 127 || errorOutput.includes("not found") || errorOutput.includes("not recognized")) {
17
+ return void 0;
18
+ }
19
+ if (err.code === "ENOENT") return void 0;
20
+ if (errorOutput === "") return false;
21
+ if (errorOutput.includes("not a git repository")) {
22
+ if (warnIfNotGitRepo) {
23
+ console.log("\u{1F536} Your code is not currently in a git repository - run `git init` to initialize a new repo.");
24
+ }
25
+ return false;
26
+ }
27
+ if (errorOutput.includes("is outside repository")) {
28
+ return void 0;
29
+ }
30
+ throw err;
31
+ }
32
+ }
33
+ __name(checkIsFileGitIgnored, "checkIsFileGitIgnored");
34
+ var PUBLIC_PREFIXES = [
35
+ "PUBLIC",
36
+ "VITE",
37
+ "NEXT_PUBLIC",
38
+ "NUXT_PUBLIC"
39
+ ];
40
+ var PUBLIC_KEYWORDS = ["PUBLIC"];
41
+ var SENSITIVE_KEYWORDS = [
42
+ "SECRET",
43
+ "API_KEY",
44
+ "PASSWORD",
45
+ "TOKEN",
46
+ "PRIVATE",
47
+ "CREDENTIALS"
48
+ ];
49
+ function isValidUrl(val) {
50
+ try {
51
+ const u = new URL(val);
52
+ return true;
53
+ } catch (err) {
54
+ return false;
55
+ }
56
+ }
57
+ __name(isValidUrl, "isValidUrl");
58
+ 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
+ var VALID_NUMBER_REGEX = /^(0|([1-9][0-9]*))?(\.[0-9]+)?$/;
60
+ function inferItemDecorators(file, itemKey, valueStr) {
61
+ let itemIsPublic = false;
62
+ if (PUBLIC_PREFIXES.some((prefix) => itemKey.startsWith(prefix))) itemIsPublic = true;
63
+ if (PUBLIC_KEYWORDS.some((keyword) => itemKey.includes(keyword))) itemIsPublic = true;
64
+ let itemIsSensitive = false;
65
+ if (SENSITIVE_KEYWORDS.some((keyword) => itemKey.includes(keyword))) itemIsSensitive = true;
66
+ if (itemIsPublic) ; else if (itemIsSensitive) {
67
+ envSpecUpdater.setItemDecorator(file, itemKey, "sensitive", "true");
68
+ }
69
+ if (itemKey === "PORT" || itemKey.endsWith("_PORT")) {
70
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "port");
71
+ } else if (itemKey.endsWith("_EMAIL")) {
72
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "email");
73
+ } else if (itemKey.endsWith("_URL") || itemKey.endsWith("_URI")) {
74
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "url");
75
+ } else if (valueStr) {
76
+ if (valueStr.startsWith("<") && valueStr.endsWith(">")) {
77
+ envSpecUpdater.setItemDecorator(file, itemKey, "example", valueStr);
78
+ }
79
+ if (valueStr === "true" || valueStr === "false") {
80
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "boolean");
81
+ } else if (EMAIL_REGEX.test(valueStr)) {
82
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "email");
83
+ } else if (valueStr !== "0" && valueStr !== "1" && VALID_NUMBER_REGEX.test(valueStr)) {
84
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "number");
85
+ } else if (isValidUrl(valueStr)) {
86
+ envSpecUpdater.setItemDecorator(file, itemKey, "type", "url");
87
+ }
88
+ }
89
+ }
90
+ __name(inferItemDecorators, "inferItemDecorators");
91
+ function inferSchemaUpdates(file) {
92
+ for (const item of file.configItems) {
93
+ const valueStr = item.value instanceof ParsedEnvSpecStaticValue && item.value.value?.toString() || "";
94
+ inferItemDecorators(file, item.key, valueStr);
95
+ }
96
+ }
97
+ __name(inferSchemaUpdates, "inferSchemaUpdates");
98
+ function ensureAllItemsExist(schemaFile, otherFiles) {
99
+ const addedItemKeys = [];
100
+ for (const otherFile of otherFiles) {
101
+ for (const item of otherFile.parsedFile.configItems) {
102
+ const itemInSchema = schemaFile.configItems.find((i) => i.key === item.key);
103
+ if (itemInSchema) continue;
104
+ if (addedItemKeys.length === 0) {
105
+ envSpecUpdater.injectFromStr(schemaFile, [
106
+ "",
107
+ "# items added to schema by `varlock init`",
108
+ "# that were missing in example, but detected in other .env files",
109
+ "# PLEASE REVIEW THESE!",
110
+ "# ---",
111
+ ""
112
+ ].join("\n"), { location: "end" });
113
+ }
114
+ addedItemKeys.push(item.key);
115
+ envSpecUpdater.injectFromStr(schemaFile, `${item.key}=`);
116
+ const itemValue = item.value instanceof ParsedEnvSpecStaticValue && item.value.value?.toString() || "";
117
+ inferItemDecorators(schemaFile, item.key, String(itemValue));
118
+ }
119
+ }
120
+ }
121
+ __name(ensureAllItemsExist, "ensureAllItemsExist");
122
+ async function detectRedundantValues(schemaFile, otherFiles, opts = {}) {
123
+ const redundantItemsBySourcePath = {};
124
+ const schemaValues = schemaFile.toSimpleObj();
125
+ for (const otherFile of Object.values(otherFiles)) {
126
+ if (otherFile.fileName.startsWith(".env.schema") || otherFile.fileName.startsWith(".env.example") || otherFile.fileName.startsWith(".env.sample") || otherFile.fileName.startsWith(".env.default")) continue;
127
+ const otherFileValues = otherFile.parsedFile.toSimpleObj();
128
+ for (const itemKey in otherFileValues) {
129
+ if (!(itemKey in schemaValues)) continue;
130
+ if (otherFileValues[itemKey] !== schemaValues[itemKey]) continue;
131
+ redundantItemsBySourcePath[otherFile.fullPath] ||= [];
132
+ redundantItemsBySourcePath[otherFile.fullPath].push(itemKey);
133
+ if (opts.delete) {
134
+ envSpecUpdater.deleteItem(otherFile.parsedFile, itemKey);
135
+ }
136
+ }
137
+ if (opts.delete) {
138
+ await fs3.writeFile(otherFile.fullPath, otherFile.parsedFile.toString(), "utf8");
139
+ }
140
+ }
141
+ return redundantItemsBySourcePath;
142
+ }
143
+ __name(detectRedundantValues, "detectRedundantValues");
144
+ var SKIP_FILE_TYPES = [".md", ".d.ts"];
145
+ async function findEnvFiles(opts) {
146
+ const cwd = opts?.cwd || process.cwd();
147
+ const envFiles = [];
148
+ const filesWithinDir = await fs3.readdir(cwd);
149
+ for (const fileName of filesWithinDir) {
150
+ if (fileName === ".env" || fileName.startsWith(".env.")) {
151
+ let skip = false;
152
+ for (const fileType of SKIP_FILE_TYPES) {
153
+ if (fileName.endsWith(fileType)) skip = true;
154
+ }
155
+ if (skip) continue;
156
+ envFiles.push(path2.join(cwd, fileName));
157
+ }
158
+ }
159
+ return envFiles;
160
+ }
161
+ __name(findEnvFiles, "findEnvFiles");
162
+
163
+ // src/cli/commands/init.command.ts
164
+ var commandSpec = define({
165
+ name: "init",
166
+ description: "Set up varlock in the current project",
167
+ args: {},
168
+ examples: `
169
+ This command starts an interactive onboarding process to help you get started with Varlock.
170
+ It will:
171
+ - Scan for existing .env files in your project
172
+ - Help create a .env.schema file from your .env.example or .env.sample file
173
+ - Install varlock as a dependency in package.json (if applicable)
174
+
175
+ \u{1F4CD} Run this command in directories that contain .env or .env.* files
176
+
177
+ Examples:
178
+ varlock init # Run in the current directory
179
+ cd path/to/your/project && varlock init
180
+
181
+ For more information, visit https://varlock.dev/getting-started/installation
182
+ `.trim()
183
+ });
184
+ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
185
+ const jsPackageManager = detectJsPackageManager();
186
+ console.log("\u{1F9D9} Hello and welcome to Varlock \u{1F512}\u{1F525}\u2728");
187
+ const envFilePaths = await findEnvFiles();
188
+ const parsedEnvFiles = {};
189
+ for (const filePath of envFilePaths) {
190
+ const fileContents = await fs3.readFile(filePath, "utf-8");
191
+ const fileName = path2.basename(filePath);
192
+ const parsedFile = await tryCatch(async () => parseEnvSpecDotEnvFile(fileContents), () => {
193
+ logLines([
194
+ "",
195
+ `Unable to parse ${fmt.filePath(filePath)}`,
196
+ "This file will be skipped."
197
+ ]);
198
+ });
199
+ if (!parsedFile) {
200
+ continue;
201
+ }
202
+ parsedEnvFiles[fileName] = {
203
+ fileName,
204
+ fullPath: filePath,
205
+ parsedFile
206
+ };
207
+ }
208
+ const existingSchemaFile = parsedEnvFiles[".env.schema"];
209
+ if (existingSchemaFile) {
210
+ logLines([
211
+ `It looks like you already have a ${fmt.fileName(".env.schema")} file \u{1F389}`,
212
+ "This init helper is meant to help you get a new project set up.",
213
+ "If you need to make changes to your schema or values, you can update your files directly.",
214
+ "See more docs at https://varlock.dev/guides/schema"
215
+ ]);
216
+ } else {
217
+ const allExampleFileNames = Object.keys(parsedEnvFiles).filter((fileName) => {
218
+ return fileName.startsWith(".env.example") || fileName.startsWith(".env.sample");
219
+ });
220
+ let exampleFileToConvert;
221
+ if (allExampleFileNames.length === 1) {
222
+ exampleFileToConvert = parsedEnvFiles[allExampleFileNames[0]];
223
+ } else if (allExampleFileNames.length > 1) {
224
+ console.log("");
225
+ const selectedExample = await Jt({
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 (Ct(selectedExample)) return gracefulExit(0);
233
+ exampleFileToConvert = selectedExample;
234
+ }
235
+ const parsedEnvSchemaFile = exampleFileToConvert?.parsedFile || parseEnvSpecDotEnvFile("");
236
+ if (!parsedEnvSchemaFile) throw new Error("expected parsed .env example file");
237
+ envSpecUpdater.ensureHeader(parsedEnvSchemaFile, [
238
+ "This env file uses @env-spec - see https://varlock.dev/env-spec for more info",
239
+ ""
240
+ // TODO: add env spec version? real links?
241
+ ].join("\n"));
242
+ envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, "defaultRequired", "infer", { explicitTrue: true });
243
+ envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, "defaultSensitive", "false", { explicitTrue: true });
244
+ envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, "generateTypes", "lang=ts, path=env.d.ts", { bareFnArgs: true });
245
+ envSpecUpdater.injectFromStr(parsedEnvSchemaFile, [
246
+ "",
247
+ "# example env variable injected by `varlock init` \u26A0\uFE0F DELETE THIS ITEM! \u26A0\uFE0F",
248
+ '# @required @sensitive @example="example value"',
249
+ 'EXAMPLE_ITEM="delete me!"',
250
+ ""
251
+ ].join("\n"), { location: "after_header" });
252
+ inferSchemaUpdates(parsedEnvSchemaFile);
253
+ ensureAllItemsExist(parsedEnvSchemaFile, Object.values(parsedEnvFiles));
254
+ const schemaFilePath = path2.join(process.cwd(), ".env.schema");
255
+ await fs3.writeFile(schemaFilePath, parsedEnvSchemaFile.toString());
256
+ if (exampleFileToConvert) {
257
+ logLines([
258
+ "",
259
+ `Your ${fmt.fileName(exampleFileToConvert.fileName)} has been used to generate your new ${fmt.fileName(".env.schema")}:`,
260
+ fmt.filePath(schemaFilePath)
261
+ ]);
262
+ } else {
263
+ logLines([
264
+ "",
265
+ `Your new ${fmt.fileName(".env.schema")} file has been created:`,
266
+ fmt.filePath(schemaFilePath)
267
+ ]);
268
+ }
269
+ if (await checkIsFileGitIgnored(schemaFilePath)) {
270
+ logLines([ansis_default.dim(`(and updated ${fmt.fileName(".gitignore")} to ensure it will be tracked by git)`)]);
271
+ await fs3.appendFile(".gitignore", "\n!.env.schema");
272
+ }
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 (Ct(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")) {
292
+ logLines([
293
+ "",
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...`
296
+ ]);
297
+ }
298
+ 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 (Ct(confirmDeleteExample)) return gracefulExit(0);
303
+ if (confirmDeleteExample) {
304
+ await fs3.unlink(exampleFileToConvert.fullPath);
305
+ }
306
+ }
307
+ const defaultsFile = Object.values(parsedEnvFiles).find((f) => {
308
+ return f.fileName.startsWith(".env.default");
309
+ });
310
+ 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
+ ]);
316
+ }
317
+ const redundantInfo = await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles);
318
+ if (Object.keys(redundantInfo).length > 0) {
319
+ logLines([
320
+ "",
321
+ ansis_default.bold("\u203C\uFE0F Now that your schema contains defaults, some values in your other .env files are redundant:")
322
+ ]);
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 (Ct(confirmDeleteRedundant)) return gracefulExit(0);
331
+ if (confirmDeleteRedundant) {
332
+ await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles, { delete: true });
333
+ }
334
+ }
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
+ }
346
+ if (jsPackageManager && await pathExists(path2.join(process.cwd(), "package.json"))) {
347
+ const installResult = installJsDependency({
348
+ packageManager: jsPackageManager.name,
349
+ packageName: "varlock"
350
+ });
351
+ if (installResult) {
352
+ logLines([
353
+ "",
354
+ `\u2705 Added ${fmt.packageName("varlock")} as a dependency in your package.json`
355
+ ]);
356
+ }
357
+ }
358
+ if (jsPackageManager?.name === "bun") {
359
+ const bunfigPath = path2.join(process.cwd(), "bunfig.toml");
360
+ const bunfigExists = await pathExists(bunfigPath);
361
+ if (bunfigExists) {
362
+ const bunfigContents = await fs3.readFile(bunfigPath, "utf-8");
363
+ if (!/^\s*env\s*=\s*false\s*$/m.test(bunfigContents)) {
364
+ await fs3.writeFile(bunfigPath, `env = false
365
+ ${bunfigContents}`);
366
+ logLines([
367
+ "",
368
+ `\u2705 Added ${ansis_default.bold("env = false")} to your existing ${fmt.fileName("bunfig.toml")}`,
369
+ ansis_default.dim("This disables Bun's automatic .env loading, which conflicts with Varlock."),
370
+ ansis_default.dim(`See ${ansis_default.underline("https://varlock.dev/integrations/bun")} for more info.`)
371
+ ]);
372
+ }
373
+ } else {
374
+ await fs3.writeFile(bunfigPath, "env = false\n");
375
+ logLines([
376
+ "",
377
+ `\u2705 Created ${fmt.fileName("bunfig.toml")} with ${ansis_default.bold("env = false")}`,
378
+ ansis_default.dim("This disables Bun's automatic .env loading, which conflicts with Varlock."),
379
+ ansis_default.dim(`See ${ansis_default.underline("https://varlock.dev/integrations/bun")} for more info.`)
380
+ ]);
381
+ }
382
+ }
383
+ }, "commandFn");
384
+
385
+ export { commandFn, commandSpec };
386
+ //# sourceMappingURL=chunk-AKWP77PS.js.map
387
+ //# sourceMappingURL=chunk-AKWP77PS.js.map