Skip to content

test — env config

Env

Functions

loadEnvFile

function loadEnvFile(envFilePath: string): Record<string, string>
TypeScript

Use loadEnvFile to parse a .env file into a plain key-value object your code can immediately read from.

Reach for this when skrypt generate needs API keys or provider credentials at runtime — for example, passing your OpenAI key and output preferences without hardcoding them into your generation script.

It reads the file at the given path, parses each KEY=VALUE line, and returns the result as a Record<string, string>. If the file doesn't exist, it throws immediately rather than returning an empty object, so misconfigured paths fail loudly.

Parameters

NameTypeRequiredDescription
envFilePathstringYesAbsolute or relative path to your .env file. Throws if the file doesn't exist at this path — double-check the path is correct relative to your working directory.

Returns

A Record<string, string> where each key maps to its value from the .env file. Pass the result directly into your generation config — for example, env["OPENAI_API_KEY"] to set your AI provider credential.

Heads up

  • The function throws Error: Env file not found: <path> if the file is missing. Wrap in a try/catch if the .env file is optional in your workflow.
  • Values are returned as raw strings — booleans like true and numbers like 3000 won't be coerced; cast them yourself before use.

Example:

import { readFileSync, existsSync } from 'fs'
import { join } from 'path'
import { writeFileSync, unlinkSync } from 'fs'

// Inline implementation — do not import from autodocs
function loadEnvFile(envFilePath: string): Record<string, string> {
  if (!existsSync(envFilePath)) {
    throw new Error(`Env file not found: ${envFilePath}`)
  }

  const content = readFileSync(envFilePath, 'utf-8')
  const result: Record<string, string> = {}

  for (const line of content.split('\n')) {
    const trimmed = line.trim()
    if (!trimmed || trimmed.startsWith('#')) continue
    const eqIndex = trimmed.indexOf('=')
    if (eqIndex === -1) continue
    const key = trimmed.slice(0, eqIndex).trim()
    const value = trimmed.slice(eqIndex + 1).trim().replace(/^["']|["']$/g, '')
    result[key] = value
  }

  return result
}

// Create a temporary .env file to simulate a real project setup
const envPath = join(process.cwd(), '.env.skrypt-example')
writeFileSync(envPath, `
# skrypt configuration
OPENAI_API_KEY=sk-proj-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
OUTPUT_DIR=./content/docs
PROVIDER=openai
MULTI_LANG=true
`.trim())

try {
  const env = loadEnvFile(envPath)

  console.log('Loaded config:')
  console.log('  Provider:', env['PROVIDER'])           // openai
  console.log('  Output:', env['OUTPUT_DIR'])           // ./content/docs
  console.log('  Multi-lang:', env['MULTI_LANG'])       // true (string — cast if needed)
  console.log('  API key set:', !!env['OPENAI_API_KEY']) // true
} catch (err) {
  console.error('Failed to load env file:', err)
} finally {
  unlinkSync(envPath)
}
TypeScript

buildCleanEnv

function buildCleanEnv(injectedVars: Record<string, string>): Record<string, string>
TypeScript

Use buildCleanEnv to create a sanitized execution environment for running generated code snippets — without leaking secrets, tokens, or other sensitive variables from the host process.

When skrypt executes the code examples it generates, it needs to run them in isolation. Passing the full process.env would expose API keys, database URLs, and other credentials from your shell into the snippet subprocess. Call this before spawning any child process that runs untrusted or generated code.

It starts from a minimal baseline (NODE_NO_WARNINGS, PATH, HOME) and merges only the variables you explicitly provide. Nothing from process.env bleeds through unless you pass it in injectedVars.

Parameters

NameTypeRequiredDescription
injectedVarsRecord<string, string>YesVariables to expose to the snippet process — only these, plus PATH and HOME, will be available. Pass API keys or config values the snippet legitimately needs to run.

Returns

A flat Record<string, string> safe to pass directly as the env option to Node's child_process.spawn or exec. The returned object is a new value — mutating it won't affect process.env.

Heads up

  • PATH and HOME are always included so runtimes (node, python, go) can be resolved. If your snippet needs a specific binary, make sure it's on the inherited PATH.
  • If you need to inject a value from process.env, pull it out explicitly — don't spread the whole object, or you defeat the purpose.

Example:

// Inline implementation matching the real behavior
function buildCleanEnv(injectedVars: Record<string, string>): Record<string, string> {
  const clean: Record<string, string> = {
    NODE_NO_WARNINGS: "1",
    PATH: process.env.PATH ?? "",
    HOME: process.env.HOME ?? "",
  };
  return { ...clean, ...injectedVars };
}

// Simulate running a generated snippet that needs an API key
const { execSync } = require("child_process");

const snippetEnv = buildCleanEnv({
  OPENAI_API_KEY: "sk-proj-abc123xyz789",
  SKRYPT_TIMEOUT: "5000",
});

console.log("Environment passed to snippet process:");
console.log(JSON.stringify(snippetEnv, null, 2));

// Use it when spawning the snippet subprocess
try {
  const output = execSync("node -e \"console.log('API key present:', !!process.env.OPENAI_API_KEY)\"", {
    env: snippetEnv,
    timeout: 5000,
    encoding: "utf8",
  });
  console.log("\nSnippet output:", output.trim());
  // => Snippet output: API key present: true
} catch (err) {
  console.error("Snippet execution failed:", err);
}
TypeScript

checkRequiredEnv

function checkRequiredEnv(required: string[], available: Record<string, string>): { ok: boolean; missing: string[] }
TypeScript

Use checkRequiredEnv to validate that all required environment variables are present before your documentation generation run starts.

Call this at startup — before invoking skrypt generate programmatically — to catch missing config early and surface exactly which variables are absent, rather than letting the process fail mid-run with a cryptic error.

Filters required against available and returns both a pass/fail boolean and the specific keys that are missing, so you can either halt with a useful error message or prompt the user to set them.

NameTypeRequiredDescription
requiredstring[]YesThe environment variable names your process cannot run without — any key absent from available will appear in missing.
availableRecord<string, string>YesThe environment to check against — typically process.env cast to Record<string, string>, or a parsed .env object.

Returns { ok: boolean; missing: string[] }. If ok is true, missing is an empty array and you're safe to proceed. If ok is false, missing contains every key that needs to be set — log or throw these before continuing.

Heads up:

  • A key set to an empty string ("") is treated as missing. Only truthy values pass the check.

Example:

function checkRequiredEnv(
  required: string[],
  available: Record<string, string>
): { ok: boolean; missing: string[] } {
  const missing = required.filter((key) => !available[key]);
  return { ok: missing.length === 0, missing };
}

const env: Record<string, string> = {
  OPENAI_API_KEY: "sk-proj-abc123xyz",
  GITHUB_TOKEN: "",         // empty — will be flagged as missing
  OUTPUT_DIR: "./docs",
  // ANTHROPIC_API_KEY is absent entirely
};

const requiredVars = ["OPENAI_API_KEY", "GITHUB_TOKEN", "ANTHROPIC_API_KEY", "OUTPUT_DIR"];

const result = checkRequiredEnv(requiredVars, env);

if (!result.ok) {
  console.error("Cannot start: missing required environment variables:");
  result.missing.forEach((key) => console.error(`  - ${key}`));
  process.exit(1);
}

console.log("All required environment variables are set. Proceeding with generation.");

// Expected output:
// Cannot start: missing required environment variables:
//   - GITHUB_TOKEN
//   - ANTHROPIC_API_KEY
TypeScript
Was this helpful?