@griffin-app/griffin-plan-executor 0.1.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.
- package/README.md +152 -0
- package/dist/adapters/axios.d.ts +5 -0
- package/dist/adapters/axios.d.ts.map +1 -0
- package/dist/adapters/axios.js +36 -0
- package/dist/adapters/axios.js.map +1 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/stub.d.ts +22 -0
- package/dist/adapters/stub.d.ts.map +1 -0
- package/dist/adapters/stub.js +36 -0
- package/dist/adapters/stub.js.map +1 -0
- package/dist/events/emitter.d.ts +68 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +83 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/emitter.test.d.ts +2 -0
- package/dist/events/emitter.test.d.ts.map +1 -0
- package/dist/events/emitter.test.js +251 -0
- package/dist/events/emitter.test.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +109 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +9 -0
- package/dist/events/types.js.map +1 -0
- package/dist/executor.d.ts +4 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +732 -0
- package/dist/executor.js.map +1 -0
- package/dist/executor.test.d.ts +2 -0
- package/dist/executor.test.d.ts.map +1 -0
- package/dist/executor.test.js +1524 -0
- package/dist/executor.test.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/secrets/index.d.ts +14 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +18 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/providers/aws.d.ts +63 -0
- package/dist/secrets/providers/aws.d.ts.map +1 -0
- package/dist/secrets/providers/aws.js +111 -0
- package/dist/secrets/providers/aws.js.map +1 -0
- package/dist/secrets/providers/env.d.ts +36 -0
- package/dist/secrets/providers/env.d.ts.map +1 -0
- package/dist/secrets/providers/env.js +37 -0
- package/dist/secrets/providers/env.js.map +1 -0
- package/dist/secrets/providers/index.d.ts +7 -0
- package/dist/secrets/providers/index.d.ts.map +1 -0
- package/dist/secrets/providers/index.js +7 -0
- package/dist/secrets/providers/index.js.map +1 -0
- package/dist/secrets/providers/vault.d.ts +75 -0
- package/dist/secrets/providers/vault.d.ts.map +1 -0
- package/dist/secrets/providers/vault.js +143 -0
- package/dist/secrets/providers/vault.js.map +1 -0
- package/dist/secrets/registry.d.ts +61 -0
- package/dist/secrets/registry.d.ts.map +1 -0
- package/dist/secrets/registry.js +182 -0
- package/dist/secrets/registry.js.map +1 -0
- package/dist/secrets/resolver.d.ts +40 -0
- package/dist/secrets/resolver.d.ts.map +1 -0
- package/dist/secrets/resolver.js +178 -0
- package/dist/secrets/resolver.js.map +1 -0
- package/dist/secrets/secrets.test.d.ts +2 -0
- package/dist/secrets/secrets.test.d.ts.map +1 -0
- package/dist/secrets/secrets.test.js +243 -0
- package/dist/secrets/secrets.test.js.map +1 -0
- package/dist/secrets/types.d.ts +71 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +38 -0
- package/dist/secrets/types.js.map +1 -0
- package/dist/shared.d.ts +8 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +30 -0
- package/dist/shared.js.map +1 -0
- package/dist/test-plan-types.d.ts +43 -0
- package/dist/test-plan-types.d.ts.map +1 -0
- package/dist/test-plan-types.js +2 -0
- package/dist/test-plan-types.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
- package/src/adapters/axios.ts +41 -0
- package/src/adapters/index.ts +2 -0
- package/src/adapters/stub.ts +47 -0
- package/src/events/emitter.test.ts +316 -0
- package/src/events/emitter.ts +133 -0
- package/src/events/index.ts +2 -0
- package/src/events/types.ts +132 -0
- package/src/executor.test.ts +1674 -0
- package/src/executor.ts +986 -0
- package/src/index.ts +69 -0
- package/src/secrets/index.ts +41 -0
- package/src/secrets/providers/aws.ts +179 -0
- package/src/secrets/providers/env.ts +66 -0
- package/src/secrets/providers/index.ts +15 -0
- package/src/secrets/providers/vault.ts +257 -0
- package/src/secrets/registry.ts +234 -0
- package/src/secrets/resolver.ts +249 -0
- package/src/secrets/secrets.test.ts +318 -0
- package/src/secrets/types.ts +105 -0
- package/src/shared.ts +46 -0
- package/src/test-plan-types.ts +49 -0
- package/src/types.ts +95 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HashiCorp Vault secret provider.
|
|
3
|
+
*
|
|
4
|
+
* Reads secrets from HashiCorp Vault KV secrets engine (v1 and v2).
|
|
5
|
+
* Supports field extraction from JSON secrets.
|
|
6
|
+
*
|
|
7
|
+
* Usage in DSL:
|
|
8
|
+
* secret("vault:secret/data/myapp/config")
|
|
9
|
+
* secret("vault:secret/data/myapp/config", { field: "api_key" })
|
|
10
|
+
* secret("vault:secret/data/myapp/config", { version: "2" })
|
|
11
|
+
*/
|
|
12
|
+
import { SecretResolutionError } from "../types.js";
|
|
13
|
+
export class VaultProvider {
|
|
14
|
+
name = "vault";
|
|
15
|
+
address;
|
|
16
|
+
token;
|
|
17
|
+
httpClient;
|
|
18
|
+
namespace;
|
|
19
|
+
kvVersion;
|
|
20
|
+
prefix;
|
|
21
|
+
// Simple in-memory cache with TTL
|
|
22
|
+
cache = new Map();
|
|
23
|
+
cacheTtlMs = 5 * 60 * 1000; // 5 minutes
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.address = options.address.replace(/\/$/, ""); // Remove trailing slash
|
|
26
|
+
this.token = options.token;
|
|
27
|
+
this.httpClient = options.httpClient;
|
|
28
|
+
this.namespace = options.namespace;
|
|
29
|
+
this.kvVersion = options.kvVersion ?? 2;
|
|
30
|
+
this.prefix = options.prefix ?? "";
|
|
31
|
+
}
|
|
32
|
+
async resolve(ref, options) {
|
|
33
|
+
const secretPath = this.prefix + ref;
|
|
34
|
+
const version = options?.version;
|
|
35
|
+
const cacheKey = `${secretPath}:${version ?? "latest"}`;
|
|
36
|
+
// Check cache
|
|
37
|
+
const cached = this.cache.get(cacheKey);
|
|
38
|
+
if (cached && cached.expires > Date.now()) {
|
|
39
|
+
return this.extractField(cached.value, options?.field, ref);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
// Build request URL
|
|
43
|
+
let url = `${this.address}/v1/${secretPath}`;
|
|
44
|
+
if (this.kvVersion === 2 && version) {
|
|
45
|
+
url += `?version=${version}`;
|
|
46
|
+
}
|
|
47
|
+
// Build headers
|
|
48
|
+
const headers = {
|
|
49
|
+
"X-Vault-Token": this.token,
|
|
50
|
+
};
|
|
51
|
+
if (this.namespace) {
|
|
52
|
+
headers["X-Vault-Namespace"] = this.namespace;
|
|
53
|
+
}
|
|
54
|
+
const response = await this.httpClient.get(url, { headers });
|
|
55
|
+
if (response.status === 404) {
|
|
56
|
+
throw new SecretResolutionError(`Secret "${secretPath}" not found in Vault`, { provider: this.name, ref });
|
|
57
|
+
}
|
|
58
|
+
if (response.status === 403) {
|
|
59
|
+
throw new SecretResolutionError(`Access denied to secret "${secretPath}". Check Vault policies.`, { provider: this.name, ref });
|
|
60
|
+
}
|
|
61
|
+
if (response.status !== 200) {
|
|
62
|
+
throw new SecretResolutionError(`Vault returned status ${response.status} for secret "${secretPath}"`, { provider: this.name, ref });
|
|
63
|
+
}
|
|
64
|
+
// Parse response based on KV version
|
|
65
|
+
const data = response.data;
|
|
66
|
+
let secretData;
|
|
67
|
+
if (this.kvVersion === 2) {
|
|
68
|
+
// KV v2 wraps data in an extra "data" object
|
|
69
|
+
const kvData = data?.data;
|
|
70
|
+
if (!kvData?.data) {
|
|
71
|
+
throw new SecretResolutionError(`Invalid KV v2 response structure for secret "${secretPath}"`, { provider: this.name, ref });
|
|
72
|
+
}
|
|
73
|
+
secretData = kvData.data;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// KV v1 has data directly
|
|
77
|
+
if (!data?.data || typeof data.data !== "object") {
|
|
78
|
+
throw new SecretResolutionError(`Invalid KV v1 response structure for secret "${secretPath}"`, { provider: this.name, ref });
|
|
79
|
+
}
|
|
80
|
+
secretData = data.data;
|
|
81
|
+
}
|
|
82
|
+
// Cache the secret data
|
|
83
|
+
this.cache.set(cacheKey, {
|
|
84
|
+
value: secretData,
|
|
85
|
+
expires: Date.now() + this.cacheTtlMs,
|
|
86
|
+
});
|
|
87
|
+
return this.extractField(secretData, options?.field, ref);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error instanceof SecretResolutionError) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
throw new SecretResolutionError(`Failed to retrieve secret "${secretPath}" from Vault: ${error instanceof Error ? error.message : String(error)}`, { provider: this.name, ref, cause: error });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Extract a field from the secret data.
|
|
98
|
+
* If no field is specified, returns the entire data as JSON string.
|
|
99
|
+
*/
|
|
100
|
+
extractField(secretData, field, ref) {
|
|
101
|
+
if (!field) {
|
|
102
|
+
// Return entire secret as JSON if no field specified
|
|
103
|
+
return JSON.stringify(secretData);
|
|
104
|
+
}
|
|
105
|
+
const value = secretData[field];
|
|
106
|
+
if (value === undefined) {
|
|
107
|
+
throw new SecretResolutionError(`Field "${field}" not found in secret "${ref}"`, { provider: this.name, ref });
|
|
108
|
+
}
|
|
109
|
+
// Convert to string if not already
|
|
110
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
111
|
+
}
|
|
112
|
+
async validate() {
|
|
113
|
+
// Verify we can authenticate with Vault
|
|
114
|
+
try {
|
|
115
|
+
const headers = {
|
|
116
|
+
"X-Vault-Token": this.token,
|
|
117
|
+
};
|
|
118
|
+
if (this.namespace) {
|
|
119
|
+
headers["X-Vault-Namespace"] = this.namespace;
|
|
120
|
+
}
|
|
121
|
+
const response = await this.httpClient.get(`${this.address}/v1/auth/token/lookup-self`, { headers });
|
|
122
|
+
if (response.status === 403) {
|
|
123
|
+
throw new Error("Invalid or expired Vault token");
|
|
124
|
+
}
|
|
125
|
+
if (response.status !== 200) {
|
|
126
|
+
throw new Error(`Vault authentication check failed with status ${response.status}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error instanceof Error && error.message.includes("Vault")) {
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`Failed to connect to Vault at ${this.address}: ${error instanceof Error ? error.message : String(error)}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Clear the cache. Useful for testing or forced refresh.
|
|
138
|
+
*/
|
|
139
|
+
clearCache() {
|
|
140
|
+
this.cache.clear();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/secrets/providers/vault.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret provider registry for managing multiple secret providers.
|
|
3
|
+
*/
|
|
4
|
+
import type { SecretProvider, SecretRefData } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Registry for managing and accessing secret providers.
|
|
7
|
+
* Supports multiple providers simultaneously (e.g., env + aws + vault).
|
|
8
|
+
*/
|
|
9
|
+
export declare class SecretProviderRegistry {
|
|
10
|
+
private providers;
|
|
11
|
+
/**
|
|
12
|
+
* Register a secret provider.
|
|
13
|
+
* @param provider - The provider to register
|
|
14
|
+
* @throws Error if a provider with the same name is already registered
|
|
15
|
+
*/
|
|
16
|
+
register(provider: SecretProvider): void;
|
|
17
|
+
/**
|
|
18
|
+
* Unregister a secret provider by name.
|
|
19
|
+
* @param name - The provider name to remove
|
|
20
|
+
* @returns true if the provider was removed, false if it wasn't registered
|
|
21
|
+
*/
|
|
22
|
+
unregister(name: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get a registered provider by name.
|
|
25
|
+
* @param name - The provider name
|
|
26
|
+
* @throws Error if the provider is not registered
|
|
27
|
+
*/
|
|
28
|
+
get(name: string): SecretProvider;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a provider is registered.
|
|
31
|
+
*/
|
|
32
|
+
has(name: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get all registered provider names.
|
|
35
|
+
*/
|
|
36
|
+
getProviderNames(): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a secret reference using the appropriate provider.
|
|
39
|
+
* @param secretRef - The secret reference data
|
|
40
|
+
* @returns The resolved secret value
|
|
41
|
+
* @throws SecretResolutionError if resolution fails
|
|
42
|
+
*/
|
|
43
|
+
resolve(secretRef: SecretRefData): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve multiple secrets, grouped by provider for efficiency.
|
|
46
|
+
* @param refs - Array of secret reference data
|
|
47
|
+
* @returns Map of "provider:ref" to resolved value
|
|
48
|
+
* @throws SecretResolutionError if any resolution fails (fail-fast)
|
|
49
|
+
*/
|
|
50
|
+
resolveMany(refs: SecretRefData[]): Promise<Map<string, string>>;
|
|
51
|
+
/**
|
|
52
|
+
* Validate all registered providers.
|
|
53
|
+
* @throws Error if any provider validation fails
|
|
54
|
+
*/
|
|
55
|
+
validateAll(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a unique key for a secret reference (for caching/deduplication).
|
|
58
|
+
*/
|
|
59
|
+
makeKey(secretRef: SecretRefData): string;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/secrets/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEd,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,SAAS,CAAqC;IAEtD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IASxC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAcjC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;;;OAKG;IACG,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBxD;;;;;OAKG;IACG,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA6FtE;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBlC;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM;CAM1C"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret provider registry for managing multiple secret providers.
|
|
3
|
+
*/
|
|
4
|
+
import { SecretResolutionError } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Registry for managing and accessing secret providers.
|
|
7
|
+
* Supports multiple providers simultaneously (e.g., env + aws + vault).
|
|
8
|
+
*/
|
|
9
|
+
export class SecretProviderRegistry {
|
|
10
|
+
providers = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Register a secret provider.
|
|
13
|
+
* @param provider - The provider to register
|
|
14
|
+
* @throws Error if a provider with the same name is already registered
|
|
15
|
+
*/
|
|
16
|
+
register(provider) {
|
|
17
|
+
if (this.providers.has(provider.name)) {
|
|
18
|
+
throw new Error(`Secret provider "${provider.name}" is already registered`);
|
|
19
|
+
}
|
|
20
|
+
this.providers.set(provider.name, provider);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Unregister a secret provider by name.
|
|
24
|
+
* @param name - The provider name to remove
|
|
25
|
+
* @returns true if the provider was removed, false if it wasn't registered
|
|
26
|
+
*/
|
|
27
|
+
unregister(name) {
|
|
28
|
+
return this.providers.delete(name);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get a registered provider by name.
|
|
32
|
+
* @param name - The provider name
|
|
33
|
+
* @throws Error if the provider is not registered
|
|
34
|
+
*/
|
|
35
|
+
get(name) {
|
|
36
|
+
const provider = this.providers.get(name);
|
|
37
|
+
if (!provider) {
|
|
38
|
+
const available = [...this.providers.keys()];
|
|
39
|
+
throw new SecretResolutionError(`Secret provider "${name}" is not configured. Available providers: ${available.length > 0 ? available.join(", ") : "(none)"}`, { provider: name, ref: "" });
|
|
40
|
+
}
|
|
41
|
+
return provider;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a provider is registered.
|
|
45
|
+
*/
|
|
46
|
+
has(name) {
|
|
47
|
+
return this.providers.has(name);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get all registered provider names.
|
|
51
|
+
*/
|
|
52
|
+
getProviderNames() {
|
|
53
|
+
return [...this.providers.keys()];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a secret reference using the appropriate provider.
|
|
57
|
+
* @param secretRef - The secret reference data
|
|
58
|
+
* @returns The resolved secret value
|
|
59
|
+
* @throws SecretResolutionError if resolution fails
|
|
60
|
+
*/
|
|
61
|
+
async resolve(secretRef) {
|
|
62
|
+
const provider = this.get(secretRef.provider);
|
|
63
|
+
try {
|
|
64
|
+
return await provider.resolve(secretRef.ref, {
|
|
65
|
+
version: secretRef.version,
|
|
66
|
+
field: secretRef.field,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof SecretResolutionError) {
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
throw new SecretResolutionError(`Failed to resolve secret "${secretRef.provider}:${secretRef.ref}": ${error instanceof Error ? error.message : String(error)}`, {
|
|
74
|
+
provider: secretRef.provider,
|
|
75
|
+
ref: secretRef.ref,
|
|
76
|
+
cause: error,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Resolve multiple secrets, grouped by provider for efficiency.
|
|
82
|
+
* @param refs - Array of secret reference data
|
|
83
|
+
* @returns Map of "provider:ref" to resolved value
|
|
84
|
+
* @throws SecretResolutionError if any resolution fails (fail-fast)
|
|
85
|
+
*/
|
|
86
|
+
async resolveMany(refs) {
|
|
87
|
+
if (refs.length === 0) {
|
|
88
|
+
return new Map();
|
|
89
|
+
}
|
|
90
|
+
// Group refs by provider
|
|
91
|
+
const byProvider = new Map();
|
|
92
|
+
for (const secretRef of refs) {
|
|
93
|
+
const key = this.makeKey(secretRef);
|
|
94
|
+
const group = byProvider.get(secretRef.provider) || [];
|
|
95
|
+
group.push({
|
|
96
|
+
ref: secretRef.ref,
|
|
97
|
+
options: {
|
|
98
|
+
version: secretRef.version,
|
|
99
|
+
field: secretRef.field,
|
|
100
|
+
},
|
|
101
|
+
key,
|
|
102
|
+
});
|
|
103
|
+
byProvider.set(secretRef.provider, group);
|
|
104
|
+
}
|
|
105
|
+
// Resolve each provider's secrets
|
|
106
|
+
const results = new Map();
|
|
107
|
+
for (const [providerName, providerRefs] of byProvider) {
|
|
108
|
+
const provider = this.get(providerName);
|
|
109
|
+
// Use batch resolution if available, otherwise resolve individually
|
|
110
|
+
if (provider.resolveMany) {
|
|
111
|
+
const batchRefs = providerRefs.map((r) => ({
|
|
112
|
+
ref: r.ref,
|
|
113
|
+
options: r.options,
|
|
114
|
+
}));
|
|
115
|
+
try {
|
|
116
|
+
const batchResults = await provider.resolveMany(batchRefs);
|
|
117
|
+
for (const providerRef of providerRefs) {
|
|
118
|
+
const value = batchResults.get(providerRef.ref);
|
|
119
|
+
if (value === undefined) {
|
|
120
|
+
throw new SecretResolutionError(`Secret "${providerName}:${providerRef.ref}" not found in batch results`, { provider: providerName, ref: providerRef.ref });
|
|
121
|
+
}
|
|
122
|
+
results.set(providerRef.key, value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (error instanceof SecretResolutionError) {
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
throw new SecretResolutionError(`Batch resolution failed for provider "${providerName}": ${error instanceof Error ? error.message : String(error)}`, {
|
|
130
|
+
provider: providerName,
|
|
131
|
+
ref: providerRefs[0]?.ref || "",
|
|
132
|
+
cause: error,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// Resolve individually (fail-fast on first error)
|
|
138
|
+
for (const providerRef of providerRefs) {
|
|
139
|
+
try {
|
|
140
|
+
const value = await provider.resolve(providerRef.ref, providerRef.options);
|
|
141
|
+
results.set(providerRef.key, value);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof SecretResolutionError) {
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
throw new SecretResolutionError(`Failed to resolve secret "${providerName}:${providerRef.ref}": ${error instanceof Error ? error.message : String(error)}`, { provider: providerName, ref: providerRef.ref, cause: error });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return results;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Validate all registered providers.
|
|
156
|
+
* @throws Error if any provider validation fails
|
|
157
|
+
*/
|
|
158
|
+
async validateAll() {
|
|
159
|
+
for (const [name, provider] of this.providers) {
|
|
160
|
+
if (provider.validate) {
|
|
161
|
+
try {
|
|
162
|
+
await provider.validate();
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
throw new Error(`Provider "${name}" validation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Create a unique key for a secret reference (for caching/deduplication).
|
|
172
|
+
*/
|
|
173
|
+
makeKey(secretRef) {
|
|
174
|
+
const parts = [secretRef.provider, secretRef.ref];
|
|
175
|
+
if (secretRef.version)
|
|
176
|
+
parts.push(`v:${secretRef.version}`);
|
|
177
|
+
if (secretRef.field)
|
|
178
|
+
parts.push(`f:${secretRef.field}`);
|
|
179
|
+
return parts.join(":");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/secrets/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret resolution utilities for test plans.
|
|
3
|
+
*/
|
|
4
|
+
import { TestPlanV1 } from "griffin/types";
|
|
5
|
+
import type { SecretProviderRegistry } from "./registry.js";
|
|
6
|
+
import type { SecretRefData } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Collected secret references from a plan.
|
|
9
|
+
*/
|
|
10
|
+
interface CollectedSecrets {
|
|
11
|
+
/** All unique secret references found */
|
|
12
|
+
refs: SecretRefData[];
|
|
13
|
+
/** Paths where secrets were found (for substitution) */
|
|
14
|
+
paths: Array<{
|
|
15
|
+
path: (string | number)[];
|
|
16
|
+
secretRef: SecretRefData;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Collect all secret references from a test plan.
|
|
21
|
+
* Scans endpoint headers and bodies for $secret markers.
|
|
22
|
+
*/
|
|
23
|
+
export declare function collectSecretsFromPlan(plan: TestPlanV1): CollectedSecrets;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve all secrets in a plan and return a new plan with substituted values.
|
|
26
|
+
* The original plan is not modified.
|
|
27
|
+
*
|
|
28
|
+
* @param plan - The test plan containing secret references
|
|
29
|
+
* @param registry - The secret provider registry
|
|
30
|
+
* @returns A new plan with all secrets resolved to their values
|
|
31
|
+
* @throws SecretResolutionError if any secret cannot be resolved (fail-fast)
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveSecretsInPlan(plan: TestPlanV1, registry: SecretProviderRegistry): Promise<TestPlanV1>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if a plan contains any secret references.
|
|
36
|
+
* Useful for short-circuiting resolution when no secrets are present.
|
|
37
|
+
*/
|
|
38
|
+
export declare function planHasSecrets(plan: TestPlanV1): boolean;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/secrets/resolver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAQ,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3D;;GAEG;AACH,UAAU,gBAAgB;IACxB,yCAAyC;IACzC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,wDAAwD;IACxD,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;QAC1B,SAAS,EAAE,aAAa,CAAC;KAC1B,CAAC,CAAC;CACJ;AAwCD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAmDzE;AAsCD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,sBAAsB,GAC/B,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAsBxD"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret resolution utilities for test plans.
|
|
3
|
+
*/
|
|
4
|
+
import { NodeType } from "griffin/schema";
|
|
5
|
+
import { isSecretRef } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Recursively collect all secret references from a value.
|
|
8
|
+
* @param value - The value to scan
|
|
9
|
+
* @param currentPath - Current path in the object tree
|
|
10
|
+
* @param collected - Accumulator for found secrets
|
|
11
|
+
*/
|
|
12
|
+
function collectSecretsFromValue(value, currentPath, collected) {
|
|
13
|
+
if (value === null || value === undefined) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (isSecretRef(value)) {
|
|
17
|
+
collected.refs.push(value.$secret);
|
|
18
|
+
collected.paths.push({
|
|
19
|
+
path: [...currentPath],
|
|
20
|
+
secretRef: value.$secret,
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
for (let i = 0; i < value.length; i++) {
|
|
26
|
+
collectSecretsFromValue(value[i], [...currentPath, i], collected);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (typeof value === "object") {
|
|
31
|
+
for (const [key, val] of Object.entries(value)) {
|
|
32
|
+
collectSecretsFromValue(val, [...currentPath, key], collected);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Collect all secret references from a test plan.
|
|
38
|
+
* Scans endpoint headers and bodies for $secret markers.
|
|
39
|
+
*/
|
|
40
|
+
export function collectSecretsFromPlan(plan) {
|
|
41
|
+
const collected = {
|
|
42
|
+
refs: [],
|
|
43
|
+
paths: [],
|
|
44
|
+
};
|
|
45
|
+
for (let nodeIndex = 0; nodeIndex < plan.nodes.length; nodeIndex++) {
|
|
46
|
+
const node = plan.nodes[nodeIndex];
|
|
47
|
+
// Only endpoints can have secrets (in headers and body)
|
|
48
|
+
if (node.type !== NodeType.ENDPOINT) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
//const endpoint = node;
|
|
52
|
+
// Scan headers
|
|
53
|
+
if (node.headers) {
|
|
54
|
+
for (const [headerKey, headerValue] of Object.entries(node.headers)) {
|
|
55
|
+
collectSecretsFromValue(headerValue, ["nodes", nodeIndex, "headers", headerKey], collected);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Scan body
|
|
59
|
+
if (node.body !== undefined) {
|
|
60
|
+
collectSecretsFromValue(node.body, ["nodes", nodeIndex, "body"], collected);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Deduplicate refs by creating a unique key
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
const uniqueRefs = [];
|
|
66
|
+
for (const ref of collected.refs) {
|
|
67
|
+
const key = `${ref.provider}:${ref.ref}:${ref.version || ""}:${ref.field || ""}`;
|
|
68
|
+
if (!seen.has(key)) {
|
|
69
|
+
seen.add(key);
|
|
70
|
+
uniqueRefs.push(ref);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
collected.refs = uniqueRefs;
|
|
74
|
+
return collected;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set a value at a path in an object.
|
|
78
|
+
* Creates intermediate objects/arrays as needed.
|
|
79
|
+
*/
|
|
80
|
+
function setAtPath(obj, path, value) {
|
|
81
|
+
if (path.length === 0) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
let current = obj;
|
|
85
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
86
|
+
const key = path[i];
|
|
87
|
+
if (current[key] === undefined) {
|
|
88
|
+
// Create intermediate object or array based on next key type
|
|
89
|
+
current[key] = typeof path[i + 1] === "number" ? [] : {};
|
|
90
|
+
}
|
|
91
|
+
current = current[key];
|
|
92
|
+
}
|
|
93
|
+
current[path[path.length - 1]] = value;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Deep clone a value.
|
|
97
|
+
*/
|
|
98
|
+
function deepClone(value) {
|
|
99
|
+
if (value === null || value === undefined) {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
return JSON.parse(JSON.stringify(value));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resolve all secrets in a plan and return a new plan with substituted values.
|
|
106
|
+
* The original plan is not modified.
|
|
107
|
+
*
|
|
108
|
+
* @param plan - The test plan containing secret references
|
|
109
|
+
* @param registry - The secret provider registry
|
|
110
|
+
* @returns A new plan with all secrets resolved to their values
|
|
111
|
+
* @throws SecretResolutionError if any secret cannot be resolved (fail-fast)
|
|
112
|
+
*/
|
|
113
|
+
export async function resolveSecretsInPlan(plan, registry) {
|
|
114
|
+
// Collect all secret references
|
|
115
|
+
const collected = collectSecretsFromPlan(plan);
|
|
116
|
+
if (collected.refs.length === 0) {
|
|
117
|
+
// No secrets to resolve
|
|
118
|
+
return plan;
|
|
119
|
+
}
|
|
120
|
+
// Resolve all secrets (fail-fast on any error)
|
|
121
|
+
const resolved = await registry.resolveMany(collected.refs);
|
|
122
|
+
// Clone the plan for modification
|
|
123
|
+
const resolvedPlan = deepClone(plan);
|
|
124
|
+
// Substitute resolved values at each path
|
|
125
|
+
for (const { path, secretRef } of collected.paths) {
|
|
126
|
+
const key = registry.makeKey(secretRef);
|
|
127
|
+
const value = resolved.get(key);
|
|
128
|
+
if (value === undefined) {
|
|
129
|
+
// This shouldn't happen if resolveMany worked correctly
|
|
130
|
+
throw new Error(`Internal error: resolved value not found for secret "${secretRef.provider}:${secretRef.ref}"`);
|
|
131
|
+
}
|
|
132
|
+
setAtPath(resolvedPlan, path, value);
|
|
133
|
+
}
|
|
134
|
+
return resolvedPlan;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if a plan contains any secret references.
|
|
138
|
+
* Useful for short-circuiting resolution when no secrets are present.
|
|
139
|
+
*/
|
|
140
|
+
export function planHasSecrets(plan) {
|
|
141
|
+
for (const node of plan.nodes) {
|
|
142
|
+
if (node.type !== NodeType.ENDPOINT) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// Check headers
|
|
146
|
+
if (node.headers) {
|
|
147
|
+
for (const headerValue of Object.values(node.headers)) {
|
|
148
|
+
if (isSecretRef(headerValue)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Check body (recursive check)
|
|
154
|
+
if (node.body !== undefined && containsSecretRef(node.body)) {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Recursively check if a value contains any secret references.
|
|
162
|
+
*/
|
|
163
|
+
function containsSecretRef(value) {
|
|
164
|
+
if (value === null || value === undefined) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (isSecretRef(value)) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
return value.some(containsSecretRef);
|
|
172
|
+
}
|
|
173
|
+
if (typeof value === "object") {
|
|
174
|
+
return Object.values(value).some(containsSecretRef);
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/secrets/resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.test.d.ts","sourceRoot":"","sources":["../../src/secrets/secrets.test.ts"],"names":[],"mappings":""}
|