diff --git a/libs/language-server/watcher/src/lib/native-watcher.ts b/libs/language-server/watcher/src/lib/native-watcher.ts index 42a82d26c2..6055d32dd7 100644 --- a/libs/language-server/watcher/src/lib/native-watcher.ts +++ b/libs/language-server/watcher/src/lib/native-watcher.ts @@ -26,7 +26,10 @@ export class NativeWatcher { private watcher: Watcher | undefined; private stopped = false; - constructor(private workspacePath: string, private callback: () => unknown) { + constructor( + private workspacePath: string, + private callback: () => unknown, + ) { this.initWatcher(); } @@ -39,7 +42,7 @@ export class NativeWatcher { const native = await importNxPackagePath( this.workspacePath, 'src/native/index.js', - lspLogger + lspLogger, ); this.watcher = new native.Watcher(this.workspacePath); @@ -57,13 +60,13 @@ export class NativeWatcher { path.endsWith('workspace.json') || path.endsWith('tsconfig.base.json') || NX_PLUGIN_PATTERNS_TO_WATCH.some((pattern) => - minimatch([path], pattern, { dot: true }) + minimatch([path], pattern, { dot: true }), ) || NativeWatcher.openDocuments.has(path)) && !path.startsWith('node_modules') && !path.startsWith(normalize('.nx/cache')) && !path.startsWith(normalize('.yarn/cache')) && - !path.startsWith(normalize('.nx/workspace-data')) + !path.startsWith(normalize('.nx/workspace-data')), ) ) { if (this.stopped) { @@ -73,7 +76,7 @@ export class NativeWatcher { lspLogger.log( `native watcher detected project changes in files ${events .map((e) => normalize(e.path)) - .join(', ')}` + .join(', ')}`, ); this.callback(); } diff --git a/libs/language-server/workspace/src/lib/get-generator-options.ts b/libs/language-server/workspace/src/lib/get-generator-options.ts index 311e5e7904..4de243f40d 100644 --- a/libs/language-server/workspace/src/lib/get-generator-options.ts +++ b/libs/language-server/workspace/src/lib/get-generator-options.ts @@ -1,4 +1,4 @@ -import { readAndCacheJsonFile } from '@nx-console/shared-file-system'; +import { readJsonFile } from '@nx-console/shared-file-system'; import { Option } from '@nx-console/shared-schema'; import { normalizeSchema } from '@nx-console/shared-schema'; import { nxWorkspace } from '@nx-console/shared-nx-workspace-info'; @@ -10,7 +10,7 @@ export async function getGeneratorOptions( generatorName: string, generatorPath: string, ): Promise { - const generatorSchema = await readAndCacheJsonFile( + const generatorSchema = await readJsonFile( generatorPath, undefined, lspLogger, diff --git a/libs/shared/file-system/src/index.ts b/libs/shared/file-system/src/index.ts index 4f2ab5b1b6..bee893fbba 100644 --- a/libs/shared/file-system/src/index.ts +++ b/libs/shared/file-system/src/index.ts @@ -1,9 +1,7 @@ export { fileExists } from './lib/file-exists'; export { directoryExists } from './lib/directory-exists'; -export { cacheJson } from './lib/cache-json'; -export { readAndCacheJsonFile } from './lib/cache-json'; -export { clearJsonCache } from './lib/cache-json'; -export { readAndParseJson } from './lib/cache-json'; +export { readJsonFile } from './lib/read-json-file'; +export { readAndParseJson } from './lib/read-json-file'; export { listFiles } from './lib/list-files'; export { readDirectory } from './lib/read-directory'; export { readFile } from './lib/read-file'; diff --git a/libs/shared/file-system/src/lib/cache-json.ts b/libs/shared/file-system/src/lib/cache-json.ts deleted file mode 100644 index 47226b1155..0000000000 --- a/libs/shared/file-system/src/lib/cache-json.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as path from 'path'; -import { PosixFS } from '@yarnpkg/fslib'; -import { ZipOpenFS, getLibzipSync as libzip } from '@yarnpkg/libzip'; -import { Logger } from '@nx-console/shared-utils'; - -import { parse as parseJson, ParseError } from 'jsonc-parser'; - -const zipOpenFs = new ZipOpenFS({ libzip }); -export const crossFs = new PosixFS(zipOpenFs); -export const files: { [path: string]: string[] } = {}; -export const fileContents: { [path: string]: any } = {}; - -export async function readAndParseJson(filePath: string) { - const content = await crossFs.readFilePromise(filePath, 'utf8'); - try { - return JSON.parse(content); - } catch { - const errors: ParseError[] = []; - const result = parseJson(content, errors); - - if (errors.length > 0) { - // for (const { error, offset } of errors) { - // TODO(cammisuli): output this generically - // getOutputChannel().appendLine( - // `${printParseErrorCode( - // error - // )} in JSON at position ${offset} in ${filePath}` - // ); - // } - } - - return result; - } -} - -export function clearJsonCache(filePath: string, basedir = '') { - const fullFilePath = path.join(basedir, filePath); - return delete fileContents[fullFilePath]; -} - -export async function readAndCacheJsonFile( - filePath: string | undefined, - basedir = '', - logger?: Logger, -): Promise<{ path: string; json: any }> { - if (!filePath) { - return { - path: '', - json: {}, - }; - } - - let fullFilePath = basedir ? path.join(basedir, filePath) : filePath; - if (fullFilePath.startsWith('file:\\')) { - fullFilePath = fullFilePath.replace('file:\\', ''); - } - if (fullFilePath.startsWith('file://')) { - fullFilePath = fullFilePath.replace('file://', ''); - } - try { - const stats = await crossFs.statPromise(fullFilePath); - if (fileContents[fullFilePath] || stats.isFile()) { - fileContents[fullFilePath] ||= await readAndParseJson(fullFilePath); - return { - path: fullFilePath, - json: fileContents[fullFilePath], - }; - } - } catch (e) { - logger?.log(`${fullFilePath} does not exist`); - } - - return { - path: fullFilePath, - json: {}, - }; -} - -/** - * Caches already created json contents to a file path - */ -export function cacheJson(filePath: string, basedir = '', content?: any) { - const fullFilePath = path.join(basedir, filePath); - if (fileContents[fullFilePath]) { - return { - json: fileContents[fullFilePath], - path: fullFilePath, - }; - } - - if (content) { - fileContents[fullFilePath] = content; - } - return { - json: content, - path: fullFilePath, - }; -} diff --git a/libs/shared/file-system/src/lib/read-file.ts b/libs/shared/file-system/src/lib/read-file.ts index 2b2445f29a..0a1da9960f 100644 --- a/libs/shared/file-system/src/lib/read-file.ts +++ b/libs/shared/file-system/src/lib/read-file.ts @@ -1,4 +1,8 @@ -import { crossFs } from './cache-json'; +import { PosixFS } from '@yarnpkg/fslib'; +import { ZipOpenFS, getLibzipSync as libzip } from '@yarnpkg/libzip'; + +const zipOpenFs = new ZipOpenFS({ libzip }); +export const crossFs = new PosixFS(zipOpenFs); export async function readFile(filePath: string): Promise { try { diff --git a/libs/shared/file-system/src/lib/read-json-file.ts b/libs/shared/file-system/src/lib/read-json-file.ts new file mode 100644 index 0000000000..7ab2b8e253 --- /dev/null +++ b/libs/shared/file-system/src/lib/read-json-file.ts @@ -0,0 +1,53 @@ +import * as path from 'path'; +import { Logger } from '@nx-console/shared-utils'; +import { readFileSync, existsSync } from 'fs'; +import { parse as parseJson, ParseError } from 'jsonc-parser'; + +export async function readAndParseJson(filePath: string) { + const content = readFileSync(filePath, 'utf8'); + try { + return JSON.parse(content); + } catch { + const errors: ParseError[] = []; + const result = parseJson(content, errors); + return result; + } +} + +export async function readJsonFile( + filePath: string | undefined, + basedir = '', + logger?: Logger, +): Promise<{ path: string; json: any }> { + if (!filePath) { + return { + path: '', + json: {}, + }; + } + + let fullFilePath = basedir ? path.join(basedir, filePath) : filePath; + if (fullFilePath.startsWith('file:\\')) { + fullFilePath = fullFilePath.replace('file:\\', ''); + } + if (fullFilePath.startsWith('file://')) { + fullFilePath = fullFilePath.replace('file://', ''); + } + + try { + if (existsSync(fullFilePath)) { + const json = await readAndParseJson(fullFilePath); + return { + path: fullFilePath, + json, + }; + } + } catch (e) { + logger?.log(`${fullFilePath} does not exist`); + } + + return { + path: fullFilePath, + json: {}, + }; +} diff --git a/libs/shared/npm/src/lib/check-is-nx-workspace.ts b/libs/shared/npm/src/lib/check-is-nx-workspace.ts index 2d08fdfea9..6df1a0783d 100644 --- a/libs/shared/npm/src/lib/check-is-nx-workspace.ts +++ b/libs/shared/npm/src/lib/check-is-nx-workspace.ts @@ -1,8 +1,5 @@ import { join } from 'path'; -import { - fileExists, - readAndCacheJsonFile, -} from '@nx-console/shared-file-system'; +import { fileExists, readJsonFile } from '@nx-console/shared-file-system'; import { coerce } from 'semver'; import { workspaceDependencyPath } from './workspace-dependencies'; @@ -18,7 +15,7 @@ export async function checkIsNxWorkspace( return false; } - const lernaPackageJson = await readAndCacheJsonFile( + const lernaPackageJson = await readJsonFile( join(lernaPath, 'package.json'), ); const lernaVersion = coerce(lernaPackageJson.json.version); @@ -26,7 +23,7 @@ export async function checkIsNxWorkspace( if (lernaVersion?.major ?? 0 >= 6) { isNxWorkspace = true; } else { - const lerna = await readAndCacheJsonFile('lerna.json', workspacePath); + const lerna = await readJsonFile('lerna.json', workspacePath); isNxWorkspace = lerna.json.useNx ?? false; } } diff --git a/libs/shared/npm/src/lib/package-details.spec.ts b/libs/shared/npm/src/lib/package-details.spec.ts index 45e6c41a0c..3c8aa9d068 100644 --- a/libs/shared/npm/src/lib/package-details.spec.ts +++ b/libs/shared/npm/src/lib/package-details.spec.ts @@ -1,4 +1,4 @@ -import { readAndCacheJsonFile } from '@nx-console/shared-file-system'; +import { readJsonFile } from '@nx-console/shared-file-system'; import { packageDetails } from './package-details'; import { normalize } from 'node:path'; @@ -6,17 +6,15 @@ jest.mock('@nx-console/shared-file-system'); describe('packageDetails', () => { it('should return package path, package name and JSON contents', async () => { - const readAndCacheJsonFileMock = jest - .mocked(readAndCacheJsonFile) - .mockResolvedValueOnce({ - path: 'path', - json: { - name: 'utils', - version: '1.0.0', - main: 'dist/index.js', - types: 'dist/index.d.ts', - }, - }); + const readJsonFileMock = jest.mocked(readJsonFile).mockResolvedValueOnce({ + path: 'path', + json: { + name: 'utils', + version: '1.0.0', + main: 'dist/index.js', + types: 'dist/index.d.ts', + }, + }); expect(await packageDetails('libs/utils')).toEqual({ packagePath: 'libs/utils', @@ -28,24 +26,22 @@ describe('packageDetails', () => { types: 'dist/index.d.ts', }, }); - expect(readAndCacheJsonFileMock).toBeCalledWith( + expect(readJsonFileMock).toBeCalledWith( normalize('libs/utils/package.json'), ); }); it('should return undefined package name if JSON is empty', async () => { - const readAndCacheJsonFileMock = jest - .mocked(readAndCacheJsonFile) - .mockResolvedValueOnce({ - path: '', - json: {}, - }); + const readJsonFileMock = jest.mocked(readJsonFile).mockResolvedValueOnce({ + path: '', + json: {}, + }); expect(await packageDetails('')).toEqual({ packagePath: '', packageName: undefined, packageJson: {}, }); - expect(readAndCacheJsonFileMock).toBeCalledWith('package.json'); + expect(readJsonFileMock).toBeCalledWith('package.json'); }); }); diff --git a/libs/shared/npm/src/lib/package-details.ts b/libs/shared/npm/src/lib/package-details.ts index a2537fbee2..4ece8f153d 100644 --- a/libs/shared/npm/src/lib/package-details.ts +++ b/libs/shared/npm/src/lib/package-details.ts @@ -1,10 +1,8 @@ -import { readAndCacheJsonFile } from '@nx-console/shared-file-system'; +import { readJsonFile } from '@nx-console/shared-file-system'; import { join } from 'path'; export async function packageDetails(packagePath: string) { - const { json } = await readAndCacheJsonFile( - join(packagePath, 'package.json') - ); + const { json } = await readJsonFile(join(packagePath, 'package.json')); return { packagePath, packageName: json.name, diff --git a/libs/shared/nx-workspace-info/src/lib/get-executors.ts b/libs/shared/nx-workspace-info/src/lib/get-executors.ts index 45d29d92fb..bc6e3031c6 100644 --- a/libs/shared/nx-workspace-info/src/lib/get-executors.ts +++ b/libs/shared/nx-workspace-info/src/lib/get-executors.ts @@ -4,14 +4,12 @@ import { Logger } from '@nx-console/shared-utils'; export type GetExecutorsOptions = { includeHidden: boolean; - clearPackageJsonCache: boolean; }; export async function getExecutors( workspacePath: string, options: GetExecutorsOptions = { includeHidden: false, - clearPackageJsonCache: false, }, logger?: Logger, ): Promise { @@ -19,7 +17,6 @@ export async function getExecutors( await readCollections( workspacePath, { - clearPackageJsonCache: options.clearPackageJsonCache, includeHidden: options.includeHidden, }, logger, diff --git a/libs/shared/nx-workspace-info/src/lib/get-generators.ts b/libs/shared/nx-workspace-info/src/lib/get-generators.ts index 47390dc626..05ba6af5c4 100644 --- a/libs/shared/nx-workspace-info/src/lib/get-generators.ts +++ b/libs/shared/nx-workspace-info/src/lib/get-generators.ts @@ -3,7 +3,7 @@ import { directoryExists, fileExists, listFiles, - readAndCacheJsonFile, + readJsonFile, } from '@nx-console/shared-file-system'; import { GeneratorCollectionInfo, @@ -26,7 +26,6 @@ export async function getGenerators( const collections = await readCollections( workspacePath, { - clearPackageJsonCache: false, includeHidden: options.includeHidden, includeNgAdd: options.includeNgAdd, }, @@ -77,9 +76,7 @@ async function readWorkspaceGeneratorsCollection( }`; const collectionPath = join(collectionDir, 'collection.json'); if (await fileExists(collectionPath)) { - const collection = await readAndCacheJsonFile( - `${collectionDir}/collection.json`, - ); + const collection = await readJsonFile(`${collectionDir}/collection.json`); return getCollectionInfo( basedir, @@ -97,7 +94,7 @@ async function readWorkspaceGeneratorsCollection( listFiles(collectionDir) .filter((f) => basename(f) === 'schema.json') .map(async (schemaJsonPath) => { - const schemaJson = await readAndCacheJsonFile(schemaJsonPath, ''); + const schemaJson = await readJsonFile(schemaJsonPath, ''); const name = schemaJson.json.id || schemaJson.json.$id; const type: GeneratorType = schemaJson.json['x-type'] ?? GeneratorType.Other; diff --git a/libs/shared/nx-workspace-info/src/lib/read-collections.ts b/libs/shared/nx-workspace-info/src/lib/read-collections.ts index 9d55a73020..86669c646e 100644 --- a/libs/shared/nx-workspace-info/src/lib/read-collections.ts +++ b/libs/shared/nx-workspace-info/src/lib/read-collections.ts @@ -1,7 +1,4 @@ -import { - clearJsonCache, - readAndCacheJsonFile, -} from '@nx-console/shared-file-system'; +import { readJsonFile } from '@nx-console/shared-file-system'; import { packageDetails, workspaceDependencies, @@ -20,7 +17,6 @@ import { nxWorkspace } from './workspace'; import { Logger } from '@nx-console/shared-utils'; export type ReadCollectionsOptions = { - clearPackageJsonCache?: boolean; includeHidden?: boolean; includeNgAdd?: boolean; }; @@ -30,10 +26,6 @@ export async function readCollections( options: ReadCollectionsOptions, logger?: Logger, ): Promise { - if (options?.clearPackageJsonCache) { - clearJsonCache('package.json', workspacePath); - } - const { projectGraph, nxVersion } = await nxWorkspace(workspacePath, logger); const packages = await workspaceDependencies( @@ -93,8 +85,8 @@ async function readCollection( ): Promise { try { const [executorCollections, generatorCollections] = await Promise.all([ - readAndCacheJsonFile(json.executors || json.builders, packagePath), - readAndCacheJsonFile(json.generators || json.schematics, packagePath), + readJsonFile(json.executors || json.builders, packagePath), + readJsonFile(json.generators || json.schematics, packagePath), ]); return getCollectionInfo( @@ -297,10 +289,7 @@ async function resolveDelegatedExecutor( packagePath, } = await packageDetails(dependencyPath); - const collection = await readAndCacheJsonFile( - executors || builders, - packagePath, - ); + const collection = await readJsonFile(executors || builders, packagePath); if (!collection.json?.[executor]) { return null; diff --git a/libs/shared/nx-workspace-info/src/lib/workspace.ts b/libs/shared/nx-workspace-info/src/lib/workspace.ts index 407c64b777..52a7496eb9 100644 --- a/libs/shared/nx-workspace-info/src/lib/workspace.ts +++ b/libs/shared/nx-workspace-info/src/lib/workspace.ts @@ -1,6 +1,6 @@ import { formatError } from '@nx-console/shared-utils'; -import { clearJsonCache, fileExists } from '@nx-console/shared-file-system'; +import { fileExists } from '@nx-console/shared-file-system'; import { Logger } from '@nx-console/shared-utils'; import { NxWorkspace } from '@nx-console/shared-types'; import { join } from 'path'; @@ -28,9 +28,6 @@ let status: Status = Status.not_started; function resetStatus(workspacePath: string) { status = Status.not_started; cachedReplay = new ReplaySubject(); - // Clear out the workspace config path, needed for older nx workspaces - clearJsonCache('workspace.json', workspacePath); - clearJsonCache('nx.json', workspacePath); } export async function nxWorkspace( diff --git a/libs/vscode/typescript-plugin/src/lib/plugin-configuration.spec.ts b/libs/vscode/typescript-plugin/src/lib/plugin-configuration.spec.ts index dabd2e94cb..741ec7156e 100644 --- a/libs/vscode/typescript-plugin/src/lib/plugin-configuration.spec.ts +++ b/libs/vscode/typescript-plugin/src/lib/plugin-configuration.spec.ts @@ -1,7 +1,4 @@ -import { - findConfig, - readAndCacheJsonFile, -} from '@nx-console/shared-file-system'; +import { findConfig, readJsonFile } from '@nx-console/shared-file-system'; import { dirname, join, posix, sep } from 'node:path'; import { getPluginConfiguration, @@ -10,7 +7,7 @@ import { } from './plugin-configuration'; jest.mock('@nx-console/shared-file-system', () => ({ - readAndCacheJsonFile: jest.fn(), + readJsonFile: jest.fn(), listFiles: jest.fn(), findConfig: jest.fn(), })); @@ -29,7 +26,7 @@ describe('getPluginConfiguration', () => { describe('additionalRootFiles', () => { it('should return an empty array if tsconfig.base.json and tsconfig.json do not exist', async () => { - (readAndCacheJsonFile as jest.Mock).mockImplementation(async (file) => { + (readJsonFile as jest.Mock).mockImplementation(async (file) => { if (file === 'tsconfig.base.json') { return { json: {} }; } @@ -48,7 +45,7 @@ describe('getPluginConfiguration', () => { }); it('should return an empty array if compilerOptions is missing in tsconfig.base.json and tsconfig.json', async () => { - (readAndCacheJsonFile as jest.Mock).mockImplementation(async (file) => { + (readJsonFile as jest.Mock).mockImplementation(async (file) => { if (file === 'tsconfig.base.json') { return { json: { someOtherProperty: 'value' } }; } @@ -67,7 +64,7 @@ describe('getPluginConfiguration', () => { }); it('should return additional root files for simple path entries in tsconfig.base.json', async () => { - (readAndCacheJsonFile as jest.Mock).mockImplementation(async (file) => { + (readJsonFile as jest.Mock).mockImplementation(async (file) => { if (file === 'tsconfig.base.json') { return { json: { @@ -102,7 +99,7 @@ describe('getPluginConfiguration', () => { }); it('should return additional root files for simple path entries in tsconfig.json', async () => { - (readAndCacheJsonFile as jest.Mock).mockImplementation((file) => { + (readJsonFile as jest.Mock).mockImplementation((file) => { if (file === 'tsconfig.json') { return { json: { diff --git a/libs/vscode/typescript-plugin/src/lib/plugin-configuration.ts b/libs/vscode/typescript-plugin/src/lib/plugin-configuration.ts index 672706668a..00939eedc8 100644 --- a/libs/vscode/typescript-plugin/src/lib/plugin-configuration.ts +++ b/libs/vscode/typescript-plugin/src/lib/plugin-configuration.ts @@ -1,7 +1,4 @@ -import { - findConfig, - readAndCacheJsonFile, -} from '@nx-console/shared-file-system'; +import { findConfig, readJsonFile } from '@nx-console/shared-file-system'; import { detectPackageManager, getPackageManagerVersion, @@ -35,16 +32,14 @@ export const TSCONFIG_BASE = 'tsconfig.base.json'; async function getAdditionalRootFiles( workspaceRoot: string, ): Promise { - let tsconfig = (await readAndCacheJsonFile(TSCONFIG_BASE, workspaceRoot)) - .json; + let tsconfig = (await readJsonFile(TSCONFIG_BASE, workspaceRoot)).json; if (!tsconfig) { return []; } if (!('compilerOptions' in tsconfig)) { - tsconfig = (await readAndCacheJsonFile('tsconfig.json', workspaceRoot)) - .json; + tsconfig = (await readJsonFile('tsconfig.json', workspaceRoot)).json; if (!tsconfig) { return []; } diff --git a/libs/vscode/typescript-plugin/src/lib/typescript-plugin.ts b/libs/vscode/typescript-plugin/src/lib/typescript-plugin.ts index 53e0008f03..30f530104f 100644 --- a/libs/vscode/typescript-plugin/src/lib/typescript-plugin.ts +++ b/libs/vscode/typescript-plugin/src/lib/typescript-plugin.ts @@ -1,5 +1,4 @@ import { gte } from '@nx-console/nx-version'; -import { clearJsonCache } from '@nx-console/shared-file-system'; import { importWorkspaceDependency, workspaceDependencyPath, @@ -214,7 +213,6 @@ async function enableTypescriptServerPlugin( watchFile( `${workspaceRoot}/tsconfig.base.json`, () => { - clearJsonCache(TSCONFIG_BASE, workspaceRoot); configurePlugin( workspaceRoot, projectGraph, diff --git a/libs/vscode/utils/src/lib/read-projects.ts b/libs/vscode/utils/src/lib/read-projects.ts index 4a227b090f..419641a24d 100644 --- a/libs/vscode/utils/src/lib/read-projects.ts +++ b/libs/vscode/utils/src/lib/read-projects.ts @@ -10,7 +10,7 @@ import type { } from 'nx/src/devkit-exports'; import * as path from 'path'; -import { readAndCacheJsonFile } from '@nx-console/shared-file-system'; +import { readJsonFile } from '@nx-console/shared-file-system'; import { localDependencyPath, workspaceDependencyPath, @@ -22,7 +22,7 @@ import { getOutputChannel } from '@nx-console/vscode-output-channels'; export function readTargetDef( targetName: string, targetsDef: NxTargetConfiguration, - project: string + project: string, ): Targets { const configurations: TargetConfiguration[] = targetsDef.configurations ? Object.keys(targetsDef.configurations).map((name) => ({ @@ -54,7 +54,7 @@ function readDefaultValues(configurations: any, name: string): DefaultValue[] { if (!config) return defaults; return Object.keys(config).reduce( (m, k) => [...m, { name: k, defaultValue: getPrimitiveValue(config[k]) }], - defaults + defaults, ); } @@ -62,7 +62,7 @@ export async function readBuilderSchema( basedir: string, builder: string, projects: Record, - projectDefaults?: { [name: string]: string } + projectDefaults?: { [name: string]: string }, ): Promise { try { const [packageName, builderName] = builder.split(':'); @@ -76,23 +76,23 @@ export async function readBuilderSchema( return undefined; } - const packageJson = await readAndCacheJsonFile( - path.join(packagePath, 'package.json') + const packageJson = await readJsonFile( + path.join(packagePath, 'package.json'), ); const b = packageJson.json.builders || packageJson.json.executors; const buildersPath = b.startsWith('.') ? b : `./${b}`; - const buildersJson = await readAndCacheJsonFile( + const buildersJson = await readJsonFile( buildersPath, - path.dirname(packageJson.path) + path.dirname(packageJson.path), ); const builderDef = { ...buildersJson.json.builders, ...buildersJson.json.executors, }[builderName]; - const builderSchema = await readAndCacheJsonFile( + const builderSchema = await readJsonFile( builderDef.schema, - path.dirname(buildersJson.path) + path.dirname(buildersJson.path), ); return await normalizeSchema(builderSchema.json, projectDefaults);