# loqatevars

A Node.js module designed to help locate errant variable use in LLM-created applications. It scans JavaScript codebases to find files containing both 'const' declarations and 'process.env' usage, enabling developers to centralize variable declarations and environment variable naming instead of having them scattered and mutated throughout the codebase.

## Why loqatevars?

When LLMs generate code, they often create scattered variable declarations and inconsistent environment variable usage across multiple files. This makes it difficult to:
- Track where variables are defined
- Maintain consistent naming conventions
- Centralize configuration management
- Refactor variable usage

loqatevars helps you identify these files so you can consolidate variable declarations and environment variable access into a centralized location.

## Features

- Recursive directory scanning to find problematic files
- Broad detection: identifies files containing:
  - `const` declarations (excluding imports)
  - `process.env` usage (including direct, indirect, and dynamic access)
  - ES module imports (`import` statements)
- Smart frontend directory exclusion (ignores public, assets, components, etc.)
- Configurable file ignore patterns (defaults to `**/localVars.js`)
- Detailed analysis with statistics for large codebases
- CLI interface with file count display for quick audits
- Lightweight with minimal dependencies

## Detection Limitations

The tool may not detect:
- `process.env` access via computed properties (`process[someKey]`)
- Environment variables accessed through proxy objects
- Variables that are dynamically constructed
- `process.env` access in minified/obfuscated code

## Installation


```bash
# install as dependency
npm install loqatevars
```

## Development Setup

To run the test suite locally you must install the project's dev dependencies.
Running `npm install` without the `--production` flag ensures Jest and other
packages in `devDependencies` are available.
Skipping this step will cause `MODULE_NOT_FOUND` errors when executing `npm test`.

## Usage

### Programmatic API

```javascript
const { findMatchingFiles, findMatchingFilesDetailed } = require('loqatevars');

async function run() {
  // Basic usage - returns an array of file paths
  const matches = await findMatchingFiles('./src');
  console.log(matches); // ["src/config.js", "src/server.js"]

  // Detailed analysis with statistics
  const detailed = await findMatchingFilesDetailed('./src');
  console.log(`Found ${detailed.summary.matchingFiles} matching files`);
  detailed.matches.forEach(match => {
    console.log(`- ${match.relativePath}`);
  });
}

run();
```

### CLI Usage

```bash
# Scan current directory (default command)
loqatevars scan

# Scan specific directory
loqatevars scan ./src

# Detailed analysis with statistics
loqatevars detailed ./src

# Custom ignore files (comma-separated or repeated)
loqatevars scan ./src --ignore "localVars.js,config.js"
# Equivalent repeated usage
loqatevars scan ./src --ignore localVars.js --ignore config.js

# Scan multiple file types
loqatevars scan ./src --extensions ".js,.ts"
# Equivalent repeated usage
loqatevars scan ./src --extensions .js --extensions .ts

# Enable debug logging
loqatevars scan ./src --debug

# Help
loqatevars help
# Or
loqatevars --help
# Or
loqatevars -h
```

Both `--ignore` and `--extensions` accept comma-separated values or can be repeated.

## How it works

loqatevars scans your codebase to identify files that contain variable declarations or environment variable access:

1. **Detects `const` declarations** - Files defining variables locally
2. **Detects `process.env` usage** - Files accessing environment variables
3. **Finds files with either** - All candidates for centralization

The goal is to help you move toward a pattern where:
- Environment variables are accessed in one centralized location (like `config.js`)
- Other files import from that central config instead of directly accessing `process.env`
- Variable naming becomes consistent across your application

By default, it ignores `**/localVars.js` (assuming this is your intended centralized config file).

## API Reference

### `findMatchingFiles(dir, ignoreFiles, extensions)`

Scans directory for files containing either 'const' declarations or 'process.env' usage.

**Parameters:**
- `dir` (string): Directory to scan (default: `process.cwd()`)
- `ignoreFiles` (string|Array): Files to ignore (default: '**/localVars.js')
- `extensions` (string|Array): File extensions to scan (default: ['.js'])

**Returns:** `Promise<string[]>` - A promise that resolves to an array of matching file paths.

### `findMatchingFilesDetailed(dir, ignoreFiles, extensions)`

Provides detailed analysis with statistics and file information for each match.

**Returns:** `Promise<object>` - A promise that resolves to an object with a `matches` array and `summary` statistics.

### `analyzeConstUsage(content)` (Internal Function)

Analyze a single file's contents to determine how `const` is used and whether
`process.env` appears. This function is not part of the public API but is documented here for completeness.

**Parameters:**
- `content` (string): File contents to inspect

**Returns:** Object with `totalConst`, `importConst`, `variableConst`,
`hasProcessEnv`, and `shouldFlag` fields

### CLI Entry Point

You can import the `main` function from `cli.js` to build a custom
command-line interface if needed. This is useful if you want to integrate `loqatevars` into other tools.

**Example:**
```javascript
const { main } = require('loqatevars/cli');

// To run the 'scan' command on the current directory programmatically:
process.argv.push('scan', '.');
main();
```

## Example Output

### Basic scan
```bash
$ loqatevars scan ./src
src/config.js
src/server.js
src/database.js
src/utils.js

Found 4 files
```

These files contain either variable declarations or environment variable access - all candidates for centralization.

### Detailed analysis
```bash
$ loqatevars detailed ./src

=== loqatevars Detailed Analysis ===
Directory: /project/src
Scanned files: 13
Matching files: 4
Ignored file patterns: **/localVars.js

--- Matching Files ---
- config.js (Reason: process.env)
- database.js (Reason: const, process.env)
- server.js (Reason: const, process.env)
- utils.js (Reason: const)

## Error Handling

The CLI tool is designed to exit with a non-zero status code upon encountering an error. The errors are categorized to help distinguish between user-correctable issues and internal problems:

- **`OperationalError`**: This error occurs when there is a problem with the environment or the inputs provided by the user. Examples include:
  - The specified directory does not exist.
  - Invalid file extensions are provided.
  - The user provides an invalid command.

- **`ProgrammerError`**: This error indicates a bug or an issue within the tool's source code. These are unexpected errors that should be reported for investigation.

When an error occurs, a descriptive message is printed to the console to help with troubleshooting.
--- Concatenated Paths ---
/project/src/config.js
/project/src/database.js
/project/src/server.js
/project/src/utils.js
```

## Refactoring Strategy

Once you've identified problematic files, consider this refactoring approach:

**Before (scattered variables):**
```javascript
// database.js
const dbHost = process.env.DB_HOST || 'localhost';
const dbPort = process.env.DB_PORT || 5432;

// server.js  
const port = process.env.PORT || 3000;
const apiKey = process.env.API_KEY;
```

**After (centralized config):**
```javascript
// config.js or localVars.js
module.exports = {
  database: {
    host: process.env.DB_HOST || 'localhost',
    port: process.env.DB_PORT || 5432
  },
  server: {
    port: process.env.PORT || 3000,
    apiKey: process.env.API_KEY
  }
};

// database.js
const config = require('./config');
const { host, port } = config.database;

// server.js
const config = require('./config');
const { port, apiKey } = config.server;
```

## Testing

Install dependencies first, then run the Jest test suite:

```bash
npm install
npm test
```

Skipping the installation step results in `MODULE_NOT_FOUND` errors for the Jest runtime. This command runs all unit tests in the `tests/` folder.

All tests reside in the `tests/` directory and are executed via Jest.

## License

MIT

