varlock 0.9.1 → 1.0.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 (103) hide show
  1. package/dist/{chunk-FWJAZMC7.js → chunk-2ABRAKHE.js} +4 -4
  2. package/dist/{chunk-FWJAZMC7.js.map → chunk-2ABRAKHE.js.map} +1 -1
  3. package/dist/chunk-2EEXFFKL.js +149 -0
  4. package/dist/chunk-2EEXFFKL.js.map +1 -0
  5. package/dist/chunk-6DXWXIQV.js +1092 -0
  6. package/dist/chunk-6DXWXIQV.js.map +1 -0
  7. package/dist/{chunk-7P3SVUZ5.js → chunk-6JKWTWLB.js} +6 -6
  8. package/dist/{chunk-7P3SVUZ5.js.map → chunk-6JKWTWLB.js.map} +1 -1
  9. package/dist/chunk-7WB7HK5Z.js +21 -0
  10. package/dist/chunk-7WB7HK5Z.js.map +1 -0
  11. package/dist/chunk-AMNNQL7K.js +26 -0
  12. package/dist/chunk-AMNNQL7K.js.map +1 -0
  13. package/dist/{chunk-UG4RTI6V.js → chunk-CKWXLVMV.js} +5 -4
  14. package/dist/chunk-CKWXLVMV.js.map +1 -0
  15. package/dist/{chunk-253NGIPN.js → chunk-FTVXXJMG.js} +3 -3
  16. package/dist/{chunk-253NGIPN.js.map → chunk-FTVXXJMG.js.map} +1 -1
  17. package/dist/{chunk-QHIRGHGG.js → chunk-GBCB7Y3B.js} +3 -3
  18. package/dist/{chunk-QHIRGHGG.js.map → chunk-GBCB7Y3B.js.map} +1 -1
  19. package/dist/chunk-HDKXXS2X.js +1959 -0
  20. package/dist/chunk-HDKXXS2X.js.map +1 -0
  21. package/dist/chunk-JEZQ2DFL.js +198 -0
  22. package/dist/chunk-JEZQ2DFL.js.map +1 -0
  23. package/dist/{chunk-GH73MG2H.js → chunk-LOIJO4MO.js} +4 -4
  24. package/dist/{chunk-GH73MG2H.js.map → chunk-LOIJO4MO.js.map} +1 -1
  25. package/dist/{chunk-ZRHT6QHO.js → chunk-NJONB6CB.js} +5 -5
  26. package/dist/{chunk-ZRHT6QHO.js.map → chunk-NJONB6CB.js.map} +1 -1
  27. package/dist/{chunk-4VC5S7NB.js → chunk-QJ6NMN5H.js} +5 -5
  28. package/dist/{chunk-4VC5S7NB.js.map → chunk-QJ6NMN5H.js.map} +1 -1
  29. package/dist/{chunk-NWKETKFP.js → chunk-QNTIIXD5.js} +5 -5
  30. package/dist/{chunk-NWKETKFP.js.map → chunk-QNTIIXD5.js.map} +1 -1
  31. package/dist/{chunk-W3GUFLIV.js → chunk-U7RQPX5K.js} +349 -1130
  32. package/dist/chunk-U7RQPX5K.js.map +1 -0
  33. package/dist/{chunk-FSLTOPCT.js → chunk-UKFHSMKY.js} +4 -4
  34. package/dist/{chunk-FSLTOPCT.js.map → chunk-UKFHSMKY.js.map} +1 -1
  35. package/dist/chunk-V2MTE4J6.js +426 -0
  36. package/dist/chunk-V2MTE4J6.js.map +1 -0
  37. package/dist/{chunk-LOGMWG5X.js → chunk-VODQDF4Q.js} +5 -5
  38. package/dist/{chunk-LOGMWG5X.js.map → chunk-VODQDF4Q.js.map} +1 -1
  39. package/dist/{chunk-BFRONY2O.js → chunk-XADO6HQG.js} +6 -6
  40. package/dist/{chunk-BFRONY2O.js.map → chunk-XADO6HQG.js.map} +1 -1
  41. package/dist/{chunk-US7YQTJZ.js → chunk-XTOUG72X.js} +5 -5
  42. package/dist/{chunk-US7YQTJZ.js.map → chunk-XTOUG72X.js.map} +1 -1
  43. package/dist/cli/cli-executable.js +47 -31
  44. package/dist/cli/cli-executable.js.map +1 -1
  45. package/dist/config-item-2FQ6I6PO.js +7 -0
  46. package/dist/{config-item-IK3DUE5F.js.map → config-item-2FQ6I6PO.js.map} +1 -1
  47. package/dist/dist-WGIHRGBZ.js +4 -0
  48. package/dist/dist-WGIHRGBZ.js.map +1 -0
  49. package/dist/encrypt.command-K2SBJVQ5.js +14 -0
  50. package/dist/encrypt.command-K2SBJVQ5.js.map +1 -0
  51. package/dist/{env-graph-DaF8Aebq.d.ts → env-graph-CXTsI2Eg.d.ts} +3 -0
  52. package/dist/explain.command-E6MR72IY.js +15 -0
  53. package/dist/{explain.command-5DG3ACIH.js.map → explain.command-E6MR72IY.js.map} +1 -1
  54. package/dist/index.d.ts +2 -2
  55. package/dist/index.js +8 -5
  56. package/dist/index.js.map +1 -1
  57. package/dist/init.command-TGDNXHJ7.js +13 -0
  58. package/dist/{init.command-EWCFF2D5.js.map → init.command-TGDNXHJ7.js.map} +1 -1
  59. package/dist/install-plugin.command-Z2S5DIFS.js +13 -0
  60. package/dist/{install-plugin.command-6ESRFNKI.js.map → install-plugin.command-Z2S5DIFS.js.map} +1 -1
  61. package/dist/load.command-K2IH3646.js +15 -0
  62. package/dist/{load.command-QNDTE2VK.js.map → load.command-K2IH3646.js.map} +1 -1
  63. package/dist/lock.command-GL4CLXED.js +7 -0
  64. package/dist/lock.command-GL4CLXED.js.map +1 -0
  65. package/dist/plugin-lib.d.ts +2 -2
  66. package/dist/printenv.command-34LGQT6W.js +15 -0
  67. package/dist/{printenv.command-SBCXAVQT.js.map → printenv.command-34LGQT6W.js.map} +1 -1
  68. package/dist/reveal.command-WOHYRSYO.js +15 -0
  69. package/dist/reveal.command-WOHYRSYO.js.map +1 -0
  70. package/dist/run.command-PPC2X2N7.js +16 -0
  71. package/dist/{run.command-64JM27VM.js.map → run.command-PPC2X2N7.js.map} +1 -1
  72. package/dist/runtime/env.d.ts +1 -1
  73. package/dist/scan.command-4DJBQEML.js +16 -0
  74. package/dist/{scan.command-YFM7VO2I.js.map → scan.command-4DJBQEML.js.map} +1 -1
  75. package/dist/telemetry.command-LIOCXWQK.js +13 -0
  76. package/dist/{telemetry.command-4AEVBTVE.js.map → telemetry.command-LIOCXWQK.js.map} +1 -1
  77. package/dist/typegen.command-COL35ALE.js +15 -0
  78. package/dist/{typegen.command-27OCEPZM.js.map → typegen.command-COL35ALE.js.map} +1 -1
  79. package/native-bins/darwin/VarlockEnclave.app/Contents/CodeResources +0 -0
  80. package/native-bins/darwin/VarlockEnclave.app/Contents/Info.plist +28 -0
  81. package/native-bins/darwin/VarlockEnclave.app/Contents/MacOS/varlock-local-encrypt +0 -0
  82. package/native-bins/darwin/VarlockEnclave.app/Contents/Resources/AppIcon.icns +0 -0
  83. package/native-bins/darwin/VarlockEnclave.app/Contents/Resources/varlock-menu-locked.pdf +0 -0
  84. package/native-bins/darwin/VarlockEnclave.app/Contents/Resources/varlock-menu-unlocked.pdf +0 -0
  85. package/native-bins/darwin/VarlockEnclave.app/Contents/_CodeSignature/CodeResources +150 -0
  86. package/native-bins/linux-arm64/varlock-local-encrypt +0 -0
  87. package/native-bins/linux-x64/varlock-local-encrypt +0 -0
  88. package/native-bins/win32-x64/varlock-local-encrypt.exe +0 -0
  89. package/package.json +9 -2
  90. package/dist/chunk-MIMMYDBC.js +0 -83
  91. package/dist/chunk-MIMMYDBC.js.map +0 -1
  92. package/dist/chunk-UG4RTI6V.js.map +0 -1
  93. package/dist/chunk-W3GUFLIV.js.map +0 -1
  94. package/dist/config-item-IK3DUE5F.js +0 -5
  95. package/dist/explain.command-5DG3ACIH.js +0 -12
  96. package/dist/init.command-EWCFF2D5.js +0 -11
  97. package/dist/install-plugin.command-6ESRFNKI.js +0 -11
  98. package/dist/load.command-QNDTE2VK.js +0 -12
  99. package/dist/printenv.command-SBCXAVQT.js +0 -12
  100. package/dist/run.command-64JM27VM.js +0 -13
  101. package/dist/scan.command-YFM7VO2I.js +0 -13
  102. package/dist/telemetry.command-4AEVBTVE.js +0 -11
  103. package/dist/typegen.command-27OCEPZM.js +0 -12
@@ -1,5 +1,5 @@
1
- import { CliExitError } from './chunk-QHIRGHGG.js';
2
- import { detectWorkspaceInfo, ansis_default } from './chunk-W3GUFLIV.js';
1
+ import { CliExitError } from './chunk-GBCB7Y3B.js';
2
+ import { detectWorkspaceInfo, ansis_default } from './chunk-U7RQPX5K.js';
3
3
  import { __name } from './chunk-6PEHRAEP.js';
4
4
  import path from 'path';
5
5
  import fs, { existsSync } from 'fs';
@@ -64,5 +64,5 @@ var logLines = /* @__PURE__ */ __name((lines) => {
64
64
  }, "logLines");
65
65
 
66
66
  export { detectJsPackageManager, fmt, installJsDependency, logLines };
67
- //# sourceMappingURL=chunk-FWJAZMC7.js.map
68
- //# sourceMappingURL=chunk-FWJAZMC7.js.map
67
+ //# sourceMappingURL=chunk-2ABRAKHE.js.map
68
+ //# sourceMappingURL=chunk-2ABRAKHE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-FWJAZMC7.js","sourcesContent":["// Re-exports for backward compatibility - prefer importing from lib/workspace-utils directly\nexport {\n JS_PACKAGE_MANAGERS,\n detectWorkspaceInfo,\n getWorkspaceInfo,\n runWithWorkspaceInfo,\n type JsPackageManager,\n type JsPackageManagerMeta,\n type WorkspaceInfo,\n type MonorepoTool,\n} from '../../lib/workspace-utils';\n\nimport path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { CliExitError } from './exit-error';\nimport { detectWorkspaceInfo, type JsPackageManager } from '../../lib/workspace-utils';\n\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n exitIfNotFound?: boolean,\n}) {\n const info = detectWorkspaceInfo({ cwd: opts?.cwd });\n if (!info) {\n if (opts?.exitIfNotFound) {\n throw new CliExitError('Unable to detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n return undefined;\n }\n return info.packageManager;\n}\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n","import ansis from 'ansis';\nimport { detectJsPackageManager, type JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
1
+ {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-2ABRAKHE.js","sourcesContent":["// Re-exports for backward compatibility - prefer importing from lib/workspace-utils directly\nexport {\n JS_PACKAGE_MANAGERS,\n detectWorkspaceInfo,\n getWorkspaceInfo,\n runWithWorkspaceInfo,\n type JsPackageManager,\n type JsPackageManagerMeta,\n type WorkspaceInfo,\n type MonorepoTool,\n} from '../../lib/workspace-utils';\n\nimport path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { CliExitError } from './exit-error';\nimport { detectWorkspaceInfo, type JsPackageManager } from '../../lib/workspace-utils';\n\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n exitIfNotFound?: boolean,\n}) {\n const info = detectWorkspaceInfo({ cwd: opts?.cwd });\n if (!info) {\n if (opts?.exitIfNotFound) {\n throw new CliExitError('Unable to detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n return undefined;\n }\n return info.packageManager;\n}\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n","import ansis from 'ansis';\nimport { detectJsPackageManager, type JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
@@ -0,0 +1,149 @@
1
+ import { define } from './chunk-4A54P4EM.js';
2
+ import { loadVarlockEnvGraph, writeBackValue } from './chunk-V2MTE4J6.js';
3
+ import { encryptValue, getBackendInfo, ensureKey, getDaemonClient } from './chunk-6DXWXIQV.js';
4
+ import { gracefulExit } from './chunk-CHQDS2PI.js';
5
+ import { CliExitError } from './chunk-GBCB7Y3B.js';
6
+ import { FileBasedDataSource, ParsedEnvSpecFunctionCall, ParsedEnvSpecStaticValue, multiselect, ansis_default, password } from './chunk-U7RQPX5K.js';
7
+ import { q } from './chunk-HDKXXS2X.js';
8
+ import { __name } from './chunk-6PEHRAEP.js';
9
+ import path from 'path';
10
+ import fs from 'fs';
11
+
12
+ var commandSpec = define({
13
+ name: "encrypt",
14
+ description: "Encrypt a value using device-local encryption",
15
+ args: {
16
+ "key-id": {
17
+ type: "string",
18
+ description: "Encryption key ID (default: varlock-default)",
19
+ default: "varlock-default"
20
+ },
21
+ file: {
22
+ type: "string",
23
+ description: "Path to a .env file \u2014 encrypts all sensitive plaintext values in-place"
24
+ }
25
+ }
26
+ });
27
+ async function encryptFile(keyId, filePath) {
28
+ const resolvedPath = path.resolve(filePath);
29
+ if (!fs.existsSync(resolvedPath)) {
30
+ throw new CliExitError(`File not found: ${resolvedPath}`);
31
+ }
32
+ const envGraph = await loadVarlockEnvGraph();
33
+ await envGraph.resolveEnvValues();
34
+ const targetSource = envGraph.sortedDataSources.find(
35
+ (s) => s instanceof FileBasedDataSource && s.fullPath === resolvedPath
36
+ );
37
+ if (!targetSource) {
38
+ throw new CliExitError(
39
+ `File "${filePath}" is not part of the loaded env graph`,
40
+ { suggestion: "Make sure the file is in the project directory or imported by your schema." }
41
+ );
42
+ }
43
+ const itemsToEncrypt = [];
44
+ for (const [key, itemDef] of Object.entries(targetSource.configItemDefs)) {
45
+ const graphItem = envGraph.configSchema[key];
46
+ if (!graphItem?.isSensitive) continue;
47
+ if (itemDef.parsedValue instanceof ParsedEnvSpecFunctionCall) continue;
48
+ if (!(itemDef.parsedValue instanceof ParsedEnvSpecStaticValue)) continue;
49
+ const val = itemDef.parsedValue.unescapedValue;
50
+ if (val === void 0 || val === "" || typeof val !== "string") continue;
51
+ itemsToEncrypt.push({ key, value: val });
52
+ }
53
+ if (itemsToEncrypt.length === 0) {
54
+ console.log("No sensitive plaintext values found to encrypt.");
55
+ return;
56
+ }
57
+ console.log("Only items marked as @sensitive in the schema are shown.");
58
+ console.log("If a key is missing, add @sensitive to it in your schema file.\n");
59
+ const selected = await multiselect({
60
+ message: `Confirm values to encrypt in ${filePath} ${ansis_default.gray("(use arrows, space to toggle, enter to confirm)")}`,
61
+ options: itemsToEncrypt.map((item) => ({
62
+ value: item.key,
63
+ label: item.key
64
+ })),
65
+ initialValues: itemsToEncrypt.map((item) => item.key)
66
+ });
67
+ if (q(selected)) return gracefulExit();
68
+ const selectedKeys = new Set(selected);
69
+ const filteredItems = itemsToEncrypt.filter((item) => selectedKeys.has(item.key));
70
+ if (filteredItems.length === 0) {
71
+ console.log("No items selected.");
72
+ return;
73
+ }
74
+ console.log("");
75
+ let encryptedCount = 0;
76
+ for (const item of filteredItems) {
77
+ const ciphertext = await encryptValue(item.value, keyId);
78
+ const result = writeBackValue(item.key, `varlock("local:${ciphertext}")`, resolvedPath);
79
+ if (result.updated) {
80
+ encryptedCount++;
81
+ console.log(` Encrypted: ${item.key}`);
82
+ }
83
+ }
84
+ console.log(`
85
+ Encrypted ${encryptedCount} value${encryptedCount !== 1 ? "s" : ""} in ${filePath}`);
86
+ }
87
+ __name(encryptFile, "encryptFile");
88
+ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
89
+ const keyId = String(ctx.values["key-id"] || "varlock-default");
90
+ const backend = getBackendInfo();
91
+ try {
92
+ await ensureKey(keyId);
93
+ } catch (err) {
94
+ if (err instanceof CliExitError) throw err;
95
+ throw new CliExitError(
96
+ `Failed to check/create encryption key: ${err instanceof Error ? err.message : err}`
97
+ );
98
+ }
99
+ console.log(`Using ${backend.type} backend (${backend.hardwareBacked ? "hardware-backed" : "file-based"})`);
100
+ const filePath = ctx.values.file;
101
+ if (filePath) {
102
+ await encryptFile(keyId, filePath);
103
+ return;
104
+ }
105
+ console.log("");
106
+ let ciphertext;
107
+ if (!process.stdin.isTTY) {
108
+ const chunks = [];
109
+ for await (const chunk of process.stdin) {
110
+ chunks.push(chunk);
111
+ }
112
+ const rawValue = Buffer.concat(chunks).toString("utf-8").replace(/\r?\n$/, "");
113
+ if (!rawValue) {
114
+ throw new CliExitError("No value received on stdin");
115
+ }
116
+ try {
117
+ ciphertext = await encryptValue(rawValue, keyId);
118
+ } catch (err) {
119
+ if (err instanceof CliExitError) throw err;
120
+ throw new CliExitError(
121
+ `Encryption failed: ${err instanceof Error ? err.message : err}`
122
+ );
123
+ }
124
+ } else if (backend.biometricAvailable) {
125
+ const client = getDaemonClient();
126
+ const result = await client.promptSecret({ keyId });
127
+ if (!result) {
128
+ return gracefulExit();
129
+ }
130
+ ciphertext = result;
131
+ } else {
132
+ const prompted = await password({ message: "Enter the value you want to encrypt", hint: "for multi-line values, pipe via stdin" });
133
+ if (q(prompted)) return gracefulExit();
134
+ try {
135
+ ciphertext = await encryptValue(prompted, keyId);
136
+ } catch (err) {
137
+ if (err instanceof CliExitError) throw err;
138
+ throw new CliExitError(
139
+ `Encryption failed: ${err instanceof Error ? err.message : err}`
140
+ );
141
+ }
142
+ }
143
+ console.log("\nCopy this into your .env.local file and rename the key appropriately:\n");
144
+ console.log(`SOME_SENSITIVE_KEY=varlock("local:${ciphertext}")`);
145
+ }, "commandFn");
146
+
147
+ export { commandFn, commandSpec };
148
+ //# sourceMappingURL=chunk-2EEXFFKL.js.map
149
+ //# sourceMappingURL=chunk-2EEXFFKL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/encrypt.command.ts"],"names":[],"mappings":"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","file":"chunk-2EEXFFKL.js","sourcesContent":["import { define } from 'gunshi';\nimport { isCancel } from '@clack/prompts';\nimport ansis from 'ansis';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\nimport {\n ParsedEnvSpecStaticValue,\n ParsedEnvSpecFunctionCall,\n} from '@env-spec/parser';\nimport { FileBasedDataSource } from '../../env-graph';\nimport { loadVarlockEnvGraph } from '../../lib/load-graph';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { CliExitError } from '../helpers/exit-error';\nimport { multiselect, password } from '../helpers/prompts';\nimport { gracefulExit } from 'exit-hook';\nimport * as localEncrypt from '../../lib/local-encrypt';\nimport { writeBackValue } from '../../lib/local-encrypt/write-back';\n\nexport const commandSpec = define({\n name: 'encrypt',\n description: 'Encrypt a value using device-local encryption',\n args: {\n 'key-id': {\n type: 'string',\n description: 'Encryption key ID (default: varlock-default)',\n default: 'varlock-default',\n },\n file: {\n type: 'string',\n description: 'Path to a .env file — encrypts all sensitive plaintext values in-place',\n },\n },\n});\n\nasync function encryptFile(keyId: string, filePath: string) {\n const resolvedPath = path.resolve(filePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new CliExitError(`File not found: ${resolvedPath}`);\n }\n\n // Load the full env graph and resolve to get sensitivity info from the schema\n const envGraph = await loadVarlockEnvGraph();\n await envGraph.resolveEnvValues();\n\n // Find the data source matching the target file\n const targetSource = envGraph.sortedDataSources.find(\n (s) => s instanceof FileBasedDataSource && s.fullPath === resolvedPath,\n ) as FileBasedDataSource | undefined;\n\n if (!targetSource) {\n throw new CliExitError(\n `File \"${filePath}\" is not part of the loaded env graph`,\n { suggestion: 'Make sure the file is in the project directory or imported by your schema.' },\n );\n }\n\n // Find sensitive items that have plaintext static values in this file\n const itemsToEncrypt: Array<{ key: string; value: string }> = [];\n\n for (const [key, itemDef] of Object.entries(targetSource.configItemDefs)) {\n const graphItem = envGraph.configSchema[key];\n if (!graphItem?.isSensitive) continue;\n\n // Skip items already using varlock() or another function call\n if (itemDef.parsedValue instanceof ParsedEnvSpecFunctionCall) continue;\n\n // Only encrypt items with actual static string values\n if (!(itemDef.parsedValue instanceof ParsedEnvSpecStaticValue)) continue;\n const val = itemDef.parsedValue.unescapedValue;\n if (val === undefined || val === '' || typeof val !== 'string') continue;\n\n itemsToEncrypt.push({ key, value: val });\n }\n\n if (itemsToEncrypt.length === 0) {\n console.log('No sensitive plaintext values found to encrypt.');\n return;\n }\n\n console.log('Only items marked as @sensitive in the schema are shown.');\n console.log('If a key is missing, add @sensitive to it in your schema file.\\n');\n\n const selected = await multiselect({\n message: `Confirm values to encrypt in ${filePath} ${ansis.gray('(use arrows, space to toggle, enter to confirm)')}`,\n options: itemsToEncrypt.map((item) => ({\n value: item.key,\n label: item.key,\n })),\n initialValues: itemsToEncrypt.map((item) => item.key),\n });\n\n if (isCancel(selected)) return gracefulExit();\n\n const selectedKeys = new Set(selected as Array<string>);\n const filteredItems = itemsToEncrypt.filter((item) => selectedKeys.has(item.key));\n\n if (filteredItems.length === 0) {\n console.log('No items selected.');\n return;\n }\n\n console.log('');\n\n let encryptedCount = 0;\n for (const item of filteredItems) {\n const ciphertext = await localEncrypt.encryptValue(item.value, keyId);\n const result = writeBackValue(item.key, `varlock(\"local:${ciphertext}\")`, resolvedPath);\n\n if (result.updated) {\n encryptedCount++;\n console.log(` Encrypted: ${item.key}`);\n }\n }\n\n console.log(`\\nEncrypted ${encryptedCount} value${encryptedCount !== 1 ? 's' : ''} in ${filePath}`);\n}\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n const keyId = String(ctx.values['key-id'] || 'varlock-default');\n const backend = localEncrypt.getBackendInfo();\n\n try {\n await localEncrypt.ensureKey(keyId);\n } catch (err) {\n if (err instanceof CliExitError) throw err;\n throw new CliExitError(\n `Failed to check/create encryption key: ${err instanceof Error ? err.message : err}`,\n );\n }\n\n console.log(`Using ${backend.type} backend (${backend.hardwareBacked ? 'hardware-backed' : 'file-based'})`);\n\n const filePath = ctx.values.file;\n\n // --file mode: encrypt all sensitive plaintext values in a .env file\n if (filePath) {\n await encryptFile(keyId, filePath);\n return;\n }\n\n // Single-value mode — read from stdin if piped, otherwise prompt interactively.\n // Avoids putting secrets in shell history (e.g. `echo $SECRET | varlock encrypt`).\n console.log('');\n\n let ciphertext: string;\n\n if (!process.stdin.isTTY) {\n const chunks: Array<Buffer> = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n const rawValue = Buffer.concat(chunks).toString('utf-8').replace(/\\r?\\n$/, '');\n if (!rawValue) {\n throw new CliExitError('No value received on stdin');\n }\n try {\n ciphertext = await localEncrypt.encryptValue(rawValue, keyId);\n } catch (err) {\n if (err instanceof CliExitError) throw err;\n throw new CliExitError(\n `Encryption failed: ${err instanceof Error ? err.message : err}`,\n );\n }\n } else if (backend.biometricAvailable) {\n // Use native secure input dialog (supports multi-line paste)\n const client = localEncrypt.getDaemonClient();\n const result = await client.promptSecret({ keyId });\n if (!result) {\n return gracefulExit();\n }\n ciphertext = result;\n } else {\n const prompted = await password({ message: 'Enter the value you want to encrypt', hint: 'for multi-line values, pipe via stdin' });\n if (isCancel(prompted)) return gracefulExit();\n try {\n ciphertext = await localEncrypt.encryptValue(prompted, keyId);\n } catch (err) {\n if (err instanceof CliExitError) throw err;\n throw new CliExitError(\n `Encryption failed: ${err instanceof Error ? err.message : err}`,\n );\n }\n }\n\n console.log('\\nCopy this into your .env.local file and rename the key appropriately:\\n');\n console.log(`SOME_SENSITIVE_KEY=varlock(\"local:${ciphertext}\")`);\n};\n"]}