refactor(read-manifest): improve type safety of manifest validation logic (#7345)

* refactor(read-manifest): move packages field validation logic

* refactor(read-manifest): remove explicit any in validation logic

* refactor(read-manifest): change validateWorkspaceManifest to assert

* refactor(read-manifest): add final WorkspaceManifest assignability check

* chore: add changeset for read-manifest improvements
This commit is contained in:
Brandon Cheng
2023-11-27 19:06:22 -05:00
committed by GitHub
parent 633c0d6f8f
commit e8926e9207
2 changed files with 23 additions and 11 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/workspace.read-manifest": patch
---
Minor refactors to improve the type safety of the workspace manifest validation logic in the `readWorkspaceManifest` function.

View File

@@ -9,11 +9,8 @@ export interface WorkspaceManifest {
export async function readWorkspaceManifest (dir: string): Promise<WorkspaceManifest | undefined> {
const manifest = await readManifestRaw(dir)
if (validateWorkspaceManifest(manifest)) {
return manifest
}
return undefined
validateWorkspaceManifest(manifest)
return manifest
}
async function readManifestRaw (dir: string): Promise<unknown> {
@@ -30,11 +27,10 @@ async function readManifestRaw (dir: string): Promise<unknown> {
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function validateWorkspaceManifest (manifest: any): manifest is WorkspaceManifest | undefined {
function validateWorkspaceManifest (manifest: unknown): asserts manifest is WorkspaceManifest | undefined {
if (manifest === undefined || manifest === null) {
// Empty or null manifest is ok
return true
return
}
if (typeof manifest !== 'object') {
@@ -47,9 +43,14 @@ function validateWorkspaceManifest (manifest: any): manifest is WorkspaceManifes
if (Object.keys(manifest).length === 0) {
// manifest content `{}` is ok
return true
return
}
assertValidWorkspaceManifestPackages(manifest)
checkWorkspaceManifestAssignability(manifest)
}
function assertValidWorkspaceManifestPackages (manifest: { packages?: unknown }): asserts manifest is { packages: string[] } {
if (!manifest.packages) {
throw new InvalidWorkspaceManifestError('packages field missing or empty')
}
@@ -68,10 +69,16 @@ function validateWorkspaceManifest (manifest: any): manifest is WorkspaceManifes
throw new InvalidWorkspaceManifestError(`Invalid package type - ${type}`)
}
}
return true
}
/**
* Empty function to ensure TypeScript has narrowed the manifest object to
* something assignable to the {@see WorkspaceManifest} interface. This helps
* make sure the validation logic in this file is correct as it's refactored in
* the future.
*/
function checkWorkspaceManifestAssignability (_manifest: WorkspaceManifest) {}
class InvalidWorkspaceManifestError extends PnpmError {
constructor (message: string) {
super('INVALID_WORKSPACE_CONFIGURATION', message)