@ayronforge/envil 0.6.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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/cli/dotenv-codec.d.ts +3 -0
- package/dist/cli/fs-utils.d.ts +7 -0
- package/dist/cli/generate-env-ts.d.ts +2 -0
- package/dist/cli/generate-example.d.ts +2 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/infer.d.ts +6 -0
- package/dist/cli/literals.d.ts +5 -0
- package/dist/cli/manifest-codec.d.ts +3 -0
- package/dist/cli/types.d.ts +61 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +1249 -0
- package/dist/cli.js.map +18 -0
- package/dist/env.d.ts +14 -0
- package/dist/errors.d.ts +10 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +443 -0
- package/dist/index.js.map +17 -0
- package/dist/prefix.d.ts +6 -0
- package/dist/presets.d.ts +30 -0
- package/dist/presets.js +26 -0
- package/dist/presets.js.map +10 -0
- package/dist/resolvers/aws.d.ts +9 -0
- package/dist/resolvers/aws.js +146 -0
- package/dist/resolvers/aws.js.map +12 -0
- package/dist/resolvers/azure.d.ts +10 -0
- package/dist/resolvers/azure.js +85 -0
- package/dist/resolvers/azure.js.map +12 -0
- package/dist/resolvers/gcp.d.ts +10 -0
- package/dist/resolvers/gcp.js +88 -0
- package/dist/resolvers/gcp.js.map +12 -0
- package/dist/resolvers/onepassword.d.ts +9 -0
- package/dist/resolvers/onepassword.js +91 -0
- package/dist/resolvers/onepassword.js.map +12 -0
- package/dist/resolvers/remote.d.ts +9 -0
- package/dist/resolvers/types.d.ts +15 -0
- package/dist/resolvers/utils.d.ts +15 -0
- package/dist/safe-env.d.ts +23 -0
- package/dist/schemas.d.ts +30 -0
- package/dist/types.d.ts +41 -0
- package/package.json +109 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/resolvers/aws.ts
|
|
10
|
+
import { Effect as Effect2 } from "effect";
|
|
11
|
+
|
|
12
|
+
// src/resolvers/utils.ts
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
|
|
15
|
+
// src/resolvers/types.ts
|
|
16
|
+
import { Data } from "effect";
|
|
17
|
+
|
|
18
|
+
class ResolverError extends Data.TaggedError("ResolverError") {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/resolvers/utils.ts
|
|
22
|
+
function toResolverError(resolver, message, cause) {
|
|
23
|
+
return new ResolverError({ resolver, message, cause });
|
|
24
|
+
}
|
|
25
|
+
function tryInitializeClient(resolver, message, initialize) {
|
|
26
|
+
return Effect.tryPromise({
|
|
27
|
+
try: initialize,
|
|
28
|
+
catch: (cause) => toResolverError(resolver, message, cause)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function strictOrElse(effect, options) {
|
|
32
|
+
return options.strict ? effect.pipe(Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause))) : effect.pipe(Effect.orElseSucceed(options.fallback));
|
|
33
|
+
}
|
|
34
|
+
function keyValueResultsToRecord(values) {
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const { envKey, value } of values) {
|
|
37
|
+
result[envKey] = value;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function fillMissingMapValues(ids, values) {
|
|
42
|
+
for (const id of ids) {
|
|
43
|
+
if (!values.has(id)) {
|
|
44
|
+
values.set(id, undefined);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/resolvers/aws.ts
|
|
50
|
+
function createSdkClient(region) {
|
|
51
|
+
return tryInitializeClient("aws", "Failed to initialize AWS Secrets Manager client", async () => {
|
|
52
|
+
const sdk = await import("@aws-sdk/client-secrets-manager");
|
|
53
|
+
const sdkClient = new sdk.SecretsManagerClient(region ? { region } : {});
|
|
54
|
+
return {
|
|
55
|
+
getSecret: async (secretId) => {
|
|
56
|
+
const response = await sdkClient.send(new sdk.GetSecretValueCommand({ SecretId: secretId }));
|
|
57
|
+
return response.SecretString ?? undefined;
|
|
58
|
+
},
|
|
59
|
+
getSecrets: async (secretIds) => {
|
|
60
|
+
const result = new Map;
|
|
61
|
+
for (let i = 0;i < secretIds.length; i += 20) {
|
|
62
|
+
const batch = secretIds.slice(i, i + 20);
|
|
63
|
+
const response = await sdkClient.send(new sdk.BatchGetSecretValueCommand({ SecretIdList: batch }));
|
|
64
|
+
for (const secretValue of response.SecretValues ?? []) {
|
|
65
|
+
if (secretValue.Name) {
|
|
66
|
+
result.set(secretValue.Name, secretValue.SecretString ?? undefined);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
fillMissingMapValues(batch, result);
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function fromAwsSecrets(opts) {
|
|
77
|
+
return Effect2.gen(function* () {
|
|
78
|
+
const strict = opts.strict ?? false;
|
|
79
|
+
const client = yield* createSdkClient(opts.region);
|
|
80
|
+
const secretIdToKeys = new Map;
|
|
81
|
+
for (const [envKey, ref] of Object.entries(opts.secrets)) {
|
|
82
|
+
const hashIndex = ref.indexOf("#");
|
|
83
|
+
const secretId = hashIndex >= 0 ? ref.slice(0, hashIndex) : ref;
|
|
84
|
+
const jsonKey = hashIndex >= 0 ? ref.slice(hashIndex + 1) : undefined;
|
|
85
|
+
const existing = secretIdToKeys.get(secretId) ?? [];
|
|
86
|
+
existing.push({ envKey, jsonKey });
|
|
87
|
+
secretIdToKeys.set(secretId, existing);
|
|
88
|
+
}
|
|
89
|
+
const uniqueSecretIds = [...secretIdToKeys.keys()];
|
|
90
|
+
const secretValues = new Map;
|
|
91
|
+
if (uniqueSecretIds.length === 1) {
|
|
92
|
+
const secretId = uniqueSecretIds[0];
|
|
93
|
+
const value = yield* strictOrElse(Effect2.tryPromise(() => client.getSecret(secretId)), {
|
|
94
|
+
strict,
|
|
95
|
+
resolver: "aws",
|
|
96
|
+
message: `Failed to resolve secret "${secretId}"`,
|
|
97
|
+
fallback: () => {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
secretValues.set(secretId, value);
|
|
102
|
+
} else {
|
|
103
|
+
const batchResult = yield* strictOrElse(Effect2.tryPromise(() => client.getSecrets(uniqueSecretIds)), {
|
|
104
|
+
strict,
|
|
105
|
+
resolver: "aws",
|
|
106
|
+
message: "Failed to resolve AWS secrets batch",
|
|
107
|
+
fallback: () => new Map
|
|
108
|
+
});
|
|
109
|
+
for (const [id, value] of batchResult) {
|
|
110
|
+
secretValues.set(id, value);
|
|
111
|
+
}
|
|
112
|
+
fillMissingMapValues(uniqueSecretIds, secretValues);
|
|
113
|
+
}
|
|
114
|
+
const result = {};
|
|
115
|
+
for (const [secretId, entries] of secretIdToKeys) {
|
|
116
|
+
const rawValue = secretValues.get(secretId);
|
|
117
|
+
for (const { envKey, jsonKey } of entries) {
|
|
118
|
+
if (rawValue === undefined) {
|
|
119
|
+
result[envKey] = undefined;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!jsonKey) {
|
|
123
|
+
result[envKey] = rawValue;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const parsed = JSON.parse(rawValue);
|
|
128
|
+
result[envKey] = parsed[jsonKey] !== undefined ? String(parsed[jsonKey]) : undefined;
|
|
129
|
+
} catch (cause) {
|
|
130
|
+
if (strict) {
|
|
131
|
+
return yield* toResolverError("aws", `Failed to parse secret "${secretId}" as JSON while extracting key "${jsonKey}"`, cause);
|
|
132
|
+
}
|
|
133
|
+
result[envKey] = undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
fromAwsSecrets,
|
|
142
|
+
ResolverError
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
//# debugId=CF166752E79C53F364756E2164756E21
|
|
146
|
+
//# sourceMappingURL=aws.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/resolvers/aws.ts", "../src/resolvers/utils.ts", "../src/resolvers/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError, type ResolverResult } from \"./types.ts\";\nimport {\n fillMissingMapValues,\n strictOrElse,\n toResolverError,\n tryInitializeClient,\n} from \"./utils.ts\";\n\nexport { ResolverError } from \"./types.ts\";\n\ninterface AwsSecretsOptions<K extends string = string> {\n secrets: Record<K, string>;\n region?: string;\n strict?: boolean;\n}\n\nfunction createSdkClient(region?: string): Effect.Effect<\n {\n getSecret: (secretId: string) => Promise<string | undefined>;\n getSecrets: (secretIds: string[]) => Promise<Map<string, string | undefined>>;\n },\n ResolverError\n> {\n return tryInitializeClient(\"aws\", \"Failed to initialize AWS Secrets Manager client\", async () => {\n const sdk = await import(\"@aws-sdk/client-secrets-manager\");\n const sdkClient = new sdk.SecretsManagerClient(region ? { region } : {});\n\n return {\n getSecret: async (secretId: string) => {\n const response = await sdkClient.send(\n new sdk.GetSecretValueCommand({ SecretId: secretId }),\n );\n return response.SecretString ?? undefined;\n },\n getSecrets: async (secretIds: string[]) => {\n const result = new Map<string, string | undefined>();\n\n for (let i = 0; i < secretIds.length; i += 20) {\n const batch = secretIds.slice(i, i + 20);\n const response = await sdkClient.send(\n new sdk.BatchGetSecretValueCommand({ SecretIdList: batch }),\n );\n\n for (const secretValue of response.SecretValues ?? []) {\n if (secretValue.Name) {\n result.set(secretValue.Name, secretValue.SecretString ?? undefined);\n }\n }\n\n fillMissingMapValues(batch, result);\n }\n\n return result;\n },\n };\n });\n}\n\nexport function fromAwsSecrets<K extends string>(\n opts: AwsSecretsOptions<K>,\n): Effect.Effect<ResolverResult<K>, ResolverError>;\nexport function fromAwsSecrets(\n opts: AwsSecretsOptions,\n): Effect.Effect<ResolverResult, ResolverError> {\n return Effect.gen(function* () {\n const strict = opts.strict ?? false;\n const client = yield* createSdkClient(opts.region);\n\n // Group env keys by secret ID to minimize API calls.\n const secretIdToKeys = new Map<string, { envKey: string; jsonKey?: string }[]>();\n for (const [envKey, ref] of Object.entries(opts.secrets)) {\n const hashIndex = ref.indexOf(\"#\");\n const secretId = hashIndex >= 0 ? ref.slice(0, hashIndex) : ref;\n const jsonKey = hashIndex >= 0 ? ref.slice(hashIndex + 1) : undefined;\n\n const existing = secretIdToKeys.get(secretId) ?? [];\n existing.push({ envKey, jsonKey });\n secretIdToKeys.set(secretId, existing);\n }\n\n const uniqueSecretIds = [...secretIdToKeys.keys()];\n const secretValues = new Map<string, string | undefined>();\n\n if (uniqueSecretIds.length === 1) {\n const secretId = uniqueSecretIds[0]!;\n const value = yield* strictOrElse(\n Effect.tryPromise(() => client.getSecret(secretId)),\n {\n strict,\n resolver: \"aws\",\n message: `Failed to resolve secret \"${secretId}\"`,\n fallback: () => undefined,\n },\n );\n secretValues.set(secretId, value);\n } else {\n const batchResult = yield* strictOrElse(\n Effect.tryPromise(() => client.getSecrets(uniqueSecretIds)),\n {\n strict,\n resolver: \"aws\",\n message: \"Failed to resolve AWS secrets batch\",\n fallback: () => new Map<string, string | undefined>(),\n },\n );\n\n for (const [id, value] of batchResult) {\n secretValues.set(id, value);\n }\n fillMissingMapValues(uniqueSecretIds, secretValues);\n }\n\n const result: Record<string, string | undefined> = {};\n for (const [secretId, entries] of secretIdToKeys) {\n const rawValue = secretValues.get(secretId);\n for (const { envKey, jsonKey } of entries) {\n if (rawValue === undefined) {\n result[envKey] = undefined;\n continue;\n }\n\n if (!jsonKey) {\n result[envKey] = rawValue;\n continue;\n }\n\n try {\n const parsed = JSON.parse(rawValue) as Record<string, unknown>;\n result[envKey] = parsed[jsonKey] !== undefined ? String(parsed[jsonKey]) : undefined;\n } catch (cause) {\n if (strict) {\n return yield* toResolverError(\n \"aws\",\n `Failed to parse secret \"${secretId}\" as JSON while extracting key \"${jsonKey}\"`,\n cause,\n );\n }\n\n result[envKey] = undefined;\n }\n }\n }\n\n return result;\n });\n}\n",
|
|
6
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError } from \"./types.ts\";\n\nexport function toResolverError(resolver: string, message: string, cause?: unknown): ResolverError {\n return new ResolverError({ resolver, message, cause });\n}\n\nexport function tryInitializeClient<A>(\n resolver: string,\n message: string,\n initialize: () => Promise<A>,\n): Effect.Effect<A, ResolverError> {\n return Effect.tryPromise({\n try: initialize,\n catch: (cause) => toResolverError(resolver, message, cause),\n });\n}\n\nexport function strictOrElse<A>(\n effect: Effect.Effect<A, unknown>,\n options: {\n strict: boolean;\n resolver: string;\n message: string;\n fallback: () => A;\n },\n): Effect.Effect<A, ResolverError> {\n return options.strict\n ? effect.pipe(\n Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause)),\n )\n : effect.pipe(Effect.orElseSucceed(options.fallback));\n}\n\nexport function keyValueResultsToRecord<K extends string>(\n values: ReadonlyArray<{ envKey: K; value: string | undefined }>,\n): Record<K, string | undefined> {\n const result = {} as Record<K, string | undefined>;\n for (const { envKey, value } of values) {\n result[envKey] = value;\n }\n return result;\n}\n\nexport function fillMissingMapValues(\n ids: readonly string[],\n values: Map<string, string | undefined>,\n): void {\n for (const id of ids) {\n if (!values.has(id)) {\n values.set(id, undefined);\n }\n }\n}\n",
|
|
7
|
+
"import { Data } from \"effect\";\n\nexport type ResolverResult<K extends string = string> = Record<K, string | undefined>;\n\nexport class ResolverError extends Data.TaggedError(\"ResolverError\")<{\n readonly resolver: string;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\nexport interface SecretClient {\n getSecret: (secretId: string) => Promise<string | undefined>;\n getSecrets?: (secretIds: string[]) => Promise<Map<string, string | undefined>>;\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "CF166752E79C53F364756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResolverError, type ResolverResult } from "./types.ts";
|
|
3
|
+
export { ResolverError } from "./types.ts";
|
|
4
|
+
interface AzureKeyVaultOptions<K extends string = string> {
|
|
5
|
+
secrets: Record<K, string>;
|
|
6
|
+
vaultUrl: string;
|
|
7
|
+
credential?: unknown;
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function fromAzureKeyVault<K extends string>(opts: AzureKeyVaultOptions<K>): Effect.Effect<ResolverResult<K>, ResolverError>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/resolvers/azure.ts
|
|
10
|
+
import { Effect as Effect2 } from "effect";
|
|
11
|
+
|
|
12
|
+
// src/resolvers/utils.ts
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
|
|
15
|
+
// src/resolvers/types.ts
|
|
16
|
+
import { Data } from "effect";
|
|
17
|
+
|
|
18
|
+
class ResolverError extends Data.TaggedError("ResolverError") {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/resolvers/utils.ts
|
|
22
|
+
function toResolverError(resolver, message, cause) {
|
|
23
|
+
return new ResolverError({ resolver, message, cause });
|
|
24
|
+
}
|
|
25
|
+
function tryInitializeClient(resolver, message, initialize) {
|
|
26
|
+
return Effect.tryPromise({
|
|
27
|
+
try: initialize,
|
|
28
|
+
catch: (cause) => toResolverError(resolver, message, cause)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function strictOrElse(effect, options) {
|
|
32
|
+
return options.strict ? effect.pipe(Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause))) : effect.pipe(Effect.orElseSucceed(options.fallback));
|
|
33
|
+
}
|
|
34
|
+
function keyValueResultsToRecord(values) {
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const { envKey, value } of values) {
|
|
37
|
+
result[envKey] = value;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function fillMissingMapValues(ids, values) {
|
|
42
|
+
for (const id of ids) {
|
|
43
|
+
if (!values.has(id)) {
|
|
44
|
+
values.set(id, undefined);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/resolvers/azure.ts
|
|
50
|
+
function fromAzureKeyVault(opts) {
|
|
51
|
+
return Effect2.gen(function* () {
|
|
52
|
+
const { secrets, vaultUrl, strict = false } = opts;
|
|
53
|
+
if (!vaultUrl) {
|
|
54
|
+
return yield* toResolverError("azure", "vaultUrl must be provided");
|
|
55
|
+
}
|
|
56
|
+
const client = yield* tryInitializeClient("azure", "Failed to initialize Azure Key Vault client", async () => {
|
|
57
|
+
const kvModule = await import("@azure/keyvault-secrets");
|
|
58
|
+
const idModule = await import("@azure/identity");
|
|
59
|
+
const credential = opts.credential ?? new idModule.DefaultAzureCredential;
|
|
60
|
+
const sdkClient = new kvModule.SecretClient(vaultUrl, credential);
|
|
61
|
+
return {
|
|
62
|
+
getSecret: async (name) => {
|
|
63
|
+
const secret = await sdkClient.getSecret(name);
|
|
64
|
+
return secret.value;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const results = yield* Effect2.forEach(Object.entries(secrets), ([envKey, secretName]) => strictOrElse(Effect2.tryPromise(() => client.getSecret(secretName)), {
|
|
69
|
+
strict,
|
|
70
|
+
resolver: "azure",
|
|
71
|
+
message: `Failed to resolve secret "${secretName}" for env key "${envKey}"`,
|
|
72
|
+
fallback: () => {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}).pipe(Effect2.map((value) => ({ envKey, value }))), { concurrency: "unbounded" });
|
|
76
|
+
return keyValueResultsToRecord(results);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
fromAzureKeyVault,
|
|
81
|
+
ResolverError
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//# debugId=67F5DBBDDFA11C8264756E2164756E21
|
|
85
|
+
//# sourceMappingURL=azure.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/resolvers/azure.ts", "../src/resolvers/utils.ts", "../src/resolvers/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError, type ResolverResult } from \"./types.ts\";\nimport {\n keyValueResultsToRecord,\n strictOrElse,\n toResolverError,\n tryInitializeClient,\n} from \"./utils.ts\";\n\nexport { ResolverError } from \"./types.ts\";\n\ninterface AzureKeyVaultOptions<K extends string = string> {\n secrets: Record<K, string>;\n vaultUrl: string;\n credential?: unknown;\n strict?: boolean;\n}\n\nexport function fromAzureKeyVault<K extends string>(\n opts: AzureKeyVaultOptions<K>,\n): Effect.Effect<ResolverResult<K>, ResolverError>;\nexport function fromAzureKeyVault(\n opts: AzureKeyVaultOptions,\n): Effect.Effect<ResolverResult, ResolverError> {\n return Effect.gen(function* () {\n const { secrets, vaultUrl, strict = false } = opts;\n\n if (!vaultUrl) {\n return yield* toResolverError(\"azure\", \"vaultUrl must be provided\");\n }\n\n const client = yield* tryInitializeClient(\n \"azure\",\n \"Failed to initialize Azure Key Vault client\",\n async () => {\n const kvModule = await import(\"@azure/keyvault-secrets\");\n const idModule = await import(\"@azure/identity\");\n const credential = opts.credential ?? new idModule.DefaultAzureCredential();\n const sdkClient = new kvModule.SecretClient(vaultUrl, credential);\n\n return {\n getSecret: async (name: string) => {\n const secret = await sdkClient.getSecret(name);\n return secret.value;\n },\n };\n },\n );\n\n const results = yield* Effect.forEach(\n Object.entries(secrets),\n ([envKey, secretName]) =>\n strictOrElse(\n Effect.tryPromise(() => client.getSecret(secretName)),\n {\n strict,\n resolver: \"azure\",\n message: `Failed to resolve secret \"${secretName}\" for env key \"${envKey}\"`,\n fallback: () => undefined,\n },\n ).pipe(Effect.map((value) => ({ envKey, value }))),\n { concurrency: \"unbounded\" },\n );\n\n return keyValueResultsToRecord(results);\n });\n}\n",
|
|
6
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError } from \"./types.ts\";\n\nexport function toResolverError(resolver: string, message: string, cause?: unknown): ResolverError {\n return new ResolverError({ resolver, message, cause });\n}\n\nexport function tryInitializeClient<A>(\n resolver: string,\n message: string,\n initialize: () => Promise<A>,\n): Effect.Effect<A, ResolverError> {\n return Effect.tryPromise({\n try: initialize,\n catch: (cause) => toResolverError(resolver, message, cause),\n });\n}\n\nexport function strictOrElse<A>(\n effect: Effect.Effect<A, unknown>,\n options: {\n strict: boolean;\n resolver: string;\n message: string;\n fallback: () => A;\n },\n): Effect.Effect<A, ResolverError> {\n return options.strict\n ? effect.pipe(\n Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause)),\n )\n : effect.pipe(Effect.orElseSucceed(options.fallback));\n}\n\nexport function keyValueResultsToRecord<K extends string>(\n values: ReadonlyArray<{ envKey: K; value: string | undefined }>,\n): Record<K, string | undefined> {\n const result = {} as Record<K, string | undefined>;\n for (const { envKey, value } of values) {\n result[envKey] = value;\n }\n return result;\n}\n\nexport function fillMissingMapValues(\n ids: readonly string[],\n values: Map<string, string | undefined>,\n): void {\n for (const id of ids) {\n if (!values.has(id)) {\n values.set(id, undefined);\n }\n }\n}\n",
|
|
7
|
+
"import { Data } from \"effect\";\n\nexport type ResolverResult<K extends string = string> = Record<K, string | undefined>;\n\nexport class ResolverError extends Data.TaggedError(\"ResolverError\")<{\n readonly resolver: string;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\nexport interface SecretClient {\n getSecret: (secretId: string) => Promise<string | undefined>;\n getSecrets?: (secretIds: string[]) => Promise<Map<string, string | undefined>>;\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;;;;;;;;AAAA,mBAAS;;;ACAT;;;ACAA;AAAA;AAIO,MAAM,sBAAsB,KAAK,YAAY,eAAe,EAIhE;AAAC;;;ADJG,SAAS,eAAe,CAAC,UAAkB,SAAiB,OAAgC;AAAA,EACjG,OAAO,IAAI,cAAc,EAAE,UAAU,SAAS,MAAM,CAAC;AAAA;AAGhD,SAAS,mBAAsB,CACpC,UACA,SACA,YACiC;AAAA,EACjC,OAAO,OAAO,WAAW;AAAA,IACvB,KAAK;AAAA,IACL,OAAO,CAAC,UAAU,gBAAgB,UAAU,SAAS,KAAK;AAAA,EAC5D,CAAC;AAAA;AAGI,SAAS,YAAe,CAC7B,QACA,SAMiC;AAAA,EACjC,OAAO,QAAQ,SACX,OAAO,KACL,OAAO,SAAS,CAAC,UAAU,gBAAgB,QAAQ,UAAU,QAAQ,SAAS,KAAK,CAAC,CACtF,IACA,OAAO,KAAK,OAAO,cAAc,QAAQ,QAAQ,CAAC;AAAA;AAGjD,SAAS,uBAAyC,CACvD,QAC+B;AAAA,EAC/B,MAAM,SAAS,CAAC;AAAA,EAChB,aAAa,QAAQ,WAAW,QAAQ;AAAA,IACtC,OAAO,UAAU;AAAA,EACnB;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,oBAAoB,CAClC,KACA,QACM;AAAA,EACN,WAAW,MAAM,KAAK;AAAA,IACpB,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG;AAAA,MACnB,OAAO,IAAI,IAAI,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;;;AD/BK,SAAS,iBAAiB,CAC/B,MAC8C;AAAA,EAC9C,OAAO,QAAO,IAAI,UAAU,GAAG;AAAA,IAC7B,QAAQ,SAAS,UAAU,SAAS,UAAU;AAAA,IAE9C,IAAI,CAAC,UAAU;AAAA,MACb,OAAO,OAAO,gBAAgB,SAAS,2BAA2B;AAAA,IACpE;AAAA,IAEA,MAAM,SAAS,OAAO,oBACpB,SACA,+CACA,YAAY;AAAA,MACV,MAAM,WAAW,MAAa;AAAA,MAC9B,MAAM,WAAW,MAAa;AAAA,MAC9B,MAAM,aAAa,KAAK,cAAc,IAAI,SAAS;AAAA,MACnD,MAAM,YAAY,IAAI,SAAS,aAAa,UAAU,UAAU;AAAA,MAEhE,OAAO;AAAA,QACL,WAAW,OAAO,SAAiB;AAAA,UACjC,MAAM,SAAS,MAAM,UAAU,UAAU,IAAI;AAAA,UAC7C,OAAO,OAAO;AAAA;AAAA,MAElB;AAAA,KAEJ;AAAA,IAEA,MAAM,UAAU,OAAO,QAAO,QAC5B,OAAO,QAAQ,OAAO,GACtB,EAAE,QAAQ,gBACR,aACE,QAAO,WAAW,MAAM,OAAO,UAAU,UAAU,CAAC,GACpD;AAAA,MACE;AAAA,MACA,UAAU;AAAA,MACV,SAAS,6BAA6B,4BAA4B;AAAA,MAClE,UAAU,MAAG;AAAA,QAAG;AAAA;AAAA,IAClB,CACF,EAAE,KAAK,QAAO,IAAI,CAAC,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC,GACnD,EAAE,aAAa,YAAY,CAC7B;AAAA,IAEA,OAAO,wBAAwB,OAAO;AAAA,GACvC;AAAA;",
|
|
10
|
+
"debugId": "67F5DBBDDFA11C8264756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResolverError, type ResolverResult } from "./types.ts";
|
|
3
|
+
export { ResolverError } from "./types.ts";
|
|
4
|
+
interface GcpSecretsOptions<K extends string = string> {
|
|
5
|
+
secrets: Record<K, string>;
|
|
6
|
+
projectId?: string;
|
|
7
|
+
version?: string;
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function fromGcpSecrets<K extends string>(opts: GcpSecretsOptions<K>): Effect.Effect<ResolverResult<K>, ResolverError>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/resolvers/gcp.ts
|
|
10
|
+
import { Effect as Effect2 } from "effect";
|
|
11
|
+
|
|
12
|
+
// src/resolvers/utils.ts
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
|
|
15
|
+
// src/resolvers/types.ts
|
|
16
|
+
import { Data } from "effect";
|
|
17
|
+
|
|
18
|
+
class ResolverError extends Data.TaggedError("ResolverError") {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/resolvers/utils.ts
|
|
22
|
+
function toResolverError(resolver, message, cause) {
|
|
23
|
+
return new ResolverError({ resolver, message, cause });
|
|
24
|
+
}
|
|
25
|
+
function tryInitializeClient(resolver, message, initialize) {
|
|
26
|
+
return Effect.tryPromise({
|
|
27
|
+
try: initialize,
|
|
28
|
+
catch: (cause) => toResolverError(resolver, message, cause)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function strictOrElse(effect, options) {
|
|
32
|
+
return options.strict ? effect.pipe(Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause))) : effect.pipe(Effect.orElseSucceed(options.fallback));
|
|
33
|
+
}
|
|
34
|
+
function keyValueResultsToRecord(values) {
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const { envKey, value } of values) {
|
|
37
|
+
result[envKey] = value;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function fillMissingMapValues(ids, values) {
|
|
42
|
+
for (const id of ids) {
|
|
43
|
+
if (!values.has(id)) {
|
|
44
|
+
values.set(id, undefined);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/resolvers/gcp.ts
|
|
50
|
+
function fromGcpSecrets(opts) {
|
|
51
|
+
return Effect2.gen(function* () {
|
|
52
|
+
const { secrets, projectId, version = "latest", strict = false } = opts;
|
|
53
|
+
const usesShortSecretName = Object.values(secrets).some((secretName) => !secretName.startsWith("projects/"));
|
|
54
|
+
if (usesShortSecretName && !projectId) {
|
|
55
|
+
return yield* toResolverError("gcp", "projectId must be provided when using short secret names");
|
|
56
|
+
}
|
|
57
|
+
const client = yield* tryInitializeClient("gcp", "Failed to initialize GCP Secret Manager client", async () => {
|
|
58
|
+
const sdk = await import("@google-cloud/secret-manager");
|
|
59
|
+
const sdkClient = new sdk.SecretManagerServiceClient;
|
|
60
|
+
return {
|
|
61
|
+
getSecret: async (name) => {
|
|
62
|
+
const [response] = await sdkClient.accessSecretVersion({ name });
|
|
63
|
+
const data = response.payload?.data;
|
|
64
|
+
return data instanceof Uint8Array ? new TextDecoder().decode(data) : data ?? undefined;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const results = yield* Effect2.forEach(Object.entries(secrets), ([envKey, secretName]) => {
|
|
69
|
+
const name = secretName.startsWith("projects/") ? secretName : `projects/${projectId}/secrets/${secretName}/versions/${version}`;
|
|
70
|
+
return strictOrElse(Effect2.tryPromise(() => client.getSecret(name)), {
|
|
71
|
+
strict,
|
|
72
|
+
resolver: "gcp",
|
|
73
|
+
message: `Failed to resolve secret "${secretName}" for env key "${envKey}"`,
|
|
74
|
+
fallback: () => {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}).pipe(Effect2.map((value) => ({ envKey, value })));
|
|
78
|
+
}, { concurrency: "unbounded" });
|
|
79
|
+
return keyValueResultsToRecord(results);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
fromGcpSecrets,
|
|
84
|
+
ResolverError
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
//# debugId=801784A885D1CD3064756E2164756E21
|
|
88
|
+
//# sourceMappingURL=gcp.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/resolvers/gcp.ts", "../src/resolvers/utils.ts", "../src/resolvers/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError, type ResolverResult } from \"./types.ts\";\nimport {\n keyValueResultsToRecord,\n strictOrElse,\n toResolverError,\n tryInitializeClient,\n} from \"./utils.ts\";\n\nexport { ResolverError } from \"./types.ts\";\n\ninterface GcpSecretsOptions<K extends string = string> {\n secrets: Record<K, string>;\n projectId?: string;\n version?: string;\n strict?: boolean;\n}\n\nexport function fromGcpSecrets<K extends string>(\n opts: GcpSecretsOptions<K>,\n): Effect.Effect<ResolverResult<K>, ResolverError>;\nexport function fromGcpSecrets(\n opts: GcpSecretsOptions,\n): Effect.Effect<ResolverResult, ResolverError> {\n return Effect.gen(function* () {\n const { secrets, projectId, version = \"latest\", strict = false } = opts;\n const usesShortSecretName = Object.values(secrets).some(\n (secretName) => !secretName.startsWith(\"projects/\"),\n );\n\n if (usesShortSecretName && !projectId) {\n return yield* toResolverError(\n \"gcp\",\n \"projectId must be provided when using short secret names\",\n );\n }\n\n const client = yield* tryInitializeClient(\n \"gcp\",\n \"Failed to initialize GCP Secret Manager client\",\n async () => {\n const sdk = await import(\"@google-cloud/secret-manager\");\n const sdkClient = new sdk.SecretManagerServiceClient();\n return {\n getSecret: async (name: string) => {\n const [response] = await sdkClient.accessSecretVersion({ name });\n const data = response.payload?.data;\n return data instanceof Uint8Array\n ? new TextDecoder().decode(data)\n : (data ?? undefined);\n },\n };\n },\n );\n\n const results = yield* Effect.forEach(\n Object.entries(secrets),\n ([envKey, secretName]) => {\n const name = secretName.startsWith(\"projects/\")\n ? secretName\n : `projects/${projectId}/secrets/${secretName}/versions/${version}`;\n\n return strictOrElse(\n Effect.tryPromise(() => client.getSecret(name)),\n {\n strict,\n resolver: \"gcp\",\n message: `Failed to resolve secret \"${secretName}\" for env key \"${envKey}\"`,\n fallback: () => undefined,\n },\n ).pipe(Effect.map((value) => ({ envKey, value })));\n },\n { concurrency: \"unbounded\" },\n );\n\n return keyValueResultsToRecord(results);\n });\n}\n",
|
|
6
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError } from \"./types.ts\";\n\nexport function toResolverError(resolver: string, message: string, cause?: unknown): ResolverError {\n return new ResolverError({ resolver, message, cause });\n}\n\nexport function tryInitializeClient<A>(\n resolver: string,\n message: string,\n initialize: () => Promise<A>,\n): Effect.Effect<A, ResolverError> {\n return Effect.tryPromise({\n try: initialize,\n catch: (cause) => toResolverError(resolver, message, cause),\n });\n}\n\nexport function strictOrElse<A>(\n effect: Effect.Effect<A, unknown>,\n options: {\n strict: boolean;\n resolver: string;\n message: string;\n fallback: () => A;\n },\n): Effect.Effect<A, ResolverError> {\n return options.strict\n ? effect.pipe(\n Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause)),\n )\n : effect.pipe(Effect.orElseSucceed(options.fallback));\n}\n\nexport function keyValueResultsToRecord<K extends string>(\n values: ReadonlyArray<{ envKey: K; value: string | undefined }>,\n): Record<K, string | undefined> {\n const result = {} as Record<K, string | undefined>;\n for (const { envKey, value } of values) {\n result[envKey] = value;\n }\n return result;\n}\n\nexport function fillMissingMapValues(\n ids: readonly string[],\n values: Map<string, string | undefined>,\n): void {\n for (const id of ids) {\n if (!values.has(id)) {\n values.set(id, undefined);\n }\n }\n}\n",
|
|
7
|
+
"import { Data } from \"effect\";\n\nexport type ResolverResult<K extends string = string> = Record<K, string | undefined>;\n\nexport class ResolverError extends Data.TaggedError(\"ResolverError\")<{\n readonly resolver: string;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\nexport interface SecretClient {\n getSecret: (secretId: string) => Promise<string | undefined>;\n getSecrets?: (secretIds: string[]) => Promise<Map<string, string | undefined>>;\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;;;;;;;;AAAA,mBAAS;;;ACAT;;;ACAA;AAAA;AAIO,MAAM,sBAAsB,KAAK,YAAY,eAAe,EAIhE;AAAC;;;ADJG,SAAS,eAAe,CAAC,UAAkB,SAAiB,OAAgC;AAAA,EACjG,OAAO,IAAI,cAAc,EAAE,UAAU,SAAS,MAAM,CAAC;AAAA;AAGhD,SAAS,mBAAsB,CACpC,UACA,SACA,YACiC;AAAA,EACjC,OAAO,OAAO,WAAW;AAAA,IACvB,KAAK;AAAA,IACL,OAAO,CAAC,UAAU,gBAAgB,UAAU,SAAS,KAAK;AAAA,EAC5D,CAAC;AAAA;AAGI,SAAS,YAAe,CAC7B,QACA,SAMiC;AAAA,EACjC,OAAO,QAAQ,SACX,OAAO,KACL,OAAO,SAAS,CAAC,UAAU,gBAAgB,QAAQ,UAAU,QAAQ,SAAS,KAAK,CAAC,CACtF,IACA,OAAO,KAAK,OAAO,cAAc,QAAQ,QAAQ,CAAC;AAAA;AAGjD,SAAS,uBAAyC,CACvD,QAC+B;AAAA,EAC/B,MAAM,SAAS,CAAC;AAAA,EAChB,aAAa,QAAQ,WAAW,QAAQ;AAAA,IACtC,OAAO,UAAU;AAAA,EACnB;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,oBAAoB,CAClC,KACA,QACM;AAAA,EACN,WAAW,MAAM,KAAK;AAAA,IACpB,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG;AAAA,MACnB,OAAO,IAAI,IAAI,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;;;AD/BK,SAAS,cAAc,CAC5B,MAC8C;AAAA,EAC9C,OAAO,QAAO,IAAI,UAAU,GAAG;AAAA,IAC7B,QAAQ,SAAS,WAAW,UAAU,UAAU,SAAS,UAAU;AAAA,IACnE,MAAM,sBAAsB,OAAO,OAAO,OAAO,EAAE,KACjD,CAAC,eAAe,CAAC,WAAW,WAAW,WAAW,CACpD;AAAA,IAEA,IAAI,uBAAuB,CAAC,WAAW;AAAA,MACrC,OAAO,OAAO,gBACZ,OACA,0DACF;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,OAAO,oBACpB,OACA,kDACA,YAAY;AAAA,MACV,MAAM,MAAM,MAAa;AAAA,MACzB,MAAM,YAAY,IAAI,IAAI;AAAA,MAC1B,OAAO;AAAA,QACL,WAAW,OAAO,SAAiB;AAAA,UACjC,OAAO,YAAY,MAAM,UAAU,oBAAoB,EAAE,KAAK,CAAC;AAAA,UAC/D,MAAM,OAAO,SAAS,SAAS;AAAA,UAC/B,OAAO,gBAAgB,aACnB,IAAI,YAAY,EAAE,OAAO,IAAI,IAC5B,QAAQ;AAAA;AAAA,MAEjB;AAAA,KAEJ;AAAA,IAEA,MAAM,UAAU,OAAO,QAAO,QAC5B,OAAO,QAAQ,OAAO,GACtB,EAAE,QAAQ,gBAAgB;AAAA,MACxB,MAAM,OAAO,WAAW,WAAW,WAAW,IAC1C,aACA,YAAY,qBAAqB,uBAAuB;AAAA,MAE5D,OAAO,aACL,QAAO,WAAW,MAAM,OAAO,UAAU,IAAI,CAAC,GAC9C;AAAA,QACE;AAAA,QACA,UAAU;AAAA,QACV,SAAS,6BAA6B,4BAA4B;AAAA,QAClE,UAAU,MAAG;AAAA,UAAG;AAAA;AAAA,MAClB,CACF,EAAE,KAAK,QAAO,IAAI,CAAC,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,OAEnD,EAAE,aAAa,YAAY,CAC7B;AAAA,IAEA,OAAO,wBAAwB,OAAO;AAAA,GACvC;AAAA;",
|
|
10
|
+
"debugId": "801784A885D1CD3064756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResolverError, type ResolverResult } from "./types.ts";
|
|
3
|
+
export { ResolverError } from "./types.ts";
|
|
4
|
+
interface OnePasswordOptions<K extends string = string> {
|
|
5
|
+
secrets: Record<K, string>;
|
|
6
|
+
serviceAccountToken?: string;
|
|
7
|
+
strict?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function fromOnePassword<K extends string>(opts: OnePasswordOptions<K>): Effect.Effect<ResolverResult<K>, ResolverError>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/resolvers/onepassword.ts
|
|
10
|
+
import { Effect as Effect2 } from "effect";
|
|
11
|
+
|
|
12
|
+
// src/resolvers/utils.ts
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
|
|
15
|
+
// src/resolvers/types.ts
|
|
16
|
+
import { Data } from "effect";
|
|
17
|
+
|
|
18
|
+
class ResolverError extends Data.TaggedError("ResolverError") {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/resolvers/utils.ts
|
|
22
|
+
function toResolverError(resolver, message, cause) {
|
|
23
|
+
return new ResolverError({ resolver, message, cause });
|
|
24
|
+
}
|
|
25
|
+
function tryInitializeClient(resolver, message, initialize) {
|
|
26
|
+
return Effect.tryPromise({
|
|
27
|
+
try: initialize,
|
|
28
|
+
catch: (cause) => toResolverError(resolver, message, cause)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function strictOrElse(effect, options) {
|
|
32
|
+
return options.strict ? effect.pipe(Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause))) : effect.pipe(Effect.orElseSucceed(options.fallback));
|
|
33
|
+
}
|
|
34
|
+
function keyValueResultsToRecord(values) {
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const { envKey, value } of values) {
|
|
37
|
+
result[envKey] = value;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function fillMissingMapValues(ids, values) {
|
|
42
|
+
for (const id of ids) {
|
|
43
|
+
if (!values.has(id)) {
|
|
44
|
+
values.set(id, undefined);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/resolvers/onepassword.ts
|
|
50
|
+
function fromOnePassword(opts) {
|
|
51
|
+
return Effect2.gen(function* () {
|
|
52
|
+
const { secrets, strict = false } = opts;
|
|
53
|
+
const token = opts.serviceAccountToken ?? process.env.OP_SERVICE_ACCOUNT_TOKEN;
|
|
54
|
+
if (!token) {
|
|
55
|
+
return yield* toResolverError("1password", "serviceAccountToken (or OP_SERVICE_ACCOUNT_TOKEN env var) must be provided");
|
|
56
|
+
}
|
|
57
|
+
const client = yield* tryInitializeClient("1password", "Failed to initialize 1Password client", async () => {
|
|
58
|
+
const sdk = await import("@1password/sdk");
|
|
59
|
+
const sdkClient = await sdk.createClient({
|
|
60
|
+
auth: token,
|
|
61
|
+
integrationName: "envil",
|
|
62
|
+
integrationVersion: "1.0.0"
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
resolveAll: async (refs2) => sdkClient.secrets.resolveAll(refs2)
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const entries = Object.entries(secrets);
|
|
69
|
+
const refs = entries.map(([, ref]) => ref);
|
|
70
|
+
const resolved = yield* strictOrElse(Effect2.tryPromise(() => client.resolveAll(refs)).pipe(Effect2.map((values) => values)), {
|
|
71
|
+
strict,
|
|
72
|
+
resolver: "1password",
|
|
73
|
+
message: "Failed to resolve 1Password secrets",
|
|
74
|
+
fallback: () => null
|
|
75
|
+
});
|
|
76
|
+
if (!resolved) {
|
|
77
|
+
return keyValueResultsToRecord(entries.map(([envKey]) => ({ envKey, value: undefined })));
|
|
78
|
+
}
|
|
79
|
+
return keyValueResultsToRecord(entries.map(([envKey], index) => ({
|
|
80
|
+
envKey,
|
|
81
|
+
value: resolved[index]
|
|
82
|
+
})));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
fromOnePassword,
|
|
87
|
+
ResolverError
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
//# debugId=52E64B21781AEF3864756E2164756E21
|
|
91
|
+
//# sourceMappingURL=onepassword.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/resolvers/onepassword.ts", "../src/resolvers/utils.ts", "../src/resolvers/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError, type ResolverResult } from \"./types.ts\";\nimport {\n keyValueResultsToRecord,\n strictOrElse,\n toResolverError,\n tryInitializeClient,\n} from \"./utils.ts\";\n\nexport { ResolverError } from \"./types.ts\";\n\ninterface OnePasswordOptions<K extends string = string> {\n secrets: Record<K, string>;\n serviceAccountToken?: string;\n strict?: boolean;\n}\n\nexport function fromOnePassword<K extends string>(\n opts: OnePasswordOptions<K>,\n): Effect.Effect<ResolverResult<K>, ResolverError>;\nexport function fromOnePassword(\n opts: OnePasswordOptions,\n): Effect.Effect<ResolverResult, ResolverError> {\n return Effect.gen(function* () {\n const { secrets, strict = false } = opts;\n\n const token = opts.serviceAccountToken ?? process.env.OP_SERVICE_ACCOUNT_TOKEN;\n if (!token) {\n return yield* toResolverError(\n \"1password\",\n \"serviceAccountToken (or OP_SERVICE_ACCOUNT_TOKEN env var) must be provided\",\n );\n }\n\n const client = yield* tryInitializeClient(\n \"1password\",\n \"Failed to initialize 1Password client\",\n async () => {\n const sdk = await import(\"@1password/sdk\");\n const sdkClient = await sdk.createClient({\n auth: token,\n integrationName: \"envil\",\n integrationVersion: \"1.0.0\",\n });\n\n return {\n resolveAll: async (refs: string[]) => sdkClient.secrets.resolveAll(refs),\n };\n },\n );\n\n const entries = Object.entries(secrets);\n const refs = entries.map(([, ref]) => ref);\n\n const resolved = yield* strictOrElse(\n Effect.tryPromise(() => client.resolveAll(refs)).pipe(\n Effect.map((values) => values as string[] | null),\n ),\n {\n strict,\n resolver: \"1password\",\n message: \"Failed to resolve 1Password secrets\",\n fallback: () => null,\n },\n );\n\n if (!resolved) {\n return keyValueResultsToRecord(entries.map(([envKey]) => ({ envKey, value: undefined })));\n }\n\n return keyValueResultsToRecord(\n entries.map(([envKey], index) => ({\n envKey,\n value: resolved[index],\n })),\n );\n });\n}\n",
|
|
6
|
+
"import { Effect } from \"effect\";\n\nimport { ResolverError } from \"./types.ts\";\n\nexport function toResolverError(resolver: string, message: string, cause?: unknown): ResolverError {\n return new ResolverError({ resolver, message, cause });\n}\n\nexport function tryInitializeClient<A>(\n resolver: string,\n message: string,\n initialize: () => Promise<A>,\n): Effect.Effect<A, ResolverError> {\n return Effect.tryPromise({\n try: initialize,\n catch: (cause) => toResolverError(resolver, message, cause),\n });\n}\n\nexport function strictOrElse<A>(\n effect: Effect.Effect<A, unknown>,\n options: {\n strict: boolean;\n resolver: string;\n message: string;\n fallback: () => A;\n },\n): Effect.Effect<A, ResolverError> {\n return options.strict\n ? effect.pipe(\n Effect.mapError((cause) => toResolverError(options.resolver, options.message, cause)),\n )\n : effect.pipe(Effect.orElseSucceed(options.fallback));\n}\n\nexport function keyValueResultsToRecord<K extends string>(\n values: ReadonlyArray<{ envKey: K; value: string | undefined }>,\n): Record<K, string | undefined> {\n const result = {} as Record<K, string | undefined>;\n for (const { envKey, value } of values) {\n result[envKey] = value;\n }\n return result;\n}\n\nexport function fillMissingMapValues(\n ids: readonly string[],\n values: Map<string, string | undefined>,\n): void {\n for (const id of ids) {\n if (!values.has(id)) {\n values.set(id, undefined);\n }\n }\n}\n",
|
|
7
|
+
"import { Data } from \"effect\";\n\nexport type ResolverResult<K extends string = string> = Record<K, string | undefined>;\n\nexport class ResolverError extends Data.TaggedError(\"ResolverError\")<{\n readonly resolver: string;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\nexport interface SecretClient {\n getSecret: (secretId: string) => Promise<string | undefined>;\n getSecrets?: (secretIds: string[]) => Promise<Map<string, string | undefined>>;\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;;;;;;;;AAAA,mBAAS;;;ACAT;;;ACAA;AAAA;AAIO,MAAM,sBAAsB,KAAK,YAAY,eAAe,EAIhE;AAAC;;;ADJG,SAAS,eAAe,CAAC,UAAkB,SAAiB,OAAgC;AAAA,EACjG,OAAO,IAAI,cAAc,EAAE,UAAU,SAAS,MAAM,CAAC;AAAA;AAGhD,SAAS,mBAAsB,CACpC,UACA,SACA,YACiC;AAAA,EACjC,OAAO,OAAO,WAAW;AAAA,IACvB,KAAK;AAAA,IACL,OAAO,CAAC,UAAU,gBAAgB,UAAU,SAAS,KAAK;AAAA,EAC5D,CAAC;AAAA;AAGI,SAAS,YAAe,CAC7B,QACA,SAMiC;AAAA,EACjC,OAAO,QAAQ,SACX,OAAO,KACL,OAAO,SAAS,CAAC,UAAU,gBAAgB,QAAQ,UAAU,QAAQ,SAAS,KAAK,CAAC,CACtF,IACA,OAAO,KAAK,OAAO,cAAc,QAAQ,QAAQ,CAAC;AAAA;AAGjD,SAAS,uBAAyC,CACvD,QAC+B;AAAA,EAC/B,MAAM,SAAS,CAAC;AAAA,EAChB,aAAa,QAAQ,WAAW,QAAQ;AAAA,IACtC,OAAO,UAAU;AAAA,EACnB;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,oBAAoB,CAClC,KACA,QACM;AAAA,EACN,WAAW,MAAM,KAAK;AAAA,IACpB,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG;AAAA,MACnB,OAAO,IAAI,IAAI,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;;;ADhCK,SAAS,eAAe,CAC7B,MAC8C;AAAA,EAC9C,OAAO,QAAO,IAAI,UAAU,GAAG;AAAA,IAC7B,QAAQ,SAAS,SAAS,UAAU;AAAA,IAEpC,MAAM,QAAQ,KAAK,uBAAuB,QAAQ,IAAI;AAAA,IACtD,IAAI,CAAC,OAAO;AAAA,MACV,OAAO,OAAO,gBACZ,aACA,4EACF;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,OAAO,oBACpB,aACA,yCACA,YAAY;AAAA,MACV,MAAM,MAAM,MAAa;AAAA,MACzB,MAAM,YAAY,MAAM,IAAI,aAAa;AAAA,QACvC,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,oBAAoB;AAAA,MACtB,CAAC;AAAA,MAED,OAAO;AAAA,QACL,YAAY,OAAO,UAAmB,UAAU,QAAQ,WAAW,KAAI;AAAA,MACzE;AAAA,KAEJ;AAAA,IAEA,MAAM,UAAU,OAAO,QAAQ,OAAO;AAAA,IACtC,MAAM,OAAO,QAAQ,IAAI,IAAI,SAAS,GAAG;AAAA,IAEzC,MAAM,WAAW,OAAO,aACtB,QAAO,WAAW,MAAM,OAAO,WAAW,IAAI,CAAC,EAAE,KAC/C,QAAO,IAAI,CAAC,WAAW,MAAyB,CAClD,GACA;AAAA,MACE;AAAA,MACA,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU,MAAM;AAAA,IAClB,CACF;AAAA,IAEA,IAAI,CAAC,UAAU;AAAA,MACb,OAAO,wBAAwB,QAAQ,IAAI,EAAE,aAAa,EAAE,QAAQ,OAAO,UAAU,EAAE,CAAC;AAAA,IAC1F;AAAA,IAEA,OAAO,wBACL,QAAQ,IAAI,EAAE,SAAS,WAAW;AAAA,MAChC;AAAA,MACA,OAAO,SAAS;AAAA,IAClB,EAAE,CACJ;AAAA,GACD;AAAA;",
|
|
10
|
+
"debugId": "52E64B21781AEF3864756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResolverError, type ResolverResult, type SecretClient } from "./types.ts";
|
|
3
|
+
export { ResolverError } from "./types.ts";
|
|
4
|
+
interface RemoteSecretsOptions<K extends string = string> {
|
|
5
|
+
secrets: Record<K, string>;
|
|
6
|
+
client: SecretClient;
|
|
7
|
+
strict?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function fromRemoteSecrets<K extends string>(opts: RemoteSecretsOptions<K>): Effect.Effect<ResolverResult<K>, ResolverError>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type ResolverResult<K extends string = string> = Record<K, string | undefined>;
|
|
2
|
+
declare const ResolverError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
3
|
+
readonly _tag: "ResolverError";
|
|
4
|
+
} & Readonly<A>;
|
|
5
|
+
export declare class ResolverError extends ResolverError_base<{
|
|
6
|
+
readonly resolver: string;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly cause?: unknown;
|
|
9
|
+
}> {
|
|
10
|
+
}
|
|
11
|
+
export interface SecretClient {
|
|
12
|
+
getSecret: (secretId: string) => Promise<string | undefined>;
|
|
13
|
+
getSecrets?: (secretIds: string[]) => Promise<Map<string, string | undefined>>;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResolverError } from "./types.ts";
|
|
3
|
+
export declare function toResolverError(resolver: string, message: string, cause?: unknown): ResolverError;
|
|
4
|
+
export declare function tryInitializeClient<A>(resolver: string, message: string, initialize: () => Promise<A>): Effect.Effect<A, ResolverError>;
|
|
5
|
+
export declare function strictOrElse<A>(effect: Effect.Effect<A, unknown>, options: {
|
|
6
|
+
strict: boolean;
|
|
7
|
+
resolver: string;
|
|
8
|
+
message: string;
|
|
9
|
+
fallback: () => A;
|
|
10
|
+
}): Effect.Effect<A, ResolverError>;
|
|
11
|
+
export declare function keyValueResultsToRecord<K extends string>(values: ReadonlyArray<{
|
|
12
|
+
envKey: K;
|
|
13
|
+
value: string | undefined;
|
|
14
|
+
}>): Record<K, string | undefined>;
|
|
15
|
+
export declare function fillMissingMapValues(ids: readonly string[], values: Map<string, string | undefined>): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { EnvValidationError } from "./errors.ts";
|
|
3
|
+
import type { ResolverError, ResolverResult } from "./resolvers/types.ts";
|
|
4
|
+
import type { AnyEnv, EnvOptions, EnvResult, EnvResultAutoRedacted, ExtractResolverKeys, PrefixMap, PrefixStr, SchemaDict } from "./types.ts";
|
|
5
|
+
export type SafeCreateEnvSuccess<T> = Readonly<{
|
|
6
|
+
success: true;
|
|
7
|
+
data: T;
|
|
8
|
+
}>;
|
|
9
|
+
export type SafeCreateEnvFailure<E> = Readonly<{
|
|
10
|
+
success: false;
|
|
11
|
+
error: E;
|
|
12
|
+
}>;
|
|
13
|
+
export type SafeCreateEnvResult<T, E> = SafeCreateEnvSuccess<T> | SafeCreateEnvFailure<E>;
|
|
14
|
+
export declare function safeCreateEnv<TServer extends SchemaDict = {}, TClient extends SchemaDict = {}, TShared extends SchemaDict = {}, const TExtends extends readonly AnyEnv[] = readonly [], const TResolvers extends readonly Effect.Effect<ResolverResult<any>, ResolverError>[] = readonly []>(opts: EnvOptions<TServer, TClient, TShared, TExtends> & {
|
|
15
|
+
resolvers: TResolvers;
|
|
16
|
+
autoRedactResolver: false;
|
|
17
|
+
}): Effect.Effect<SafeCreateEnvResult<EnvResult<TExtends, TServer, TClient, TShared>, ResolverError | EnvValidationError>, never>;
|
|
18
|
+
export declare function safeCreateEnv<TServer extends SchemaDict = {}, TClient extends SchemaDict = {}, TShared extends SchemaDict = {}, const TExtends extends readonly AnyEnv[] = readonly [], const TResolvers extends readonly Effect.Effect<ResolverResult<any>, ResolverError>[] = readonly [], const TPrefix extends string | PrefixMap | undefined = undefined>(opts: EnvOptions<TServer, TClient, TShared, TExtends> & {
|
|
19
|
+
resolvers: TResolvers;
|
|
20
|
+
autoRedactResolver?: true;
|
|
21
|
+
prefix?: TPrefix;
|
|
22
|
+
}): Effect.Effect<SafeCreateEnvResult<EnvResultAutoRedacted<TExtends, TServer, TClient, TShared, ExtractResolverKeys<TResolvers>, PrefixStr<TPrefix>>, ResolverError | EnvValidationError>, never>;
|
|
23
|
+
export declare function safeCreateEnv<TServer extends SchemaDict = {}, TClient extends SchemaDict = {}, TShared extends SchemaDict = {}, const TExtends extends readonly AnyEnv[] = readonly []>(opts: EnvOptions<TServer, TClient, TShared, TExtends>): SafeCreateEnvResult<EnvResult<TExtends, TServer, TClient, TShared>, EnvValidationError>;
|