@chriscode/hush 4.2.0 → 5.0.1

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 (78) hide show
  1. package/dist/cli.js +58 -29
  2. package/dist/commands/check.d.ts +3 -3
  3. package/dist/commands/check.d.ts.map +1 -1
  4. package/dist/commands/check.js +30 -33
  5. package/dist/commands/decrypt.d.ts +2 -2
  6. package/dist/commands/decrypt.d.ts.map +1 -1
  7. package/dist/commands/decrypt.js +52 -55
  8. package/dist/commands/edit.d.ts +2 -2
  9. package/dist/commands/edit.d.ts.map +1 -1
  10. package/dist/commands/edit.js +10 -12
  11. package/dist/commands/encrypt.d.ts +2 -2
  12. package/dist/commands/encrypt.d.ts.map +1 -1
  13. package/dist/commands/encrypt.js +27 -29
  14. package/dist/commands/expansions.d.ts +2 -2
  15. package/dist/commands/expansions.d.ts.map +1 -1
  16. package/dist/commands/expansions.js +46 -44
  17. package/dist/commands/has.d.ts +2 -2
  18. package/dist/commands/has.d.ts.map +1 -1
  19. package/dist/commands/has.js +12 -15
  20. package/dist/commands/init.d.ts +2 -2
  21. package/dist/commands/init.d.ts.map +1 -1
  22. package/dist/commands/init.js +107 -87
  23. package/dist/commands/inspect.d.ts +2 -2
  24. package/dist/commands/inspect.d.ts.map +1 -1
  25. package/dist/commands/inspect.js +14 -16
  26. package/dist/commands/keys.d.ts +2 -1
  27. package/dist/commands/keys.d.ts.map +1 -1
  28. package/dist/commands/keys.js +47 -49
  29. package/dist/commands/list.d.ts +2 -2
  30. package/dist/commands/list.d.ts.map +1 -1
  31. package/dist/commands/list.js +11 -14
  32. package/dist/commands/migrate.d.ts +7 -0
  33. package/dist/commands/migrate.d.ts.map +1 -0
  34. package/dist/commands/migrate.js +117 -0
  35. package/dist/commands/push.d.ts +2 -2
  36. package/dist/commands/push.d.ts.map +1 -1
  37. package/dist/commands/push.js +41 -45
  38. package/dist/commands/resolve.d.ts +2 -2
  39. package/dist/commands/resolve.d.ts.map +1 -1
  40. package/dist/commands/resolve.js +25 -28
  41. package/dist/commands/run.d.ts +2 -2
  42. package/dist/commands/run.d.ts.map +1 -1
  43. package/dist/commands/run.js +35 -39
  44. package/dist/commands/set.d.ts +2 -2
  45. package/dist/commands/set.d.ts.map +1 -1
  46. package/dist/commands/set.js +61 -70
  47. package/dist/commands/skill.d.ts +2 -2
  48. package/dist/commands/skill.d.ts.map +1 -1
  49. package/dist/commands/skill.js +186 -487
  50. package/dist/commands/status.d.ts +2 -2
  51. package/dist/commands/status.d.ts.map +1 -1
  52. package/dist/commands/status.js +52 -55
  53. package/dist/commands/template.d.ts +2 -2
  54. package/dist/commands/template.d.ts.map +1 -1
  55. package/dist/commands/template.js +36 -39
  56. package/dist/commands/trace.d.ts +2 -2
  57. package/dist/commands/trace.d.ts.map +1 -1
  58. package/dist/commands/trace.js +16 -19
  59. package/dist/config/loader.js +3 -3
  60. package/dist/context.d.ts +3 -0
  61. package/dist/context.d.ts.map +1 -0
  62. package/dist/context.js +59 -0
  63. package/dist/core/parse.js +3 -3
  64. package/dist/core/sops.js +9 -9
  65. package/dist/core/template.d.ts +2 -2
  66. package/dist/core/template.d.ts.map +1 -1
  67. package/dist/core/template.js +11 -12
  68. package/dist/lib/age.js +9 -9
  69. package/dist/lib/fs.d.ts +25 -0
  70. package/dist/lib/fs.d.ts.map +1 -0
  71. package/dist/lib/fs.js +36 -0
  72. package/dist/lib/onepassword.d.ts.map +1 -1
  73. package/dist/lib/onepassword.js +41 -4
  74. package/dist/types.d.ts +91 -0
  75. package/dist/types.d.ts.map +1 -1
  76. package/dist/types.js +4 -4
  77. package/dist/utils/version-check.js +5 -5
  78. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/core/template.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AASvD,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,GACf,mBAAmB,CAqCrB;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,GAAE,kBAAuB,GAC/B,MAAM,EAAE,CAQV"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/core/template.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AASpE,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,GACpB,mBAAmB,CAqCrB;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,GAAE,kBAAuB,GAC/B,MAAM,EAAE,CAQV"}
@@ -1,31 +1,30 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
1
  import { join } from 'node:path';
3
2
  import { parseEnvContent } from './parse.js';
4
3
  import { mergeVars } from './merge.js';
5
4
  import { interpolateVars } from './interpolate.js';
6
5
  const TEMPLATE_FILES = {
7
- base: '.env',
8
- development: '.env.development',
9
- production: '.env.production',
10
- local: '.env.local',
6
+ base: '.hush',
7
+ development: '.hush.development',
8
+ production: '.hush.production',
9
+ local: '.hush.local',
11
10
  };
12
- export function loadLocalTemplates(contextDir, env) {
11
+ export function loadLocalTemplates(contextDir, env, fs) {
13
12
  const files = [];
14
13
  const varSources = [];
15
14
  const basePath = join(contextDir, TEMPLATE_FILES.base);
16
- if (existsSync(basePath)) {
15
+ if (fs.existsSync(basePath)) {
17
16
  files.push(TEMPLATE_FILES.base);
18
- varSources.push(parseEnvContent(readFileSync(basePath, 'utf-8')));
17
+ varSources.push(parseEnvContent(fs.readFileSync(basePath, 'utf-8')));
19
18
  }
20
19
  const envPath = join(contextDir, TEMPLATE_FILES[env]);
21
- if (existsSync(envPath)) {
20
+ if (fs.existsSync(envPath)) {
22
21
  files.push(TEMPLATE_FILES[env]);
23
- varSources.push(parseEnvContent(readFileSync(envPath, 'utf-8')));
22
+ varSources.push(parseEnvContent(fs.readFileSync(envPath, 'utf-8')));
24
23
  }
25
24
  const localPath = join(contextDir, TEMPLATE_FILES.local);
26
- if (existsSync(localPath)) {
25
+ if (fs.existsSync(localPath)) {
27
26
  files.push(TEMPLATE_FILES.local);
28
- varSources.push(parseEnvContent(readFileSync(localPath, 'utf-8')));
27
+ varSources.push(parseEnvContent(fs.readFileSync(localPath, 'utf-8')));
29
28
  }
30
29
  if (varSources.length === 0) {
31
30
  return {
package/dist/lib/age.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { execSync } from 'node:child_process';
2
- import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
2
+ import { fs } from './fs.js';
3
3
  import { join, dirname } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
5
  const KEYS_DIR = join(homedir(), '.config', 'sops', 'age', 'keys');
@@ -30,29 +30,29 @@ export function keyPath(project) {
30
30
  return join(KEYS_DIR, `${project.replace(/\//g, '-')}.txt`);
31
31
  }
32
32
  export function keyExists(project) {
33
- return existsSync(keyPath(project));
33
+ return fs.existsSync(keyPath(project));
34
34
  }
35
35
  export function keySave(project, key) {
36
36
  const path = keyPath(project);
37
- mkdirSync(dirname(path), { recursive: true });
38
- writeFileSync(path, `# project: ${project}\n# public key: ${key.public}\n${key.private}\n`, { mode: 0o600 });
37
+ fs.mkdirSync(dirname(path), { recursive: true });
38
+ fs.writeFileSync(path, `# project: ${project}\n# public key: ${key.public}\n${key.private}\n`, { mode: 0o600 });
39
39
  }
40
40
  export function keyLoad(project) {
41
41
  const path = keyPath(project);
42
- if (!existsSync(path))
42
+ if (!fs.existsSync(path))
43
43
  return null;
44
- const content = readFileSync(path, 'utf-8');
44
+ const content = fs.readFileSync(path, 'utf-8');
45
45
  const pub = content.match(/# public key: (age1[a-z0-9]+)/)?.[1];
46
46
  const priv = content.match(/(AGE-SECRET-KEY-[A-Z0-9]+)/)?.[1];
47
47
  return pub && priv ? { private: priv, public: pub } : null;
48
48
  }
49
49
  export function keysList() {
50
- if (!existsSync(KEYS_DIR))
50
+ if (!fs.existsSync(KEYS_DIR))
51
51
  return [];
52
- return readdirSync(KEYS_DIR)
52
+ return fs.readdirSync(KEYS_DIR)
53
53
  .filter(f => f.endsWith('.txt'))
54
54
  .map(f => {
55
- const content = readFileSync(join(KEYS_DIR, f), 'utf-8');
55
+ const content = fs.readFileSync(join(KEYS_DIR, f), 'utf-8');
56
56
  const project = content.match(/# project: (.+)/)?.[1] ?? content.match(/# repo: (.+)/)?.[1];
57
57
  const pub = content.match(/# public key: (age1[a-z0-9]+)/)?.[1];
58
58
  return project && pub ? { project, public: pub } : null;
@@ -0,0 +1,25 @@
1
+ import { type PathLike, type WriteFileOptions } from 'node:fs';
2
+ /**
3
+ * Filesystem wrapper to allow for easier testing and isolation of side effects.
4
+ * All core logic and commands should use these instead of direct node:fs calls.
5
+ */
6
+ export declare const fs: {
7
+ existsSync: (path: PathLike) => boolean;
8
+ readFileSync: (path: PathLike, options?: {
9
+ encoding?: BufferEncoding;
10
+ flag?: string;
11
+ } | BufferEncoding) => string | Buffer;
12
+ writeFileSync: (path: PathLike, data: string | Uint8Array, options?: WriteFileOptions) => void;
13
+ mkdirSync: (path: PathLike, options?: {
14
+ recursive?: boolean;
15
+ mode?: number;
16
+ }) => string | undefined;
17
+ readdirSync: (path: PathLike, options?: {
18
+ recursive?: boolean;
19
+ }) => string[];
20
+ unlinkSync: (path: PathLike) => void;
21
+ statSync: (path: PathLike) => import("fs").Stats;
22
+ fstatSync: (fd: number) => import("fs").Stats;
23
+ renameSync: (oldPath: PathLike, newPath: PathLike) => void;
24
+ };
25
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/lib/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AAEH,eAAO,MAAM,EAAE;uBACM,QAAQ,KAAG,OAAO;yBAIhB,QAAQ,YAAY;QAAE,QAAQ,CAAC,EAAE,cAAc,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,KAAG,MAAM,GAAG,MAAM;0BAKlG,QAAQ,QAAQ,MAAM,GAAG,UAAU,YAAY,gBAAgB,KAAG,IAAI;sBAI1E,QAAQ,YAAY;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,MAAM,GAAG,SAAS;wBAI7E,QAAQ,YAAY;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,MAAM,EAAE;uBAKvD,QAAQ,KAAG,IAAI;qBAIjB,QAAQ;oBAIT,MAAM;0BAIA,QAAQ,WAAW,QAAQ,KAAG,IAAI;CAGzD,CAAC"}
package/dist/lib/fs.js ADDED
@@ -0,0 +1,36 @@
1
+ import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync, writeFileSync as nodeWriteFileSync, mkdirSync as nodeMkdirSync, readdirSync as nodeReaddirSync, unlinkSync as nodeUnlinkSync, statSync as nodeStatSync, fstatSync as nodeFstatSync, renameSync as nodeRenameSync, } from 'node:fs';
2
+ /**
3
+ * Filesystem wrapper to allow for easier testing and isolation of side effects.
4
+ * All core logic and commands should use these instead of direct node:fs calls.
5
+ */
6
+ export const fs = {
7
+ existsSync: (path) => {
8
+ return nodeExistsSync(path);
9
+ },
10
+ readFileSync: (path, options) => {
11
+ // @ts-ignore - handled by overloads in node:fs
12
+ return nodeReadFileSync(path, options);
13
+ },
14
+ writeFileSync: (path, data, options) => {
15
+ nodeWriteFileSync(path, data, options);
16
+ },
17
+ mkdirSync: (path, options) => {
18
+ return nodeMkdirSync(path, options);
19
+ },
20
+ readdirSync: (path, options) => {
21
+ // @ts-ignore - handled by node:fs
22
+ return nodeReaddirSync(path, options);
23
+ },
24
+ unlinkSync: (path) => {
25
+ nodeUnlinkSync(path);
26
+ },
27
+ statSync: (path) => {
28
+ return nodeStatSync(path);
29
+ },
30
+ fstatSync: (fd) => {
31
+ return nodeFstatSync(fd);
32
+ },
33
+ renameSync: (oldPath, newPath) => {
34
+ nodeRenameSync(oldPath, newPath);
35
+ }
36
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"onepassword.d.ts","sourceRoot":"","sources":["../../src/lib/onepassword.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAUjD,wBAAgB,WAAW,IAAI,OAAO,CAOrC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAOrC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASvE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBvG;AAED,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnD"}
1
+ {"version":3,"file":"onepassword.d.ts","sourceRoot":"","sources":["../../src/lib/onepassword.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,qBAAqB,CAAC;AA8CjD,wBAAgB,WAAW,IAAI,OAAO,CAOrC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAOrC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASvE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBvG;AAED,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnD"}
@@ -1,6 +1,43 @@
1
1
  import { execSync } from 'node:child_process';
2
+ import { platform } from 'node:os';
2
3
  export const OP_ITEM_PREFIX = 'SOPS Key - hush/';
3
- function opExec(command) {
4
+ function showBiometricNotification(reason) {
5
+ const title = 'Hush - 1Password';
6
+ const message = `${reason}\n\n1Password biometric prompt will appear next.`;
7
+ try {
8
+ switch (platform()) {
9
+ case 'darwin': {
10
+ const script = `display dialog "${message}" with title "${title}" buttons {"Continue"} default button "Continue" with icon note`;
11
+ execSync(`osascript -e '${script}'`, { stdio: 'pipe' });
12
+ break;
13
+ }
14
+ case 'win32': {
15
+ const psScript = `
16
+ Add-Type -AssemblyName System.Windows.Forms
17
+ [System.Windows.Forms.MessageBox]::Show("${message}", "${title}", "OK", "Information")
18
+ `;
19
+ execSync(`powershell -Command "${psScript}"`, { stdio: 'pipe' });
20
+ break;
21
+ }
22
+ case 'linux': {
23
+ try {
24
+ execSync(`zenity --info --title="${title}" --text="${message}"`, { stdio: 'pipe' });
25
+ }
26
+ catch {
27
+ execSync(`kdialog --msgbox "${message}" --title "${title}"`, { stdio: 'pipe' });
28
+ }
29
+ break;
30
+ }
31
+ }
32
+ }
33
+ catch {
34
+ // If GUI fails, fall through silently - better to continue than block
35
+ }
36
+ }
37
+ function opExec(command, reason) {
38
+ if (reason) {
39
+ showBiometricNotification(reason);
40
+ }
4
41
  return execSync(`op signin && ${command}`, {
5
42
  encoding: 'utf-8',
6
43
  stdio: 'pipe',
@@ -29,7 +66,7 @@ export function opGetKey(project, vault) {
29
66
  try {
30
67
  const vaultArgs = vault ? ['--vault', vault] : [];
31
68
  const command = ['op', 'item', 'get', `${OP_ITEM_PREFIX}${project}`, ...vaultArgs, '--fields', 'password', '--reveal'].join(' ');
32
- const result = opExec(command);
69
+ const result = opExec(command, `Retrieving encryption key for "${project}" from 1Password.`);
33
70
  return result.trim() || null;
34
71
  }
35
72
  catch {
@@ -47,7 +84,7 @@ export function opStoreKey(project, privateKey, publicKey, vault) {
47
84
  `"public_key[text]=${publicKey}"`,
48
85
  ].join(' ');
49
86
  try {
50
- opExec(command);
87
+ opExec(command, `Backing up encryption key for "${project}" to 1Password.`);
51
88
  }
52
89
  catch (err) {
53
90
  const message = err instanceof Error ? err.message : 'Failed to store in 1Password';
@@ -58,7 +95,7 @@ export function opListKeys(vault) {
58
95
  try {
59
96
  const vaultArgs = vault ? ['--vault', vault] : [];
60
97
  const command = ['op', 'item', 'list', '--categories', 'password', ...vaultArgs, '--format', 'json'].join(' ');
61
- const result = opExec(command);
98
+ const result = opExec(command, 'Listing Hush encryption keys stored in 1Password.');
62
99
  const items = JSON.parse(result);
63
100
  return items
64
101
  .filter(i => i.title.startsWith(OP_ITEM_PREFIX))
package/dist/types.d.ts CHANGED
@@ -50,6 +50,7 @@ export interface SetOptions {
50
50
  root: string;
51
51
  file?: 'shared' | 'development' | 'production' | 'local';
52
52
  key?: string;
53
+ value?: string;
53
54
  gui?: boolean;
54
55
  }
55
56
  export interface RunOptions {
@@ -119,4 +120,94 @@ export interface TraceOptions {
119
120
  }
120
121
  export declare const DEFAULT_SOURCES: SourceFiles;
121
122
  export declare const FORMAT_OUTPUT_FILES: Record<OutputFormat, Record<Environment, string>>;
123
+ export interface HushContext {
124
+ fs: {
125
+ existsSync(path: string): boolean;
126
+ readFileSync(path: string, options?: {
127
+ encoding?: BufferEncoding;
128
+ flag?: string;
129
+ } | BufferEncoding): string | Buffer;
130
+ writeFileSync(path: string, data: string | Uint8Array, options?: {
131
+ encoding?: BufferEncoding;
132
+ mode?: number;
133
+ flag?: string;
134
+ } | BufferEncoding | null): void;
135
+ mkdirSync(path: string, options?: {
136
+ recursive?: boolean;
137
+ mode?: number;
138
+ }): string | undefined;
139
+ readdirSync(path: string, options?: {
140
+ recursive?: boolean;
141
+ withFileTypes?: boolean;
142
+ }): (string | {
143
+ name: string;
144
+ isDirectory(): boolean;
145
+ })[];
146
+ unlinkSync(path: string): void;
147
+ statSync(path: string): {
148
+ isDirectory(): boolean;
149
+ mtime: Date;
150
+ };
151
+ renameSync(oldPath: string, newPath: string): void;
152
+ };
153
+ path: {
154
+ join(...paths: string[]): string;
155
+ };
156
+ exec: {
157
+ spawnSync(command: string, args: string[], options?: any): {
158
+ status: number | null;
159
+ stdout: string | Buffer;
160
+ stderr: string | Buffer;
161
+ error?: Error;
162
+ };
163
+ execSync(command: string, options?: any): string | Buffer;
164
+ };
165
+ logger: {
166
+ log(message: string): void;
167
+ error(message: string): void;
168
+ warn(message: string): void;
169
+ info(message: string): void;
170
+ };
171
+ process: {
172
+ cwd(): string;
173
+ exit(code: number): never;
174
+ env: NodeJS.ProcessEnv;
175
+ stdin: NodeJS.ReadStream;
176
+ stdout: NodeJS.WriteStream;
177
+ };
178
+ config: {
179
+ loadConfig(root: string): HushConfig;
180
+ findProjectRoot(startDir: string): {
181
+ configPath: string;
182
+ projectRoot: string;
183
+ } | null;
184
+ };
185
+ age: {
186
+ ageAvailable(): boolean;
187
+ ageGenerate(): {
188
+ private: string;
189
+ public: string;
190
+ };
191
+ keyExists(project: string): boolean;
192
+ keySave(project: string, key: {
193
+ private: string;
194
+ public: string;
195
+ }): void;
196
+ keyPath(project: string): string;
197
+ keyLoad(project: string): {
198
+ private: string;
199
+ public: string;
200
+ } | null;
201
+ agePublicFromPrivate(privateKey: string): string;
202
+ };
203
+ onepassword: {
204
+ opAvailable(): boolean;
205
+ opGetKey(project: string): string | null;
206
+ opStoreKey(project: string, privateKey: string, publicKey: string): void;
207
+ };
208
+ sops: {
209
+ decrypt(path: string): string;
210
+ isSopsInstalled(): boolean;
211
+ };
212
+ }
122
213
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,9 +1,9 @@
1
1
  export const CURRENT_SCHEMA_VERSION = 2;
2
2
  export const DEFAULT_SOURCES = {
3
- shared: '.env',
4
- development: '.env.development',
5
- production: '.env.production',
6
- local: '.env.local',
3
+ shared: '.hush',
4
+ development: '.hush.development',
5
+ production: '.hush.production',
6
+ local: '.hush.local',
7
7
  };
8
8
  export const FORMAT_OUTPUT_FILES = {
9
9
  dotenv: {
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync } from 'node:fs';
1
+ import { fs } from '../lib/fs.js';
2
2
  import { join } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { spawn } from 'node:child_process';
@@ -8,13 +8,13 @@ const CACHE_FILE = join(CONFIG_DIR, 'update-check.json');
8
8
  const CHECK_INTERVAL_MS = 1000 * 60 * 60 * 24;
9
9
  export function checkForUpdate(currentVersion) {
10
10
  try {
11
- if (!existsSync(CONFIG_DIR)) {
12
- mkdirSync(CONFIG_DIR, { recursive: true });
11
+ if (!fs.existsSync(CONFIG_DIR)) {
12
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
13
13
  }
14
14
  let cache = null;
15
- if (existsSync(CACHE_FILE)) {
15
+ if (fs.existsSync(CACHE_FILE)) {
16
16
  try {
17
- cache = JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));
17
+ cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
18
18
  }
19
19
  catch {
20
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chriscode/hush",
3
- "version": "4.2.0",
3
+ "version": "5.0.1",
4
4
  "description": "SOPS-based secrets management for monorepos. Encrypt once, decrypt everywhere.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -52,8 +52,9 @@
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^20.11.0",
55
+ "@vitest/coverage-v8": "^4.0.17",
55
56
  "typescript": "^5.8.3",
56
- "vitest": "^2.0.0"
57
+ "vitest": "^4.0.17"
57
58
  },
58
59
  "files": [
59
60
  "dist",