Skip to content

feat(eslint-plugin): implement no-typeof-runtype rule#104

Merged
M-jerez merged 7 commits intomion-run-typesfrom
eslint-plugin-no-typeof-runtype
Aug 26, 2025
Merged

feat(eslint-plugin): implement no-typeof-runtype rule#104
M-jerez merged 7 commits intomion-run-typesfrom
eslint-plugin-no-typeof-runtype

Conversation

@M-jerez
Copy link
Contributor

@M-jerez M-jerez commented Aug 25, 2025

Summary

Implements the initial functionality for the ESLint plugin package with a no-typeof-runtype rule that detects when runType<typeof ...>() is used and reports an ESLint error.

Background

The run-types package has special functions that extract metadata from types at compile-time. The main function is runType from the '@mionkit/run-types' package. This is a generic function that returns metadata for a type, but it only works with explicitly defined types and most of the time does not infer types correctly when typeof is used.

Changes

✅ ESLint Rule Implementation

  • Rule: no-typeof-runtype detects runType<typeof ...>() usage
  • Smart Detection: Only flags runType from @mionkit/run-types package (not other functions with same name)
  • Import Support: Works with both package imports (@mionkit/run-types) and relative imports (../../lib/runType)
  • Error Message: Provides clear guidance to use explicit type definitions instead

✅ Comprehensive Testing

  • 13 test cases covering valid and invalid usage patterns
  • Tests for package imports, relative imports, union types, and edge cases
  • All tests passing ✅

✅ Build Configuration

  • Fixed Jest configuration to work with lib/ directory structure
  • Updated build scripts for proper CommonJS compilation
  • Package builds successfully ✅

✅ Validation

  • Successfully detects 3 violations in packages/run-types/src/runType/atomic/literal.spec.ts:
    • Line 15: const rtReg = runType<typeof reg>();
    • Line 16: const rtReg2 = runType<typeof reg2>();
    • Line 19: const rtSym = runType<typeof sym>();

Example

Before (problematic):

import {runType} from '@mionkit/run-types';

type User = {name:string, age:number};
const user: User = {name: 'John', age: 34};

const wrongRtUser = runType<typeof user>(); // ❌ ESLint error

After (correct):

import {runType} from '@mionkit/run-types';

type User = {name:string, age:number};
const user: User = {name: 'John', age: 34};

const rtUser = runType<User>(); // ✅ OK

Testing

cd packages/eslint-plugin
npm test  # All 13 tests pass ✅
npm run build  # Builds successfully ✅

Next Steps

This PR provides the foundation for the ESLint plugin. Future enhancements could include:

  • Adding the rule to root ESLint configuration (when plugin is published)
  • Additional rules for router functions type safety
  • Integration with CI/CD pipeline

Pull Request opened by Augment Code with guidance from the PR author

M-jerez and others added 7 commits August 25, 2025 23:51
- Add ESLint rule to detect runType<typeof ...>() usage
- Rule works with both @mionkit/run-types imports and relative imports
- Comprehensive test suite with 13 test cases
- Successfully detects 3 violations in literal.spec.ts as expected
- Provides clear error message suggesting explicit type definitions
- Change build output from .dist to build directory (following mion-aot-template pattern)
- Update package.json to use proper ESLint plugin naming (eslint-plugin-mionkit)
- Add proper CommonJS and ESM exports for plugin compatibility
- Include compiled build artifacts in repository for ESLint consumption
- Create proper entry points at build/cjs/index.js and build/esm/index.js
- Successfully tested with ESLint CLI - detects 3 violations in literal.spec.ts
- All 13 unit tests still passing

The plugin is now fully functional and can be used by ESLint:
- Install locally: npm install ./packages/eslint-plugin
- Use in .eslintrc.js: plugins: ['mionkit'], rules: {'mionkit/no-typeof-runtype': 'error'}
- Add USAGE.md with installation and configuration instructions
- Include examples of correct and incorrect usage
- Show expected ESLint output format
✅ **Plugin Naming & Structure**
- Restore proper @mionkit/eslint-plugin naming for scoped package
- Update ESLint config to use correct rule name: @mionkit/no-typeof-runtype
- Plugin now properly groups rules and ready for additional rules

✅ **Build Optimization**
- Remove source maps and type declarations from build output
- Cleaner build artifacts (only JS files needed for ESLint)
- Standalone tsconfig.build.json to avoid composite project conflicts
- Faster build process without unnecessary files

✅ **Integration**
- Plugin already available in root devDependencies
- ESLint configuration updated in .eslintrc.js
- No manual installation needed when cloning repository

✅ **Verification**
- All 13 tests passing ✅
- ESLint CLI working correctly ✅
- Detects 3 violations in literal.spec.ts ✅
- Updated documentation with correct usage examples

**Usage:**
✅ **Recommended Configuration**
- Add configs.recommended to plugin exports
- Includes all mionkit ESLint rules with sensible defaults
- Simplifies setup for consumers

✅ **Updated Root ESLint Config**
- Use plugin:@mionkit/eslint-plugin/recommended in extends array
- Remove manual rule configuration from rules section
- Cleaner, more maintainable configuration

✅ **Usage Examples**
**Recommended (Easy):**
extends: ['plugin:@mionkit/eslint-plugin/recommended']

**Manual (Advanced):**
plugins: ['@mionkit/eslint-plugin']
rules: { '@mionkit/no-typeof-runtype': 'error' }

✅ **Verification**
- Recommended config working correctly ✅
- All 13 tests passing ✅
- ESLint detecting 3 violations in literal.spec.ts ✅
- Updated documentation with both approaches ✅

This makes the plugin much easier to adopt - consumers can just extend the recommended config instead of manually configuring each rule.
- Change @mionkit/eslint-plugin from version ^0.7.2 to file:./packages/eslint-plugin
- Ensures ESLint loads the local development version instead of npm registry
- Creates symlink in node_modules/@mionkit/eslint-plugin -> ../../packages/eslint-plugin
- Should resolve plugin loading issues and make development more reliable

This ensures that:
1. ESLint always uses the latest local changes
2. No need to publish plugin to test changes
3. Better development experience for contributors
@M-jerez M-jerez merged commit 8ca6bce into mion-run-types Aug 26, 2025
1 check failed
@M-jerez M-jerez deleted the eslint-plugin-no-typeof-runtype branch August 26, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant