@pikku/core 0.12.71 → 0.12.72

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.
@@ -1,78 +0,0 @@
1
- import { execFileSync } from 'child_process'
2
- import type { SecretService } from './secret-service.js'
3
-
4
- /**
5
- * Service for retrieving secrets from gopass.
6
- * Requires gopass to be installed and configured on the system.
7
- */
8
- export class GopassSecretService implements SecretService {
9
- constructor(private prefix: string = '') {}
10
-
11
- private getFullKey(key: string): string {
12
- if (!/^[\w.\-/]+$/.test(key)) {
13
- throw new Error(`Invalid secret key format: ${key}`)
14
- }
15
- return this.prefix ? `${this.prefix}${key}` : key
16
- }
17
-
18
- public async getSecret<T = string>(key: string): Promise<T> {
19
- const fullKey = this.getFullKey(key)
20
- try {
21
- const raw = execFileSync('gopass', ['show', '-o', fullKey], {
22
- encoding: 'utf8',
23
- }).trim()
24
- try {
25
- return JSON.parse(raw) as T
26
- } catch {
27
- return raw as unknown as T
28
- }
29
- } catch (error: any) {
30
- throw new Error(`Secret Not Found: ${key}`, { cause: error })
31
- }
32
- }
33
-
34
- public async hasSecret(key: string): Promise<boolean> {
35
- const fullKey = this.getFullKey(key)
36
- try {
37
- execFileSync('gopass', ['show', '-o', fullKey], { encoding: 'utf8' })
38
- return true
39
- } catch {
40
- return false
41
- }
42
- }
43
-
44
- public async setSecret(key: string, value: unknown): Promise<void> {
45
- const fullKey = this.getFullKey(key)
46
- const encoded = typeof value === 'string' ? value : JSON.stringify(value)
47
- try {
48
- execFileSync('gopass', ['insert', '-f', fullKey], {
49
- encoding: 'utf8',
50
- input: encoded,
51
- stdio: ['pipe', 'pipe', 'pipe'],
52
- })
53
- } catch (error: any) {
54
- throw new Error(`Failed to set secret: ${key}`, { cause: error })
55
- }
56
- }
57
-
58
- public async deleteSecret(key: string): Promise<void> {
59
- const fullKey = this.getFullKey(key)
60
- try {
61
- execFileSync('gopass', ['rm', '-f', fullKey], { encoding: 'utf8' })
62
- } catch {
63
- // Ignore errors if secret doesn't exist
64
- }
65
- }
66
-
67
- public async getSecrets<
68
- T extends Record<string, unknown> = Record<string, unknown>,
69
- >(keys: (keyof T & string)[]): Promise<Partial<T>> {
70
- const results = await Promise.allSettled(keys.map((k) => this.getSecret(k)))
71
- const out: Record<string, unknown> = {}
72
- keys.forEach((key, i) => {
73
- if (results[i].status === 'fulfilled')
74
- out[key] = (results[i] as PromiseFulfilledResult<unknown>).value
75
- })
76
- return out as Partial<T>
77
- }
78
- }