You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8.4 KiB
8.4 KiB
ESLint Rules for PlatformServiceMixin Migration
Overview
Custom ESLint rules to enforce PlatformServiceMixin patterns and prevent regression to legacy patterns.
Rules Configuration
Add to .eslintrc.js
:
module.exports = {
// ... existing config
rules: {
// ... existing rules
// Custom rules for PlatformServiceMixin migration
'timesafari/no-direct-database-util': 'error',
'timesafari/no-legacy-logging': 'error',
'timesafari/require-mixin-for-database': 'error',
'timesafari/no-direct-platform-service': 'warn',
'timesafari/prefer-mixin-methods': 'warn',
},
// Custom rules plugin
plugins: ['timesafari'],
}
Custom Rules Implementation
Create eslint-plugin-timesafari/index.js
:
module.exports = {
rules: {
'no-direct-database-util': {
meta: {
type: 'problem',
docs: {
description: 'Disallow direct imports from databaseUtil',
category: 'Migration',
recommended: true,
},
schema: [],
},
create(context) {
return {
ImportDeclaration(node) {
if (node.source.value.includes('databaseUtil')) {
context.report({
node,
message: 'Direct databaseUtil imports are deprecated. Use PlatformServiceMixin instead.',
});
}
},
};
},
},
'no-legacy-logging': {
meta: {
type: 'problem',
docs: {
description: 'Disallow legacy logging methods',
category: 'Migration',
recommended: true,
},
schema: [],
},
create(context) {
return {
ImportDeclaration(node) {
if (node.specifiers.some(spec => spec.imported?.name === 'logConsoleAndDb')) {
context.report({
node,
message: 'logConsoleAndDb is deprecated. Use PlatformServiceMixin $log methods instead.',
});
}
},
CallExpression(node) {
if (node.callee.name === 'logConsoleAndDb') {
context.report({
node,
message: 'logConsoleAndDb is deprecated. Use this.$logAndConsole() instead.',
});
}
},
};
},
},
'require-mixin-for-database': {
meta: {
type: 'suggestion',
docs: {
description: 'Require PlatformServiceMixin for components using database operations',
category: 'Migration',
recommended: true,
},
schema: [],
},
create(context) {
let hasDbOperations = false;
let hasMixin = false;
return {
CallExpression(node) {
// Check for database operations
if (node.callee.property &&
['dbQuery', 'dbExec', 'dbGetOneRow'].includes(node.callee.property.name)) {
hasDbOperations = true;
}
},
Property(node) {
// Check for mixin usage
if (node.key.name === 'mixins' &&
node.value.elements?.some(el => el.name === 'PlatformServiceMixin')) {
hasMixin = true;
}
},
'Program:exit'() {
if (hasDbOperations && !hasMixin) {
context.report({
node: context.getSourceCode().ast,
message: 'Components using database operations should include PlatformServiceMixin.',
});
}
},
};
},
},
'no-direct-platform-service': {
meta: {
type: 'suggestion',
docs: {
description: 'Discourage direct PlatformServiceFactory usage',
category: 'Migration',
recommended: false,
},
schema: [],
},
create(context) {
return {
CallExpression(node) {
if (node.callee.object?.name === 'PlatformServiceFactory' &&
node.callee.property?.name === 'getInstance') {
context.report({
node,
message: 'Consider using PlatformServiceMixin methods instead of direct PlatformServiceFactory.',
});
}
},
};
},
},
'prefer-mixin-methods': {
meta: {
type: 'suggestion',
docs: {
description: 'Prefer mixin convenience methods over direct database calls',
category: 'Migration',
recommended: false,
},
schema: [],
},
create(context) {
return {
CallExpression(node) {
// Check for patterns that could use mixin methods
if (node.callee.property?.name === 'dbQuery') {
const arg = node.arguments[0];
if (arg && arg.type === 'Literal') {
const sql = arg.value.toLowerCase();
if (sql.includes('select * from contacts')) {
context.report({
node,
message: 'Consider using this.$getAllContacts() instead of direct SQL.',
});
}
if (sql.includes('select * from settings')) {
context.report({
node,
message: 'Consider using this.$settings() instead of direct SQL.',
});
}
}
}
},
};
},
},
},
};
Pre-commit Hook
Create .pre-commit-config.yaml
:
repos:
- repo: local
hooks:
- id: eslint-migration-check
name: ESLint Migration Check
entry: npx eslint --ext .vue --rule 'timesafari/no-direct-database-util: error'
language: system
files: \.vue$
- id: no-legacy-logging
name: No Legacy Logging
entry: bash -c 'if grep -r "logConsoleAndDb" src/ --include="*.vue" --include="*.ts"; then echo "Found legacy logging imports"; exit 1; fi'
language: system
pass_filenames: false
Migration Validation Script
Create scripts/validate-migration.sh
:
#!/bin/bash
echo "🔍 Validating PlatformServiceMixin migration..."
# Check for legacy patterns
echo "Checking for legacy databaseUtil imports..."
LEGACY_DB_IMPORTS=$(grep -r "import.*databaseUtil" src/ --include="*.vue" --include="*.ts" | wc -l)
echo "Found $LEGACY_DB_IMPORTS legacy databaseUtil imports"
echo "Checking for legacy logging imports..."
LEGACY_LOG_IMPORTS=$(grep -r "logConsoleAndDb" src/ --include="*.vue" --include="*.ts" | wc -l)
echo "Found $LEGACY_LOG_IMPORTS legacy logging imports"
# Check for mixin usage
echo "Checking for PlatformServiceMixin usage..."
MIXIN_USAGE=$(grep -r "PlatformServiceMixin" src/ --include="*.vue" | wc -l)
echo "Found $MIXIN_USAGE files using PlatformServiceMixin"
# Check for direct PlatformService usage
echo "Checking for direct PlatformService usage..."
DIRECT_PLATFORM=$(grep -r "PlatformServiceFactory.getInstance" src/ --include="*.vue" --include="*.ts" | wc -l)
echo "Found $DIRECT_PLATFORM direct PlatformService usages"
# Summary
echo ""
echo "📊 Migration Status Summary:"
echo "- Legacy databaseUtil imports: $LEGACY_DB_IMPORTS (should be 0)"
echo "- Legacy logging imports: $LEGACY_LOG_IMPORTS (should be 0)"
echo "- Mixin usage: $MIXIN_USAGE (should be high)"
echo "- Direct PlatformService usage: $DIRECT_PLATFORM (should be low)"
# Set exit code based on legacy usage
if [ $LEGACY_DB_IMPORTS -gt 0 ] || [ $LEGACY_LOG_IMPORTS -gt 0 ]; then
echo "❌ Migration validation failed - legacy patterns found"
exit 1
else
echo "✅ Migration validation passed - no legacy patterns found"
exit 0
fi
Usage
-
Install ESLint rules:
npm install --save-dev eslint-plugin-timesafari
-
Run validation:
npm run lint ./scripts/validate-migration.sh
-
Fix issues automatically:
npm run lint -- --fix
IDE Integration
VS Code Settings
Add to .vscode/settings.json
:
{
"eslint.validate": [
"javascript",
"typescript",
"vue"
],
"eslint.options": {
"extensions": [".js", ".ts", ".vue"]
}
}
WebStorm Settings
- Go to Settings → Languages & Frameworks → JavaScript → Code Quality Tools → ESLint
- Enable ESLint
- Set configuration file to
.eslintrc.js
- Add
.vue
to file extensions