Skip to content

Commit

Permalink
feat: enhance require-singular-dasherized-resource-name rule with cus…
Browse files Browse the repository at this point in the history
…tomizable normalization options
  • Loading branch information
Baltazore committed Jan 9, 2025
1 parent 2481db8 commit b51ea74
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const { dasherize, singularize } = require('inflection');

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
Expand All @@ -10,10 +8,47 @@ module.exports = {
recommended: true,
url: 'https://github.com/emberjs/data/tree/main/packages/eslint-plugin-warp-drive/docs/require-singular-dasherized-resource-name.md',
},
schema: [],
fixable: 'code',
defaultOptions: [
{
moduleName: 'inflection',
methodNames: ['dasherize', 'singularize'],
},
],
schema: {
type: 'array',
items: [
{
type: 'object',
properties: {
moduleName: { type: 'string' },
methodNames: { type: 'array' },
},
additionalProperties: false,
},
],
},
},

create(context) {
const params = context.options[0] ?? { moduleName: 'inflection', methodNames: ['dasherize', 'singularize'] };
const { moduleName, methodNames } = params;
let normalize;

try {
const module = require(moduleName);
normalize = (value) => {
return methodNames.reduce((acc, methodName) => {
return module[methodName](acc);
}, value);
};
} catch (error) {
context.report({
message: `Failed to load module '${moduleName}' or methods '${methodNames.join(', ')}'`,
});
return {};
}

return {
CallExpression(node) {
const decorator =
Expand All @@ -25,10 +60,7 @@ module.exports = {
// TODO: add support for passing normalize function to rule to test
const resource = args.at(0); // The first argument is the resource name
const resourceName = resource.value;
const normalizedResourceName = dasherize(singularize(resourceName));

console.log({ resourceName, normalizedResourceName });
console.log(resourceName === normalizedResourceName, 'true');
const normalizedResourceName = normalize(resourceName);

if (resourceName !== normalizedResourceName) {
context.report({
Expand All @@ -37,6 +69,9 @@ module.exports = {
data: {
decorator: decorator.callee.name,
},
fix(fixer) {
return fixer.replaceText(resource, `'${normalizedResourceName}'`);
},
});
return;
}
Expand Down
11 changes: 11 additions & 0 deletions packages/eslint-plugin-warp-drive/tests/normalizer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Super naive normalizer for testing purposes
module.exports = {
normalize: function (value) {
return value
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/_/g, '-')
.replace(/s$/, '')
.toLowerCase();
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ ruleTester.run('require-singular-dasherized-resource-name', rule, {
@belongsTo('Posts', { async: true, inverse: 'post-comments' }) post;
}
`,
output: null,
output: `
import Model, { belongsTo } from '@ember-data/model';
export default class extends Model {
@belongsTo('Post', { async: true, inverse: 'post-comments' }) post;
}
`,
errors: [
{
message:
Expand All @@ -61,7 +66,12 @@ ruleTester.run('require-singular-dasherized-resource-name', rule, {
@hasMany('user_settings', { inverse: 'user' }) userSettings;
}
`,
output: null,
output: `
import Model, { hasMany } from '@ember-data/model';
export default class User extends Model {
@hasMany('user-setting', { inverse: 'user' }) userSettings;
}
`,
errors: [
{
message:
Expand All @@ -70,5 +80,27 @@ ruleTester.run('require-singular-dasherized-resource-name', rule, {
},
],
},
{
code: `
import Model, { hasMany } from '@ember-data/model';
export default class User extends Model {
@hasMany('UserSettings', { inverse: 'user' }) userSettings;
}
`,
output: `
import Model, { hasMany } from '@ember-data/model';
export default class User extends Model {
@hasMany('user-setting', { inverse: 'user' }) userSettings;
}
`,
options: [{ moduleName: require.resolve('./normalizer.js'), methodNames: ['normalize'] }],
errors: [
{
message:
"The @hasMany decorator resource name should be singular and dasherized (user-setting), but found 'UserSettings'.",
type: 'CallExpression',
},
],
},
],
});

0 comments on commit b51ea74

Please sign in to comment.