dagger-env
Version:
A type-safe, reusable environment configuration abstraction for Dagger modules.
159 lines • 6.31 kB
JavaScript
import { dag } from '@dagger.io/dagger';
import { z } from 'zod/v4';
/**
* Reusable Dagger environment abstraction
*/
export class DaggerEnv {
config;
optionsSchema;
constructor(config) {
this.config = config;
this.optionsSchema = z.object({
args: config.args,
env: config.env,
secrets: config.secrets,
});
}
/**
* Parse dagger options from a Secret
*/
async parseDaggerOptions(options) {
return this.optionsSchema.parse(JSON.parse(await options.plaintext()));
}
/**
* Create a function that applies environment variables and secrets to a container
* based on the provided Dagger options, secret presets, and additional secret names.
*/
async getWithEnv(daggerOptions, secretPresets, secretNames) {
const isSecret = (obj) => obj &&
typeof obj === 'object' &&
'id' in obj &&
'plaintext' in obj &&
typeof obj.id === 'function' &&
typeof obj.plaintext === 'function';
const opts = isSecret(daggerOptions)
? await this.parseDaggerOptions(daggerOptions)
: daggerOptions;
return {
withEnv: (con) => {
let c = con;
// Add individual secret names
for (const name of secretNames ?? []) {
if (typeof name === 'string' && name in opts.secrets) {
const secret = opts.secrets[name];
if (!secret) {
throw new Error(`Secret ${name} is undefined`);
}
c = c.withSecretVariable(name, dag.setSecret(name, secret));
}
}
const allSecretNames = [...(secretNames ?? [])];
// Add secret presets
for (const preset of secretPresets) {
const presetSecrets = this.config.secretPresets[preset];
if (!presetSecrets) {
throw new Error(`Unknown secret preset: ${String(preset)}`);
}
for (const secretName of presetSecrets) {
const secret = opts.secrets[secretName];
if (!secret) {
throw new Error(`Secret ${secretName} is undefined`);
}
allSecretNames.push(secretName);
c = c.withSecretVariable(secretName, dag.setSecret(secretName, secret));
}
}
// Add derived env vars based on secretNames
for (const name of allSecretNames) {
const derivedEnvVars = this.config.derivedEnvVars[name];
if (derivedEnvVars) {
for (const [key, value] of Object.entries(derivedEnvVars)) {
c = c.withEnvVariable(key, value);
}
}
}
// Add environment variables from options
const envVars = opts.env;
for (const [key, value] of Object.entries(envVars)) {
if (value !== undefined && typeof value === 'string') {
c = c.withEnvVariable(key, value);
}
}
return c;
},
withoutEnv: (con) => {
let c = con;
// Add individual secret names
for (const name of secretNames ?? []) {
if (typeof name === 'string' && name in opts.secrets) {
const secret = opts.secrets[name];
if (!secret) {
throw new Error(`Secret ${name} is undefined`);
}
c = c.withoutSecretVariable(name);
}
}
const allSecretNames = [...(secretNames ?? [])];
// remove secret presets
for (const preset of secretPresets) {
const presetSecrets = this.config.secretPresets[preset];
if (!presetSecrets) {
throw new Error(`Unknown secret preset: ${String(preset)}`);
}
for (const secretName of presetSecrets) {
const secret = opts.secrets[secretName];
if (!secret) {
throw new Error(`Secret ${secretName} is undefined`);
}
allSecretNames.push(secretName);
c = c.withoutSecretVariable(secretName);
}
}
// remove derived env vars based on secretNames
for (const name of allSecretNames) {
const derivedEnvVars = this.config.derivedEnvVars[name];
if (derivedEnvVars) {
for (const key of Object.keys(derivedEnvVars)) {
c = c.withoutEnvVariable(key);
}
}
}
// remove environment variables from options
const envVars = opts.env;
for (const key of Object.keys(envVars)) {
c = c.withoutEnvVariable(key);
}
return c;
},
};
}
/**
* Get the options schema for this DaggerEnv instance
*/
getOptionsSchema() {
return this.optionsSchema;
}
/**
* Get available secret presets
*/
getSecretPresets() {
return Object.keys(this.config.secretPresets);
}
/**
* Get secrets for a specific preset
*/
getPresetSecrets(preset) {
const secrets = this.config.secretPresets[preset];
if (!secrets) {
throw new Error(`Unknown secret preset: ${String(preset)}`);
}
return secrets;
}
}
/**
* Helper function to create a DaggerEnv instance with proper typing
*/
export function createDaggerEnv(config) {
return new DaggerEnv(config);
}
//# sourceMappingURL=dagger-env.js.map