Skip to content

Custom plugin ​

A plugin is a class that extends BasePlugin and returns an array of proposed files. The plugin does not need to write files to disk itself: FileGenerator handles this so that all artifacts go through the common headerTemplate, format, logging, cleanup, and cascading iterations.

generate ​

A method for proposing files for the generator to create or modify.

ts
import path from 'node:path';

import { 
  BasePlugin, 
  type TypeGeneratedFiles, 
  type TypePluginGenerateArgs 
} from '@arfa-tools/generator';

export class PluginBuildInfo extends BasePlugin {
  name = 'build-info';

  async generate({ 
    rootDir, 
    pluginLog 
  }: TypePluginGenerateArgs): Promise<TypeGeneratedFiles> {
    pluginLog({ plugin: this.name, message: 'Generating build info' });

    return [
      {
        plugin: this.name,
        filePath: path.resolve(rootDir, 'buildInfo.generated.ts'),
        rawContent: "export const generatorName = '@arfa-tools/generator';\n",
      },
    ];
  }
}
ts
rootDir: string

The root directory passed to FileGenerator

ts
changedFiles?: Array<{
  event: 'add' | 'change' | 'unlink';
  origin: 'watch' | 'cascade';
  filePath: string;
  eventTimeMs: number;
  relativePath: string;
}>

The list of files changed in watch mode or a cascading iteration. On the first iteration of generator.runFullCycle(), this is undefined

ts
pluginLog: (log: {
  message: string;
  plugin: string;
}) => void

A function for logging informational messages

ts
pluginError: (log: {
  message: string;
  plugin: string;
  error: unknown;
}) => void

A function for reporting errors

Return the same content for unchanged inputs. Date.now(), random values, or other changing data inside generate can trigger cascading iterations (up to the limit of 10).

TypeGeneratedFiles ​

ts
plugin: string

The plugin name used in logs

ts
filePath: string

The absolute path of the target file

ts
rawContent: string

The content before headerTemplate and format are applied

ts
skipHeader?: boolean

Disables the common header for this file. Useful for JSON, assets, documentation, etc.

cleanup ​

A method for proposing files for the generator to delete.

ts
import path from 'node:path';

import {
  BasePlugin,
  type TypeCleanupFiles,
  type TypeGeneratedFiles,
  type TypePluginCleanupArgs,
  type TypePluginGenerateArgs,
} from '@arfa-tools/generator';

export class PluginBuildInfo extends BasePlugin {
  name = 'build-info';

  async generate({ rootDir }: TypePluginGenerateArgs): Promise<TypeGeneratedFiles> {
    return [{
      plugin: this.name,
      filePath: path.resolve(rootDir, 'generated/buildInfo/index.generated.ts'),
      rawContent: "export const generatorName = '@arfa-tools/generator';\n",
    }];
  }

  cleanup({ rootDir, generatedFiles, changedFiles }: TypePluginCleanupArgs): TypeCleanupFiles {
    // Cleanup only during runFullCycle()
    if (changedFiles) return [];

    const expectedPaths = new Set(
      generatedFiles
        .filter(({ plugin }) => plugin === this.name)
        .map(({ filePath }) => filePath)
    );

    return this.globToPaths({
      rootDir,
      entries: ['generated/buildInfo/*.generated.ts'],
      kind: 'file',
    })
      .filter((filePath) => !expectedPaths.has(filePath))
      .map((filePath) => ({ plugin: this.name, filePath }));
  }
}
ts
rootDir: string

The root directory passed to FileGenerator

ts
changedFiles?: Array<{
  event: 'add' | 'change' | 'unlink';
  origin: 'watch' | 'cascade';
  filePath: string;
  eventTimeMs: number;
  relativePath: string;
}>

The list of files changed in watch mode or a cascading iteration. On the first iteration of generator.runFullCycle(), this is undefined

ts
generatedFiles: TypeGeneratedFiles

The results of successful generate calls from all plugins in the current iteration, including files not written to disk because their content was unchanged

Cleanup runs after writing and receives the results of successful generate calls from the current iteration. If a plugin’s generate throws an exception, its cleanup is skipped, preserving previously created artifacts.

TypeCleanupFiles ​

ts
plugin: string

The plugin name used in logs

ts
filePath: string

The absolute path of the file the generator should delete

Built-in helpers ​

BasePlugin provides two helper methods that return sorted absolute paths:

ts
globToPaths(params: {
  rootDir: string;
  entries: Array<string>;
  kind: 'file' | 'dir';
  exclude?: RegExp;
}): Array<string>

Finds files or directories using glob patterns relative to rootDir

ts
getDirectChildren(params: {
  folderPath: string;
  filter?: (filePath: string) => boolean;
  exclude?: RegExp;
}): Array<string>

Returns the immediate child files of a folder, with optional filtering

entries are specified relative to rootDir; absolute paths and .. segments are not allowed.

exclude matches against the file or folder name.

MIT License