in src/project-info.ts [147:278]
export function loadProjectInfo(projectRoot: string): ProjectInfoResult {
const packageJsonPath = path.join(projectRoot, 'package.json');
const pkg: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const diagnostics: ts.Diagnostic[] = [];
let bundleDependencies: { [name: string]: string } | undefined;
for (const name of pkg.bundleDependencies ?? pkg.bundledDependencies ?? []) {
const version = pkg.dependencies?.[name];
if (!version) {
throw new JsiiError(
`The "package.json" file has "${name}" in "bundleDependencies", but it is not declared in "dependencies"`,
);
}
if (pkg.peerDependencies && name in pkg.peerDependencies) {
throw new JsiiError(
`The "package.json" file has "${name}" in "bundleDependencies", and also in "peerDependencies"`,
);
}
bundleDependencies = bundleDependencies ?? {};
bundleDependencies[name] = _resolveVersion(version, projectRoot).version;
}
// Check peerDependencies are also in devDependencies
// You need this to write tests properly. There are probably cases where
// it makes sense to have this different, so most of what this checking
// produces is warnings, not errors.
const devDependencies = pkg.devDependencies ?? {};
for (const [name, rng] of Object.entries(pkg.peerDependencies ?? {})) {
const range = new semver.Range(_resolveVersion(rng as string, projectRoot).version);
const minVersion = semver.minVersion(range)?.raw;
if (!(name in devDependencies) || devDependencies[name] !== `${minVersion}`) {
diagnostics.push(
JsiiDiagnostic.JSII_0006_MISSING_DEV_DEPENDENCY.createDetached(
name,
`${rng as any}`,
`${minVersion}`,
`${devDependencies[name]}`,
),
);
continue;
}
}
const bundled = new Set(Object.keys(bundleDependencies ?? {}));
const dependencies: Record<string, string> = filterDictByKey(
pkg.dependencies ?? {},
(depName) => !bundled.has(depName),
);
const peerDependencies: Record<string, string> = pkg.peerDependencies ?? {};
const resolver = new DependencyResolver();
const resolved = resolver.discoverDependencyTree(projectRoot, {
...dependencies,
...peerDependencies,
});
const transitiveDependencies = resolver.assemblyClosure(resolved);
const metadata = mergeMetadata(
{
jsii: {
pacmak: {
// When `true`, `jsii-pacmak` will use the `Jsii$Default` implementation in code generation even for dependencies.
hasDefaultInterfaces: true,
},
},
},
pkg.jsii?.metadata,
);
const projectInfo: ProjectInfo = {
projectRoot,
packageJson: pkg,
name: _required(pkg.name, 'The "package.json" file must specify the "name" attribute'),
version: _required(pkg.version, 'The "package.json" file must specify the "version" attribute'),
deprecated: pkg.deprecated,
stability: _validateStability(pkg.stability, pkg.deprecated),
author: _toPerson(_required(pkg.author, 'The "package.json" file must specify the "author" attribute'), 'author'),
repository: _toRepository(
_required(pkg.repository, 'The "package.json" file must specify the "repository" attribute'),
),
license: _validateLicense(pkg.license),
keywords: pkg.keywords,
main: _required(pkg.main, 'The "package.json" file must specify the "main" attribute'),
types: _required(pkg.types, 'The "package.json" file must specify the "types" attribute'),
dependencies,
peerDependencies,
dependencyClosure: transitiveDependencies,
bundleDependencies,
targets: {
..._required(pkg.jsii, 'The "package.json" file must specify the "jsii" attribute').targets,
js: { npm: pkg.name },
},
metadata,
jsiiVersionFormat: _validateVersionFormat(pkg.jsii?.versionFormat ?? 'full'),
description: pkg.description,
homepage: pkg.homepage,
contributors: (pkg.contributors as any[])?.map((contrib, index) =>
_toPerson(contrib, `contributors[${index}]`, 'contributor'),
),
excludeTypescript: pkg.jsii?.excludeTypescript ?? [],
projectReferences: pkg.jsii?.projectReferences,
tsc: {
outDir: pkg.jsii?.tsc?.outDir,
rootDir: pkg.jsii?.tsc?.rootDir,
baseUrl: pkg.jsii?.tsc?.baseUrl,
paths: pkg.jsii?.tsc?.paths,
forceConsistentCasingInFileNames: pkg.jsii?.tsc?.forceConsistentCasingInFileNames,
noImplicitOverride: pkg.jsii?.tsc?.noImplicitOverride,
noPropertyAccessFromIndexSignature: pkg.jsii?.tsc?.noPropertyAccessFromIndexSignature,
noUncheckedIndexedAccess: pkg.jsii?.tsc?.noUncheckedIndexedAccess,
..._sourceMapPreferences(pkg.jsii?.tsc),
types: pkg.jsii?.tsc?.types,
},
bin: pkg.bin,
exports: pkg.exports,
diagnostics: _loadDiagnostics(pkg.jsii?.diagnostics),
// user-provided tsconfig
tsconfig: pkg.jsii?.tsconfig,
validateTsconfig: _validateTsconfigRuleSet(pkg.jsii?.validateTsconfig ?? 'strict'),
};
return { projectInfo, diagnostics };
}