Created
September 19, 2025 09:02
-
-
Save Ribeiro-Tiago/efa60a36cac64e19ace18d86b29f59c7 to your computer and use it in GitHub Desktop.
ensure env vars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env tsx | |
| import {readdirSync, readFileSync} from 'fs' | |
| import {join, resolve} from 'path' | |
| import {config} from 'dotenv' | |
| config({quiet: true}) | |
| const WHITELISTED = [ | |
| // injected by aws | |
| '_X_AMZN_TRACE_ID', | |
| // these are basically vars for local / dev shtuff | |
| 'APPCONFIG_LOCAL', | |
| 'NODE_ENV', | |
| ] | |
| // Recursively collect .js/.ts/.jsx/.tsx files asynchronously | |
| async function getAllFiles(dir: string): Promise<string[]> { | |
| const entries = readdirSync(dir, {withFileTypes: true}) | |
| const files: string[] = [] | |
| await Promise.all( | |
| entries.map(async (entry) => { | |
| const fullPath = join(dir, entry.name) | |
| if (entry.isDirectory()) { | |
| const subFiles = await getAllFiles(fullPath) | |
| files.push(...subFiles) | |
| } else if (/\.ts$/.test(entry.name)) { | |
| files.push(fullPath) | |
| } | |
| }), | |
| ) | |
| return files | |
| } | |
| async function findEnvVariablesInFiles(files: string[]): Promise<string[]> { | |
| const envVarRegex = /process\.env\.([a-zA-Z_][a-zA-Z0-9_]*)/g | |
| const allMatches = await Promise.all( | |
| files.map((file) => { | |
| const content = readFileSync(file, 'utf8') | |
| const matches = new Set<string>() | |
| let match | |
| while ((match = envVarRegex.exec(content)) !== null) { | |
| matches.add(match[1]!) | |
| } | |
| return Array.from(matches) | |
| }), | |
| ) | |
| return Array.from(new Set(allMatches.flat())) | |
| } | |
| function getEnvVars(): string[] { | |
| return Object.keys(process.env) | |
| } | |
| ;(async function main() { | |
| const targetDirs = ['src/functions', 'src/shared'] | |
| // Collect files from all directories in parallel | |
| const allFiles = (await Promise.all(targetDirs.map((dir) => getAllFiles(resolve(dir))))).flat() | |
| const allEnvVars = getEnvVars() | |
| const missingVars = (await findEnvVariablesInFiles(allFiles)).filter( | |
| (name) => !WHITELISTED.includes(name) && !allEnvVars.includes(name), | |
| ) | |
| if (missingVars.length > 0) { | |
| process.stderr.write(`❌ Missing environment variables: ${missingVars.join('; ')}\n`) | |
| process.exit(1) | |
| } | |
| process.stderr.write('✅ All environment variables are set.\n') | |
| process.exit(0) | |
| })() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment