56bd21de6f
For the last years the Angular repositories relied on `ts-api-guardian` for testing the public API signature. This project worked well in general but its another inconvenience to maintain if we could rely on Microsoft's `api-extractor` tool. Especially since with TypeScript 4.3 issues with export aliases appeared that would require us to extend TS API guardian to support such exports. This is not as straightforward as it sounds, given it requires rewriting of declarations to show-case the proper name in the API golden. Microsoft's API extractor has integrated support for this. As of TypeScript 4.3, we want to start using the new `override` keyword. We are not able to use that keyword currently because an old version of API extractor is used in the `ng_module` rule to flatten the types into a single file. To fix this, we need to update `api-extractor`, but this unveils the issue with TS API guardian because the most recent version of api-extractor uses alias exports to avoid potential conflicts with globals available through the TypeScript default libraries (e.g. `dom.d.ts`). PR Close #42688
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {lstatSync, readdirSync, readFileSync} from 'fs';
|
|
import {dirname, join} from 'path';
|
|
|
|
/** Interface describing a resolved NPM package entry point. */
|
|
export interface PackageEntryPoint {
|
|
typesEntryPointPath: string;
|
|
packageJsonPath: string;
|
|
}
|
|
|
|
/** Interface describing contents of a `package.json`. */
|
|
interface PackageJson {
|
|
types?: string;
|
|
typings?: string;
|
|
}
|
|
|
|
/** Finds all entry points within a given NPM package directory. */
|
|
export function findEntryPointsWithinNpmPackage(dirPath: string): PackageEntryPoint[] {
|
|
const entryPoints: PackageEntryPoint[] = [];
|
|
|
|
for (const packageJsonFilePath of findPackageJsonFilesInDirectory(dirPath)) {
|
|
const packageJson = JSON.parse(readFileSync(packageJsonFilePath, 'utf8')) as PackageJson;
|
|
const typesFile = packageJson.types || packageJson.typings;
|
|
|
|
if (typesFile) {
|
|
entryPoints.push({
|
|
packageJsonPath: packageJsonFilePath,
|
|
typesEntryPointPath: join(dirname(packageJsonFilePath), typesFile),
|
|
});
|
|
}
|
|
}
|
|
|
|
return entryPoints;
|
|
}
|
|
|
|
/** Determine if the provided path is a directory. */
|
|
function isDirectory(dirPath: string) {
|
|
try {
|
|
return lstatSync(dirPath).isDirectory();
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Finds all `package.json` files within a directory. */
|
|
function* findPackageJsonFilesInDirectory(directoryPath: string): IterableIterator<string> {
|
|
for (const fileName of readdirSync(directoryPath)) {
|
|
const fullPath = join(directoryPath, fileName);
|
|
if (isDirectory(fullPath)) {
|
|
yield* findPackageJsonFilesInDirectory(fullPath);
|
|
} else if (fileName === 'package.json') {
|
|
yield fullPath;
|
|
}
|
|
}
|
|
}
|