Skip to content

refactor: add type safety to package.json reading in utils.ts #54

@gsong

Description

@gsong

Summary

The getPackageVersion() function in src/utils.ts:5-10 uses JSON.parse() with an implicit any type, reducing type safety and potentially allowing runtime errors to go undetected.

Current State

The current implementation lacks type safety:

export function getPackageVersion(): string {
  const __dirname = dirname(fileURLToPath(import.meta.url));
  const packageJson = JSON.parse(
    readFileSync(join(__dirname, "../package.json"), "utf8"),
  );
  return packageJson.version;
}

Issues:

  • JSON.parse() returns any, bypassing TypeScript's type checking
  • No validation that version field exists or is a string
  • Could silently return undefined if package.json structure is unexpected

Security & Reliability Concern

Reading JSON without validation could cause issues if:

  • The package.json file is corrupted or malformed
  • The version field is missing or has an unexpected type
  • Future modifications to the file structure break assumptions

While this is unlikely in normal circumstances, adding validation improves robustness and provides clearer error messages during development or build issues.

Proposed Solution

Add a simple interface with runtime validation:

interface PackageJson {
  version: string;
}

export function getPackageVersion(): string {
  const __dirname = dirname(fileURLToPath(import.meta.url));
  const packageJson = JSON.parse(
    readFileSync(join(__dirname, "../package.json"), "utf8"),
  ) as PackageJson;
  
  if (!packageJson.version || typeof packageJson.version !== 'string') {
    throw new Error('Invalid package.json: missing or invalid version field');
  }
  
  return packageJson.version;
}

Benefits

  • Type Safety: Explicit type annotation makes code intent clear
  • Runtime Validation: Catches malformed package.json early with descriptive errors
  • Better Error Messages: Developers get clear feedback instead of mysterious undefined behavior
  • Maintainability: Future developers understand expected structure at a glance

Implementation Notes

  • This is a localized change requiring minimal testing
  • Consider using a more comprehensive validation library like zod if package.json reading becomes more complex
  • The interface can be extended if other package.json fields are needed in the future

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions