/** * Validate No File Import Cycles Executor * * Per-project circular-dependency gate. Runs `madge` over the project's * TypeScript sources and fails when an import cycle is found. * * Unlike the old `nx:run-commands` target (which shelled out to a runtime * `npx madge` fetch — undeclared, so consumers of the published plugin had no * local madge and CI runners corrupted their npx cache fetching it), this executor: * - invokes the madge it bundles as a dependency (deterministic, no network), * - is driven by webpieces.config.json like every other webpieces rule, so it * supports an on/off `mode` and a time-boxed `turnOffRuleUntilEpoch`. * * Config (webpieces.config.json, rule key `no-file-import-cycles`): * "no-file-import-cycles": { * "mode": "RUN_EVERY_TIME", // "OFF" disables the gate everywhere * "turnOffRuleUntilEpoch": 1771931925, // epoch SECONDS; while now < epoch, * // cycles are reported but the gate PASSES * // (warn, don't fail). After it, fails again. * "turnOffRuleWhileOnBranch": null, // branch name; while that branch is checked out, * // cycles are reported but the gate PASSES * "ignoreTypeOnly": true, // ignore `import type` re-export cycles * // (erased at compile time, harmless at runtime) * "excludePackages": ["@db/entities"] // npm package names whose source trees madge * // should NOT traverse (stops foreign cycles * // from leaking into this project's report) * } * * Mirrors the dated-disable model already used for the method/file-size rules: * the epoch is a grace window so a strict gate can be turned on against an * existing codebase without an open-ended "off everywhere" escape hatch. * * Usage: nx run :validate-no-file-import-cycles */ import type { ExecutorContext } from '@nx/devkit'; export type ValidateNoFileImportCyclesMode = 'RUN_EVERY_TIME' | 'OFF'; export interface ValidateNoFileImportCyclesOptions { } export interface ExecutorResult { success: boolean; } interface MadgeOptions { fileExtensions: string[]; excludeRegExp?: string[]; detectiveOptions?: Record; } export declare function buildMadgeOptions(ignoreTypeOnly: boolean, excludePackages: string[], workspaceRoot: string, projectRoot: string, userExcludeRegExp?: string[]): MadgeOptions; export default function runExecutor(_options: ValidateNoFileImportCyclesOptions, context: ExecutorContext): Promise; export {};