import { getProjects, ProjectConfiguration, ProjectGraph, Tree, } from 'nx/src/devkit-exports'; type CallBack = ( currentValue: T, project: string, target: string, configuration?: string ) => void; /** * Calls a function for each different options that an executor is configured with */ export function forEachExecutorOptions( tree: Tree, /** * Name of the executor to update options for */ executorName: string, /** * Callback that is called for each options configured for a builder */ callback: CallBack ): void { forEachProjectConfig(getProjects(tree), executorName, callback); } /** * Calls a function for each different options that an executor is configured with via the project graph * this is helpful when you need to get the expaned configuration options from the nx.json **/ export function forEachExecutorOptionsInGraph( graph: ProjectGraph, executorName: string, callback: CallBack ): void { const projects = new Map(); Object.values(graph.nodes).forEach((p) => projects.set(p.name, p.data)); forEachProjectConfig(projects, executorName, callback); } function forEachProjectConfig( projects: Map, executorName: string, callback: CallBack ): void { for (const [projectName, project] of projects) { for (const [targetName, target] of Object.entries(project.targets || {})) { if (executorName !== target.executor) { continue; } callback(target.options ?? {}, projectName, targetName); if (!target.configurations) { continue; } Object.entries(target.configurations).forEach(([configName, options]) => { callback(options, projectName, targetName, configName); }); } } } // TODO: add a method for updating options