Skip to content

CheckerCli ​

Runs an external CLI command within the generator’s unified pipeline, with cwd: rootDir. The command runs synchronously through spawnSync. Standard output from successful runs is not included in the logs. If the command fails, its output, exit code, signal, and other available information are logged.

ts
name: string

The checker name used in logs

ts
getCommand: (args: {
  changedFiles: Array<{
    relativePath: string;
    absolutePath: string;
  }>;
  deletedFiles: Array<{
    relativePath: string;
    absolutePath: string;
  }>;
  isFullGeneration: boolean;
}) => false | Array<string>

A function that returns an array whose first element is the command and whose remaining elements are its arguments. Returning false skips the check.

changedFiles contains unique paths of files added or changed by the user in watch mode, or written by the generator across all iterations of the current run.

deletedFiles contains unique paths of files deleted by the user in watch mode, or by the generator during cleanup across all iterations of the current run.

isFullGeneration is true for a full runFullCycle() run and false for an incremental run in watch mode. Useful for deciding when to run a full check

All tests run during full generation and after files are deleted; incremental generation runs only tests related to changed files

ts
new CheckerCli({
  name: 'vitest',
  getCommand({ changedFiles, deletedFiles, isFullGeneration }) {
    const vitest = path.resolve(process.cwd(), 'node_modules/.bin/vitest');

    if (isFullGeneration || deletedFiles.length > 0) return [vitest, 'run'];

    if (changedFiles.length === 0) return false;

    return [vitest, 'related', '--run', ...changedFiles.map(({ relativePath }) => relativePath)];
  },
}),
Run Sandbox
USER: src/sum.ts was created with content:
ts
export const sum = (a: number, b: number) => a + b;
USER: src/double.ts was created with content:
ts
export const double = (value: number) => value * 2;
USER: src/obsolete.ts was created with content:
ts
export const obsolete = true;
USER: tests/sum.test.ts was created with content:
ts
import { expect, it } from 'vitest';
import { sum } from '../src/sum';

it('adds two numbers', () => {
  expect(sum(2, 3)).toBe(5);
});
USER: tests/double.test.ts was created with content:
ts
import { expect, it } from 'vitest';
import { double } from '../src/double';

it('doubles a number', () => {
  expect(double(3)).toBe(6);
});
ARFA Generator shows logs:
txt
[ARFA-GEN] finished in 0ms

Example: Biome checks only changed files

If no files were changed (for example, if files were only deleted), the check is skipped

ts
new CheckerCli({
  name: 'biome',
  getCommand({ changedFiles }) {
    if (changedFiles.length === 0) return false;

    return [
      path.resolve(process.cwd(), 'node_modules/.bin/biome'),
      'check',
      '--no-errors-on-unmatched',
      ...changedFiles.map(({ relativePath }) => relativePath),
    ];
  },
}),
Run Sandbox
USER: biome.json was created with content:
json
{
  "formatter": {
    "indentStyle": "space",
    "indentWidth": 2
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single"
    }
  }
}
USER: src/draft.ts was created with content:
ts
export const answer = 42;
ARFA Generator shows logs:
txt
[ARFA-GEN] finished in 0ms

Example: Type checking with tsc

In this example, tsc runs for the entire project, even if files were only deleted

ts
new CheckerCli({
  name: 'tsc',
  getCommand: () => [path.resolve(process.cwd(), 'node_modules/.bin/tsc')],
}),
Run Sandbox
USER: tsconfig.json was created with content:
json
{
  "include": ["src"],
  "compilerOptions": {
    "target": "ES2023",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "noEmit": true,
    "strict": true,
    "types": []
  }
}
USER: src/count.ts was created with content:
ts
export const count: number = 1;
ARFA Generator shows logs:
txt
[ARFA-GEN] finished in 0ms

MIT License