loqatevars
Version:
Locate JavaScript files with 'const' or 'process.env' usage in LLM-generated codebases
1,522 lines (1,152 loc) • 142 kB
text/xml
This file is a merged representation of the entire codebase, combined into a single document by Repomix.
<file_summary>
This section contains a summary of this file.
<purpose>
This file contains a packed representation of the entire repository's contents.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
</purpose>
<file_format>
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
- File path as an attribute
- Full contents of the file
</file_format>
<usage_guidelines>
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
</usage_guidelines>
<notes>
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Files are sorted by Git change count (files with more changes are at the bottom)
</notes>
</file_summary>
<directory_structure>
.github/
workflows/
nodejs.yml
.local/
state/
replit/
agent/
.latest.json
.upm/
store.json
attached_assets/
Pasted--directory-test-git-main-hexdump-C-scopeTest-js-00000000-2f-2f-20-54-65-73-74-20-66-69-6c-65--1753168145351_1753168145352.txt
Pasted--workspace-npm-test-loqatevars-1-0-4-test-node-experimental-vm-modules-node-modules-jest-bi-1753165878508_1753165878509.txt
config/
localVars.js
summary.md
directory_test/
AGENTS.md
badConst.js
badEnvOnly.js
badScope.js
functionCaller.js
functionDefault.js
ifStatement.js
importModule.js
letVariable.js
localVars.js
mockEnv.js
requireImport.js
scopeTest.js
summary.md
useLocalVars.js
ignoreDirTest/
public/
file.js
index.js
lib/
errors.js
logger.js
summary.md
utils.js
test_dir/
indirect-env.js
test_samples/
app.js
config.js
constants.js
database.js
localVars.js
server.js
summary.md
tests/
__mocks__/
globby.js
asyncPool.cleanup.test.js
asyncPool.test.js
cli.default.test.js
cli.helpCommand.test.js
cli.invalidCommand.test.js
cli.multipleOptions.test.js
cli.run.test.js
cli.test.js
errors.test.js
findMatchingFiles.invalid.test.js
findMatchingFiles.single.test.js
findMatchingFilesDetailed.test.js
function-scope.test.js
glob-patterns.test.js
index.test.js
indirect-env.test.js
integration.test.js
localVars.test.js
searchFiles.defaultStreamFallback.test.js
searchFiles.invalid-extension.test.js
searchFiles.invalidExtensionType.test.js
searchFiles.test.js
utils.test.js
validateDirectory.invalid.test.js
validateDirectory.success.test.js
validateDirectory.test.js
.gitignore
.replit
AGENTS.md
ARCHITECTURE.md
cli.js
DB_SCHEMA.md
DEPENDENCY_GRAPH.md
index.js
MODULES.md
package.json
README.md
replit.md
WORKFLOWS.md
</directory_structure>
<files>
This section contains the contents of the repository's files.
<file path=".local/state/replit/agent/.latest.json">
{"latest": "main"}
</file>
<file path=".upm/store.json">
{"version":2,"languages":{"nodejs-npm":{"specfileHash":"0a520387f417e4526881cc107797bbf2","lockfileHash":"b4695602750c8a916ef78523524eb39d"}}}
</file>
<file path="config/summary.md">
# Config Directory
This directory contains configuration files for the `loqatevars` application.
* **[`localVars.js`](localVars.js)**: This is the central place for defining and exporting configuration variables. It includes a list of directories to be ignored during scans (`ignoreDirs`) and handles loading environment variables using `dotenv`. Centralizing configuration here makes the application easier to manage and maintain.
</file>
<file path="directory_test/functionCaller.js">
// File 7: imports function and invokes it with different string literal
const { greetUser } = require('./functionDefault');
console.log(greetUser("custom user"));
</file>
<file path="directory_test/functionDefault.js">
// File 6: function declaration with string literal as default parameter
function greetUser(name = "default user") {
return `Hello, ${name}!`;
}
module.exports = { greetUser };
</file>
<file path="directory_test/ifStatement.js">
// File 8: if statement with string literal in conditional
if (production === "development") {
console.log("This will never execute");
} else {
console.log("Running in production mode");
}
</file>
<file path="directory_test/importModule.js">
// File 10: imports node module using import
import fs from 'fs';
import path from 'path';
console.log('File system module loaded with import');
</file>
<file path="directory_test/letVariable.js">
// File 4: let declaration for "let variable"
let letVariable = "let variable";
console.log(letVariable);
</file>
<file path="directory_test/localVars.js">
// File 2: mock localVars.js with const variable and imported MOCK_ENV
const { MOCK_ENV } = require('./mockEnv');
const testValue = "test value";
const mockEnv = MOCK_ENV;
module.exports = {
testValue,
mockEnv
};
</file>
<file path="directory_test/mockEnv.js">
// File 1: mockEnv file with let declaration for process.env.MOCK_ENV
const localVars = require('../config/localVars');
let MOCK_ENV = localVars.MOCK_ENV;
MOCK_ENV = "test env";
module.exports = { MOCK_ENV };
</file>
<file path="directory_test/requireImport.js">
// File 9: imports node module using require
const fs = require('fs');
const path = require('path');
console.log('File system module loaded');
</file>
<file path="directory_test/scopeTest.js">
// Test file for top-level scope detection
const localVars = require('../config/localVars');
function myFunction() {
const insideFunction = "should NOT be flagged";
if (true) {
const insideBlock = "should NOT be flagged";
}
}
class MyClass {
constructor() {
const insideClass = "should NOT be flagged";
}
}
if (true) {
const insideIfBlock = "should NOT be flagged";
}
</file>
<file path="directory_test/useLocalVars.js">
// File 11: imports exports of mock localVars and uses them
const { testValue, mockEnv } = require('./localVars');
console.log('Test value:', testValue);
console.log('Mock environment:', mockEnv);
// Use the imported values in some logic
if (mockEnv === "test env") {
console.log('Environment is correctly set to test');
}
</file>
<file path="ignoreDirTest/public/file.js">
// ignored file
</file>
<file path="ignoreDirTest/index.js">
// root file
</file>
<file path="lib/summary.md">
# Lib Directory
This directory contains the core logic for the `loqatevars` application.
* **[`utils.js`](utils.js)**: This file contains all the main functions for scanning and analyzing the codebase. It is responsible for finding files, parsing them using `acorn` to create an Abstract Syntax Tree (AST), and then analyzing the AST to find `const` declarations and `process.env` usage.
* **[`errors.js`](errors.js)**: This file defines a custom error class for the application.
</file>
<file path="test_samples/app.js">
const express = require('express');
const app = express();
const { Router } = require('express');
</file>
<file path="test_samples/config.js">
const localVars = require('../config/localVars');
var config = {
apiKey: localVars.API_KEY,
env: localVars.NODE_ENV
};
</file>
<file path="test_samples/constants.js">
const localVars = require('../config/localVars');
</file>
<file path="test_samples/database.js">
const localVars = require('../config/localVars');
const database = require('./db');
</file>
<file path="test_samples/localVars.js">
const localConfig = {
secret: process.env.SECRET_KEY
};
</file>
<file path="test_samples/server.js">
const localVars = require('../config/localVars');
const config = {
port: localVars.PORT,
database: localVars.DATABASE_URL
};
const server = require('express')();
console.log('Server starting...');
</file>
<file path="test_samples/summary.md">
# Test Samples Directory
This directory contains a set of sample JavaScript files that are likely used for more comprehensive testing of the `loqatevars` tool. The file names suggest they represent different components of a sample application:
* `app.js`
* `config.js`
* `constants.js`
* `database.js`
* `localVars.js`
* `server.js`
These files probably provide more realistic and complex test cases than the ones in the `directory_test` folder, allowing for testing the tool against a simulated project structure.
</file>
<file path="tests/errors.test.js">
const { AppError } = require('../lib/errors');
const path = require('path');
describe('AppError', () => {
test('stores message and code', () => {
const err = new AppError('fail', 'FAIL_CODE');
expect(err.message).toBe('fail');
expect(err.code).toBe('FAIL_CODE');
});
test('captures stack information', () => {
const err = new AppError('fail', 'FAIL');
expect(err.stack).toBeDefined();
expect(err.stack.startsWith('AppError:')).toBe(true);
expect(err.stack).toContain('AppError');
expect(err.stack).toContain(path.basename(__filename));
});
});
</file>
<file path="tests/findMatchingFiles.invalid.test.js">
// Mock globby to avoid ESM loading issues
jest.mock('globby');
const { findMatchingFiles } = require('../lib/utils');
describe('findMatchingFiles invalid directory', () => {
test('rejects for non-existent directory', async () => {
await expect(findMatchingFiles('./nonexistent')).rejects.toMatchObject({ code: 'DIRECTORY_NOT_FOUND' });
});
});
</file>
<file path="tests/index.test.js">
// Mock globby to avoid ESM issues in utils
jest.mock('globby');
const lib = require('../index');
describe('index exports', () => {
test('re-exports findMatchingFiles', () => {
expect(typeof lib.findMatchingFiles).toBe('function');
});
test('re-exports findMatchingFilesDetailed', () => {
expect(typeof lib.findMatchingFilesDetailed).toBe('function');
});
});
</file>
<file path="tests/validateDirectory.invalid.test.js">
// Mock globby to avoid ESM loading issues
jest.mock('globby');
const { validateDirectory } = require('../lib/utils');
describe('validateDirectory invalid parameter', () => {
test('rejects for non-string directory argument', async () => {
await expect(validateDirectory(123)).rejects.toHaveProperty('code', 'INVALID_DIRECTORY');
});
});
</file>
<file path="tests/validateDirectory.success.test.js">
// No fs-extra mocking, use actual fs-extra
const { validateDirectory } = require('../lib/utils');
const fs = require('fs-extra');
const path = require('path');
const os = require('os');
describe('validateDirectory success path', () => {
let tempDir;
beforeAll(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'valid-dir-')); // create temp directory for test
});
afterAll(() => {
fs.removeSync(tempDir); // cleanup temporary directory after tests
});
test('resolves for existing directory', async () => {
await expect(validateDirectory(tempDir)).resolves.toBeUndefined(); // should resolve with undefined for valid directory
});
});
</file>
<file path=".gitignore">
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Coverage directory used by tools like istanbul
coverage/
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage
.grunt
# Bower dependency directory
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons
build/Release
# Dependency directories
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache
.cache
.parcel-cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# MacOS
.DS_Store
# Windows
Thumbs.db
ehthumbs.db
# Editor directories and files
.vscode/
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
</file>
<file path=".replit">
modules = ["nodejs-20"]
[nix]
channel = "stable-24_05"
[workflows]
runButton = "Project"
[[workflows.workflow]]
name = "Project"
mode = "parallel"
author = "agent"
[[workflows.workflow.tasks]]
task = "workflow.run"
args = "Test Module"
[[workflows.workflow]]
name = "Test Module"
author = "agent"
[[workflows.workflow.tasks]]
task = "shell.exec"
args = "npm test"
[deployment]
run = ["sh", "-c", "npm test"]
</file>
<file path="AGENTS.md">
# AGENTS.md
## VISION
This project, `loqatevars`, enforces an architectural pattern where environment variables and constants are centralized. The core business logic is to prevent the proliferation of scattered `process.env` calls and `const` declarations in large, especially AI-generated, codebases. This tool was created to automate the detection of non-compliance with this pattern, as manual auditing is error-prone and time-consuming. The intended end-state for a codebase analyzed by this tool is to have a single, clearly-defined configuration file (e.g., `config.js` or `localVars.js`) from which all other modules import their configuration.
## FUNCTIONALITY
No undocumented items.
## SCOPE
**In-Scope:**
* Identifying `.js` files containing `const` or `process.env`.
* Providing command-line and programmatic interfaces for file scanning.
* Ignoring specified files and directories to narrow the search.
**Out-of-Scope:**
* Automatically refactoring or modifying the identified files. The tool is for detection only.
* Analyzing file types other than JavaScript by default (though configurable).
* Supporting languages other than JavaScript.
## CONSTRAINTS
* All tests reside in the `tests/` directory and are executed via Jest.
* The `directory_test/` and `test_samples/` directories contain files specifically designed for testing various scenarios. Do not add, remove, or modify files in these directories unless you are intentionally changing the test cases.
## POLICY
No undocumented items.
</file>
<file path="ARCHITECTURE.md">
# Architecture
This project, `loqatevars`, is a Node.js command-line tool designed to analyze JavaScript codebases. Its primary function is to identify files that contain `const` variable declarations and `process.env` usage.
The architecture is composed of three main layers:
1. **Command-Line Interface (CLI)**: The entry point for user interaction is [`cli.js`](cli.js). It is responsible for parsing command-line arguments, handling user commands (`scan`, `detailed`, `help`), and displaying the final output to the console.
2. **Core Logic Library**: The core functionality resides in the `lib/` directory, specifically within [`lib/utils.js`](lib/utils.js). This module contains the functions responsible for:
* Traversing the file system to find relevant files.
* Reading file contents.
* Parsing JavaScript code into an Abstract Syntax Tree (AST) using the `acorn` library.
* Analyzing the AST to detect `const` declarations (while intelligently ignoring those used for `require` statements) and `process.env` access.
3. **Module Entry Point**: The [`index.js`](index.js) file serves as the main entry point for the `npm` package. It exposes the core scanning functions (`findMatchingFiles` and `findMatchingFilesDetailed`) for programmatic use in other projects.
## Data Flow
The typical data flow is as follows:
1. A user executes a command via the `loqatevars` CLI.
2. [`cli.js`](cli.js) parses the arguments and invokes the corresponding function from [`lib/utils.js`](lib/utils.js).
3. The function in [`lib/utils.js`](lib/utils.js) scans the target directory, reads files, and analyzes their content.
4. The results are returned to [`cli.js`](cli.js), which then formats and prints the output to the user.
Configuration, such as directories to ignore, is managed in [`config/localVars.js`](config/localVars.js).
</file>
<file path="DB_SCHEMA.md">
# Database Schema
This project, `loqatevars`, does not utilize a database. It is a command-line tool that operates directly on the file system to analyze JavaScript source code. All data is processed in memory during the execution of the tool, and no persistent data storage is required.
</file>
<file path="index.js">
/**
* @file Main entry point for the loqatevars npm module.
* @description This file serves as the public interface for the `loqatevars` package.
* It exports the core scanning functions, making them available for programmatic
* use in other Node.js projects.
*/
const {
findMatchingFiles,
findMatchingFilesDetailed
} = require('./lib/utils.js');
module.exports = {
findMatchingFiles,
findMatchingFilesDetailed
};
</file>
<file path="MODULES.md">
# Modules
This document provides a summary of the key modules in the `loqatevars` project.
* **[`index.js`](index.js)**
* **Purpose**: The main entry point for the `npm` package.
* **Functionality**: It exports the core functions `findMatchingFiles` and `findMatchingFilesDetailed` from [`lib/utils.js`](lib/utils.js), making them available for other Node.js projects to use programmatically.
* **[`cli.js`](cli.js)**
* **Purpose**: The command-line interface for the application.
* **Functionality**: This module handles parsing of command-line arguments, executes the appropriate scanning functions based on user commands (`scan`, `detailed`), and displays the results in a user-friendly format in the console. It also provides a `help` command.
* **[`lib/utils.js`](lib/utils.js)**
* **Purpose**: The core logic of the application.
* **Functionality**: This is where the main work of finding and analyzing files happens.
* `searchFiles`: Uses `globby` to find all relevant files in a directory, respecting ignore patterns.
* `analyzeConstUsage`: Uses `acorn` to perform Abstract Syntax Tree (AST) analysis on file content to identify `const` declarations (excluding `require` statements) and `process.env` usage.
* `findMatchingFiles` and `findMatchingFilesDetailed`: These functions orchestrate the file search and analysis, returning a simple or detailed list of matching files.
* **[`config/localVars.js`](config/localVars.js)**
* **Purpose**: Centralized configuration for the application.
* **Functionality**: This file defines and exports configuration variables, such as `ignoreDirs` (a list of directories to exclude from scans) and any environment variables used in the project. This makes it easy to manage and modify configuration without changing the core logic.
* **[`lib/errors.js`](lib/errors.js)**
* **Purpose**: Defines a custom error class for the application.
* **Functionality**: This file contains the `AppError` class, which is used to create custom errors with unique codes. This is useful for handling specific error cases in the application.
</file>
<file path=".github/workflows/nodejs.yml">
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- uses: actions/upload-artifact@v3
with:
name: coverage
path: coverage
if-no-files-found: ignore
</file>
<file path="attached_assets/Pasted--directory-test-git-main-hexdump-C-scopeTest-js-00000000-2f-2f-20-54-65-73-74-20-66-69-6c-65--1753168145351_1753168145352.txt">
➜ directory_test git:(main) hexdump -C scopeTest.js
00000000 2f 2f 20 54 65 73 74 20 66 69 6c 65 20 66 6f 72 |// Test file for|
00000010 20 74 6f 70 2d 6c 65 76 65 6c 20 73 63 6f 70 65 | top-level scope|
00000020 20 64 65 74 65 63 74 69 6f 6e 0a 63 6f 6e 73 74 | detection.const|
00000030 20 6c 6f 63 61 6c 56 61 72 73 20 3d 20 72 65 71 | localVars = req|
00000040 75 69 72 65 28 27 2e 2e 2f 63 6f 6e 66 69 67 2f |uire('../config/|
00000050 6c 6f 63 61 6c 56 61 72 73 27 29 3b 0a 0a 66 75 |localVars');..fu|
00000060 6e 63 74 69 6f 6e 20 6d 79 46 75 6e 63 74 69 6f |nction myFunctio|
00000070 6e 28 29 20 7b 0a 20 20 63 6f 6e 73 74 20 69 6e |n() {. const in|
00000080 73 69 64 65 46 75 6e 63 74 69 6f 6e 20 3d 20 22 |sideFunction = "|
00000090 73 68 6f 75 6c 64 20 4e 4f 54 20 62 65 20 66 6c |should NOT be fl|
000000a0 61 67 67 65 64 22 3b 0a 20 20 69 66 20 28 74 72 |agged";. if (tr|
000000b0 75 65 29 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 |ue) {. const |
000000c0 69 6e 73 69 64 65 42 6c 6f 63 6b 20 3d 20 22 73 |insideBlock = "s|
000000d0 68 6f 75 6c 64 20 4e 4f 54 20 62 65 20 66 6c 61 |hould NOT be fla|
000000e0 67 67 65 64 22 3b 0a 20 20 7d 0a 7d 0a 0a 63 6c |gged";. }.}..cl|
000000f0 61 73 73 20 4d 79 43 6c 61 73 73 20 7b 0a 20 20 |ass MyClass {. |
00000100 63 6f 6e 73 74 72 75 63 74 6f 72 28 29 20 7b 0a |constructor() {.|
00000110 20 20 20 20 63 6f 6e 73 74 20 69 6e 73 69 64 65 | const inside|
00000120 43 6c 61 73 73 20 3d 20 22 73 68 6f 75 6c 64 20 |Class = "should |
00000130 4e 4f 54 20 62 65 20 66 6c 61 67 67 65 64 22 3b |NOT be flagged";|
00000140 0a 20 20 7d 0a 7d 0a 0a 69 66 20 28 74 72 75 65 |. }.}..if (true|
00000150 29 20 7b 0a 20 20 63 6f 6e 73 74 20 69 6e 73 69 |) {. const insi|
00000160 64 65 49 66 42 6c 6f 63 6b 20 3d 20 22 73 68 6f |deIfBlock = "sho|
00000170 75 6c 64 20 4e 4f 54 20 62 65 20 66 6c 61 67 67 |uld NOT be flagg|
00000180 65 64 22 3b 0a 7d |ed";.}|
00000186
➜ directory_test git:(main) loqatevars --debug
badConst.js badEnvOnly.js mockEnv.js scopeTest.js
Found 4 files
➜ directory_test git:(main) which loqatevars
npm list -g loqatevars
/Users/q/.nvm/versions/node/v22.17.0/bin/loqatevars
/Users/q/.nvm/versions/node/v22.17.0/lib
└── loqatevars@1.0.4
➜ directory_test git:(main) loqatevars detailed
=== loqatevars Analysis ===
Directory: /Users/q/code/loqatevars/directory_test
Total JS files: 13
Scanned files: 12
Matching files: 4
Ignored files: localVars.js
Files containing const or process.env:
badConst.js ()
badEnvOnly.js (process.env)
mockEnv.js (process.env)
scopeTest.js ()
Concatenated result:
badConst.js badEnvOnly.js mockEnv.js scopeTest.js
➜ directory_test git:(main)
</file>
<file path="attached_assets/Pasted--workspace-npm-test-loqatevars-1-0-4-test-node-experimental-vm-modules-node-modules-jest-bi-1753165878508_1753165878509.txt">
~/workspace$ npm test
> loqatevars@1.0.4 test
> node --experimental-vm-modules node_modules/jest/bin/jest.js tests
PASS tests/integration.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🛠️ run anywhere with `dotenvx run -- yourcommand`)
at _log (node_modules/dotenv/lib/main.js:136:11)
(node:686) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS tests/cli.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/utils.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ override existing env vars with { override: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
(node:693) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS tests/glob-patterns.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🛠️ run anywhere with `dotenvx run -- yourcommand`)
at _log (node_modules/dotenv/lib/main.js:136:11)
(node:687) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS tests/indirect-env.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent building .env in docker: https://dotenvx.com/prebuild)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/findMatchingFilesDetailed.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/cli.default.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/cli.multipleOptions.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.defaultStreamFallback.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/localVars.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/cli.invalidCommand.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ load multiple .env files with { path: ['.env.local', '.env'] })
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/asyncPool.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent building .env in docker: https://dotenvx.com/prebuild)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/cli.run.test.js
PASS tests/cli.helpCommand.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.invalid-extension.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/findMatchingFiles.single.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.invalidExtensionType.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.success.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ override existing env vars with { override: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/errors.test.js
PASS tests/asyncPool.cleanup.test.js
PASS tests/function-scope.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/index.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/findMatchingFiles.invalid.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ load multiple .env files with { path: ['.env.local', '.env'] })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.invalid.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
Test Suites: 26 passed, 26 total
Tests: 64 passed, 64 total
Snapshots: 0 total
Time: 3.486 s
Ran all test suites matching /tests/i.
~/workspace$ npm i
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
added 55 packages, removed 16 packages, changed 64 packages, and audited 329 packages in 3s
55 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
~/workspace$ npm test
> loqatevars@1.0.4 test
> node --experimental-vm-modules node_modules/jest/bin/jest.js tests
FAIL tests/integration.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/integration.test.js:11:18)
FAIL tests/cli.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.test.js:1:18)
(node:865) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS tests/utils.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🛠️ run anywhere with `dotenvx run -- yourcommand`)
at _log (node_modules/dotenv/lib/main.js:136:11)
(node:866) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS tests/glob-patterns.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/cli.run.test.js
FAIL tests/cli.invalidCommand.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.invalidCommand.test.js:1:18)
PASS tests/findMatchingFilesDetailed.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.defaultStreamFallback.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
FAIL tests/cli.multipleOptions.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.multipleOptions.test.js:1:18)
FAIL tests/cli.default.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.default.test.js:7:18)
PASS tests/searchFiles.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/asyncPool.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/indirect-env.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 encrypt with dotenvx: https://dotenvx.com)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/findMatchingFiles.single.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ enable debug logging with { debug: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
FAIL tests/cli.helpCommand.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.helpCommand.test.js:1:18)
PASS tests/localVars.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit)
at _log (node_modules/dotenv/lib/main.js:136:11)
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ suppress all logs with { quiet: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.invalidExtensionType.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: 🔐 prevent building .env in docker: https://dotenvx.com/prebuild)
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/index.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/findMatchingFiles.invalid.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ write to custom object with { processEnv: myObject })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/searchFiles.invalid-extension.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ load multiple .env files with { path: ['.env.local', '.env'] })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.success.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/errors.test.js
PASS tests/function-scope.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ override existing env vars with { override: true })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/validateDirectory.invalid.test.js
● Console
console.log
[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' })
at _log (node_modules/dotenv/lib/main.js:136:11)
PASS tests/asyncPool.cleanup.test.js
Summary of all failing tests
FAIL tests/integration.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/integration.test.js:11:18)
FAIL tests/cli.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.test.js:1:18)
FAIL tests/cli.invalidCommand.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.invalidCommand.test.js:1:18)
FAIL tests/cli.multipleOptions.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.multipleOptions.test.js:1:18)
FAIL tests/cli.default.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.default.test.js:7:18)
FAIL tests/cli.helpCommand.test.js
● Test suite failed to run
Must use import to load ES Module: /home/runner/workspace/node_modules/yargs/index.mjs
8 | // Import scanning functions directly from lib to avoid circular dependency when
9 | // index.js also requires this module
> 10 | const yargs = require('yargs/yargs');
| ^
11 | const { hideBin } = require('yargs/helpers');
12 | const { findMatchingFiles, findMatchingFilesDetailed } = require('./lib/utils.js');
13 | const { AppError, OperationalError, ProgrammerError } = require('./lib/errors');
at Runtime.requireModule (node_modules/jest-runtime/build/index.js:799:21)
at Object.require (cli.js:10:15)
at Object.require (tests/cli.helpCommand.test.js:1:18)
Test Suites: 6 failed, 20 passed, 26 total
Tests: 49 passed, 49 total
Snapshots: 0 total
Time: 2.377 s, estimated 4 s
Ran all test suites matching tests.
</file>
<file path="directory_test/AGENTS.md">
Do not modify the files in this folder.
</file>
<file path="directory_test/badConst.js">
// File 3: const variable declaration for "bad variable"
const pig = "pink";
</file>
<file path="directory_test/badEnvOnly.js">
// File 5: uses process.env.BAD_ENV without using const
if (process.env.BAD_ENV) {
console.log('BAD_ENV is set to:', process.env.BAD_ENV);
} else {
console.log('BAD_ENV is not set');
}
</file>
<file path="directory_test/summary.md">
# Directory Test Directory
This directory contains a collection of JavaScript files used for testing the `loqatevars` tool.
The files are designed to test specific scenarios, such as:
* `badConst.js`
* `badScope.js`
* `functionCaller.js`
* `ifStatement.js`
* `importModule.js`
* `letVariable.js`
* `badEnvOnly.js`
* `requireImport.js`
These files likely serve as test cases to ensure the tool correctly identifies or
ignores different patterns of `const` and `process.env` usage.
</file>
<file path="test_dir/indirect-env.js">
// Test file for indirect process.env access
const env = process.env;
console.log(env.TEST_VAR);
// Test destructuring
const { env: destructuredEnv } = process;
console.log(destructuredEnv.TEST_VAR2);
</file>
<file path="tests/__mocks__/globby.js">
const fs = require('fs');
const path = require('path');
function walk(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
let files = [];
for (const entry of entries) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
files = files.concat(walk(full));
} else {
files.push(full);
}
}
return files;
}
function globbySync(patterns, options = {}) {
const cwd = options.cwd || process.cwd();
const ignore = options.ignore || [];
const exts = patterns.map(p => p.replace('**/*', ''));
const allFiles = walk(cwd).filter(f => exts.some(ext => f.endsWith(ext)));
return allFiles.filter(f => !ignore.some(pat => {
const clean = pat.replace(/\*\*\//g, '').replace(/\*\*/g, '');
return f.includes(clean);
}));
}
function globbyStream(patterns, options = {}) {
const files = globbySync(patterns, options);
async function* generator() {
for (const file of files) { yield file; }
}
return generator();
}
function globby() {}
globby.stream = jest.fn(globbyStream);
module.exports = {
__esModule: true,
default: globby,
globbySync,
stream: globby.stream,
};
</file>
<file path="tests/asyncPool.cleanup.test.js">
describe('asyncPool cleanup safety', () => {
test('does not splice when promise not present', () => {
const executing = [Promise.resolve('a'), Promise.resolve('b')];
const e = Promise.resolve('c');
const cleanup = () => {
const idx = executing.indexOf(e);
if (idx > -1) executing.splice(idx, 1);
};
const beforeLen = executing.length;
cleanup();
expect(executing.length).toBe(beforeLen);
});
});
</file>
<file path="tests/cli.helpCommand.test.js">
const { main } = require('../cli.js');
const utils = require('../lib/utils.js');
jest.mock('../lib/utils.js');
describe('CLI help command', () => {
let logSpy;
let exitSpy;
beforeEach(() => {
logSpy = jest.spyOn(console, 'log').mockImplementation();
exitSpy = jest.spyOn(process, 'exit').mockImplementation();
});
afterEach(() => {
logSpy.mockRestore();
exitSpy.mockRestore();
jest.clearAllMocks();
});
test('loqatevars help shows usage info', async () => {
process.argv = ['node', 'cli.js', 'help'];
await main();
expect(utils.findMatchingFiles).not.toHaveBeenCalled();
const output = logSpy.mock.calls.map(c => c.join(' ')).join('\n');
expect(output).toMatch(/Commands:/); // confirm help output
expect(exitSpy).not.toHaveBeenCalled();
});
});
</file>
<file path="tests/cli.invalidCommand.test.js">
const { main } = require('../cli.js');
const utils = require('../lib/utils.js');
jest.mock('../lib/utils.js');
describe('CLI invali