Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-environment

Environment files for Pudu: load .env variables safely with layered files, discovery, expansion, typed reads, and secrets kept out of every message

0.1.0Apache-2.01

InstallClose

Cascade.pudu

Pudu41 lines1.4 KB

GitHub ↗
1/** @Domain.Cascade.Module — environment names and their layered files */2module PuduLangEnvironment.Domain.Cascade34import Std.Char as Char5import PuduLangEnvironment.Constants.Names as Names67/// The explicit name when it is not blank, else the first naming variable that is set and not8/// blank, trimmed.9export fn chooseName(explicit: &Option[Str], process: &Map[Str, Str]) -> Option[Str] {10  if let Some(named) = explicit {11    if !named.trim().isEmpty() { return Some(named.trim()) }12  }13  for variable in Names.ENVIRONMENT_NAME_VARIABLES {14    if let Some(held) = process.get(variable) {15      if !held.trim().isEmpty() { return Some(held.trim()) }16    }17  }18  None19}2021/// Whether a name can extend `.env` without leaving its directory: not blank, no `..`, and no22/// character a file name cannot hold on some platform.23export fn isSafe(name: Str) -> Bool {24  if name.trim().isEmpty() || name.contains(Names.PARENT_STEP) { return false }25  for symbol in name {26    if Names.UNSAFE_NAME_CHARACTERS.contains(symbol) || Char.isControl(symbol) { return false }27  }28  true29}3031/// The cascade's file names in reading order: `.env`, `.env.local`, and with a name,32/// `.env.<name>` and `.env.<name>.local`.33export fn candidates(name: &Option[Str]) -> Array[Str] {34  let base = Names.DEFAULT_FILE35  let shared = [base, base + Names.LOCAL_SUFFIX]36  match name {37    case Some(named) => shared.concat([base + "." + named, base + "." + named + Names.LOCAL_SUFFIX])38    case None => shared39  }40}41