Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 48 additions & 51 deletions scripts/updateProjectReferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ import { getWorkspacesList } from './utils/getWorkspacesList';
}
};

const parseTSConfigFile = (configPath: string) => {
try {
return fs.existsSync(configPath)
? JSON.parse(fs.readFileSync(configPath).toString())
: null;
} catch {
console.error(chalk.bold.red('Error while parsing file: '), configPath);
process.exit(1);
}
};

const isDiffInConfig = async (actualConfig: any[] = [], expectedConfig: any[] = []) =>
(await serializeConfig(actualConfig)) !== (await serializeConfig(expectedConfig));

const workspaces = getWorkspacesList();

// NOTE: Workspace keys must be sorted due to file systems being a part of the equation...
Expand All @@ -54,26 +68,25 @@ import { getWorkspacesList } from './utils/getWorkspacesList';

const workspacePath = path.resolve(process.cwd(), workspace.location);
const workspaceConfigPath = path.resolve(workspacePath, 'tsconfig.json');
const workspaceLibConfigPath = path.resolve(workspacePath, 'tsconfig.lib.json');

// actual references of the workspace = typings from argv + parsed package.json (assigned later)
const nextWorkspaceReferences = typingPaths.map((typingPath: string) => ({
path: path.relative(workspacePath, path.resolve(process.cwd(), typingPath)),
}));

const defaultWorkspaceConfig = {
extends: path.relative(workspacePath, path.resolve(process.cwd(), 'tsconfig.json')),
compilerOptions: { outDir: './libDev' },
include: ['.'],
};

let workspaceConfig;
try {
workspaceConfig = fs.existsSync(workspaceConfigPath)
? JSON.parse(fs.readFileSync(workspaceConfigPath).toString())
: defaultWorkspaceConfig;
} catch {
console.error(chalk.bold.red('Error while parsing file: '), workspaceConfigPath);
process.exit(1);
}
// parse tsconfig.json, which should exist, so if it doesn't, assign default config to have it created
const workspaceConfig =
parseTSConfigFile(workspaceConfigPath) ?? defaultWorkspaceConfig;

const nextWorkspaceReferences = typingPaths.map((typingPath: string) => ({
path: path.relative(workspacePath, path.resolve(process.cwd(), typingPath)),
}));
// parse tsconfig.lib.json, which may not exist, and shall not be created
const workspaceLibConfig = parseTSConfigFile(workspaceLibConfigPath);

Object.values(workspace.workspaceDependencies).forEach(dependencyLocation => {
const dependencyPath = path.resolve(process.cwd(), dependencyLocation);
Expand All @@ -90,59 +103,43 @@ import { getWorkspacesList } from './utils/getWorkspacesList';
}
});

const expectedReferences = nextWorkspaceReferences;
const expectedLibReferences = nextWorkspaceReferences.filter(
// Don't include reference to schema-utils due to issues with the @sinclair/typebox library
// When using a reference it results in incorrect imports
({ path }) => path !== '../schema-utils',
);

if (isTesting) {
if (
(await serializeConfig(workspaceConfig.references ?? [])) !==
(await serializeConfig(nextWorkspaceReferences))
) {
const isConfigDiff = await isDiffInConfig(
workspaceConfig.references,
expectedReferences,
);

const isConfigLibDiff =
workspaceLibConfig !== null &&
(await isDiffInConfig(workspaceLibConfig.references, expectedLibReferences));

if (isConfigDiff || isConfigLibDiff) {
console.error(
chalk.red(
`TypeScript project references in ${workspace.location} are inconsistent with package.json#dependencies.`,
),
chalk.red.bold(`Run "yarn update-project-references" to fix them.`),
);

process.exit(1);
}

return;
}

workspaceConfig.references = nextWorkspaceReferences;
if (readOnlyGlobs.some((path: string) => minimatch(workspace.location, path))) return;

if (!readOnlyGlobs.some((path: string) => minimatch(workspace.location, path))) {
fs.writeFileSync(workspaceConfigPath, await serializeConfig(workspaceConfig));
}

// Copy references also to tsconfig.lib.json if exists
const workspaceLibConfigPath = path.resolve(workspacePath, 'tsconfig.lib.json');
if (fs.existsSync(workspaceLibConfigPath)) {
try {
const workspaceLibConfig = JSON.parse(
fs.readFileSync(workspaceLibConfigPath).toString(),
);
workspaceConfig.references = expectedReferences;
fs.writeFileSync(workspaceConfigPath, await serializeConfig(workspaceConfig));

workspaceLibConfig.references = nextWorkspaceReferences.filter(
// Don't include reference to schema-utils due to issues with the @sinclair/typebox library
// When using a reference it results in incorrect imports
({ path }) => path !== '../schema-utils',
);

if (
!readOnlyGlobs.some((path: string) => minimatch(workspace.location, path))
) {
fs.writeFileSync(
workspaceLibConfigPath,
await serializeConfig(workspaceLibConfig, 2),
);
}
} catch {
console.error(
chalk.bold.red('Error while parsing file: '),
workspaceLibConfigPath,
);
process.exit(1);
}
}
if (workspaceLibConfig === null) return;
workspaceLibConfig.references = expectedLibReferences;
fs.writeFileSync(workspaceLibConfigPath, await serializeConfig(workspaceLibConfig, 2));
});
})();