fix(dotenv): show warning when there is invalid key in .env file (#5745)

This commit is contained in:
Yoshiya Hinosawa 2024-08-21 14:56:34 +09:00 committed by GitHub
parent 210402c6d2
commit ce40f0bae1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 1 deletions

View File

@ -4,6 +4,8 @@
* Parses and loads environment variables from a `.env` file into the current
* process, or stringify data into a `.env` file format.
*
* Note: The key needs to match the pattern /^[a-zA-Z_][a-zA-Z0-9_]*$/.
*
* ```ts no-eval
* // Automatically load environment variables from a `.env` file
* import "@std/dotenv/load";
@ -84,6 +86,8 @@ export function loadSync(
* Inspired by the node modules {@linkcode https://github.com/motdotla/dotenv | dotenv}
* and {@linkcode https://github.com/motdotla/dotenv-expand | dotenv-expand}.
*
* Note: The key needs to match the pattern /^[a-zA-Z_][a-zA-Z0-9_]*$/.
*
* ## Basic usage
* ```sh
* # .env

View File

@ -10,7 +10,9 @@ type LineParseResult = {
type CharactersMap = { [key: string]: string };
const RE_KEY_VALUE =
/^\s*(?:export\s+)?(?<key>[a-zA-Z_]+[a-zA-Z0-9_]*?)\s*=[\ \t]*('\n?(?<notInterpolated>(.|\n)*?)\n?'|"\n?(?<interpolated>(.|\n)*?)\n?"|(?<unquoted>[^\n#]*)) *#*.*$/gm;
/^\s*(?:export\s+)?(?<key>[^\s=#]+?)\s*=[\ \t]*('\n?(?<notInterpolated>(.|\n)*?)\n?'|"\n?(?<interpolated>(.|\n)*?)\n?"|(?<unquoted>[^\n#]*)) *#*.*$/gm;
const RE_VALID_KEY = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
const RE_EXPAND_VALUE =
/(\${(?<inBrackets>.+?)(\:-(?<inBracketsDefault>.+))?}|(?<!\\)\$(?<notInBrackets>\w+)(\:-(?<notInBracketsDefault>.+))?)/g;
@ -57,6 +59,8 @@ function expand(str: string, variablesMap: { [key: string]: string }): string {
/**
* Parse `.env` file output in an object.
*
* Note: The key needs to match the pattern /^[a-zA-Z_][a-zA-Z0-9_]*$/.
*
* @example Usage
* ```ts
* import { parse } from "@std/dotenv/parse";
@ -79,6 +83,13 @@ export function parse(text: string): Record<string, string> {
const { key, interpolated, notInterpolated, unquoted } = match
?.groups as LineParseResult;
if (!RE_VALID_KEY.test(key)) {
console.warn(
`Ignored the key "${key}" as it is not a valid identifier: The key need to match the pattern /^[a-zA-Z_][a-zA-Z0-9_]*$/.`,
);
continue;
}
if (unquoted) {
keysForExpandCheck.push(key);
}

View File

@ -3,11 +3,14 @@
import { assertEquals } from "@std/assert";
import { parse } from "./parse.ts";
import * as path from "@std/path";
import { assertSpyCall, spy } from "@std/testing/mock";
const moduleDir = path.dirname(path.fromFileUrl(import.meta.url));
const testdataDir = path.resolve(moduleDir, "testdata");
Deno.test("parse()", () => {
using consoleWarnSpy = spy(console, "warn");
const testDotenv = Deno.readTextFileSync(
path.join(testdataDir, "./.env.test"),
);
@ -140,6 +143,12 @@ Deno.test("parse()", () => {
"export is ignored",
"export at the start of the key is ignored",
);
assertSpyCall(consoleWarnSpy, 0, {
args: [
'Ignored the key "1INVALID" as it is not a valid identifier: The key need to match the pattern /^[a-zA-Z_][a-zA-Z0-9_]*$/.',
],
});
});
Deno.test("parse() ignores comments", () => {