mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-11 02:29:48 -04:00
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:
5
.changeset/six-fireants-count.md
Normal file
5
.changeset/six-fireants-count.md
Normal 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.
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user