eslint-plugin-conventions 5.3.5 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -138,6 +138,7 @@ Part of the **Interlace ESLint ecosystem** — AI-native rules with LLM-optimize
|
|
|
138
138
|
| [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | [](https://www.npmjs.com/package/eslint-plugin-secure-coding) | Injection prevention. |
|
|
139
139
|
| [`eslint-plugin-sequelize-security`](https://www.npmjs.com/package/eslint-plugin-sequelize-security) | [](https://www.npmjs.com/package/eslint-plugin-sequelize-security) | Sequelize ORM security. |
|
|
140
140
|
| [`eslint-plugin-sqlite-security`](https://www.npmjs.com/package/eslint-plugin-sqlite-security) | [](https://www.npmjs.com/package/eslint-plugin-sqlite-security) | SQLite security. |
|
|
141
|
+
| [`eslint-plugin-supabase-security`](https://www.npmjs.com/package/eslint-plugin-supabase-security) | [](https://www.npmjs.com/package/eslint-plugin-supabase-security) | Supabase security. |
|
|
141
142
|
| [`eslint-plugin-typeorm-security`](https://www.npmjs.com/package/eslint-plugin-typeorm-security) | [](https://www.npmjs.com/package/eslint-plugin-typeorm-security) | TypeORM security. |
|
|
142
143
|
| [`eslint-plugin-vercel-ai-security`](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | [](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | AI SDK security. |
|
|
143
144
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-conventions",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "ESLint plugin for team code conventions — enforces filename case, magic-number bans, commented-out code, expiring TODOs, and deprecated-API usage.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.rules={get"no-commented-code"(){return require("./rules/conventions/no-commented-code").noCommentedCode},get"expiring-todo-comments"(){return require("./rules/conventions/expiring-todo-comments").expiringTodoComments},get"prefer-code-point"(){return require("./rules/conventions/prefer-code-point").preferCodePoint},get"prefer-dom-node-text-content"(){return require("./rules/conventions/prefer-dom-node-text-content").preferDomNodeTextContent},get"no-console-spaces"(){return require("./rules/conventions/no-console-spaces").noConsoleSpaces},get"no-deprecated-api"(){return require("./rules/deprecation/no-deprecated-api").noDeprecatedApi},get"prefer-dependency-version-strategy"(){return require("./rules/conventions/prefer-dependency-version-strategy").preferDependencyVersionStrategy},get"filename-case"(){return require("./rules/conventions/filename-case").filenameCase},get"consistent-existence-index-check"(){return require("./rules/conventions/consistent-existence-index-check").consistentExistenceIndexCheck},get"no-json-schema-tags"(){return require("./rules/conventions/no-json-schema-tags").noJsonSchemaTags},get"require-data-testid"(){return require("./rules/conventions/require-data-testid").requireDataTestId},get"utm-taxonomy"(){return require("./rules/conventions/utm-taxonomy").utmTaxonomy},get"no-raw-cross-property-href"(){return require("./rules/conventions/no-raw-cross-property-href").noRawCrossPropertyHref},get"analytics-event-naming"(){return require("./rules/conventions/analytics-event-naming").analyticsEventNaming},get"no-magic-numbers"(){return require("./rules/conventions/no-magic-numbers").noMagicNumbers}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-conventions",exports.rules);exports.plugin={meta:{name:"eslint-plugin-conventions",version:"
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.rules={get"no-commented-code"(){return require("./rules/conventions/no-commented-code").noCommentedCode},get"expiring-todo-comments"(){return require("./rules/conventions/expiring-todo-comments").expiringTodoComments},get"prefer-code-point"(){return require("./rules/conventions/prefer-code-point").preferCodePoint},get"prefer-dom-node-text-content"(){return require("./rules/conventions/prefer-dom-node-text-content").preferDomNodeTextContent},get"no-console-spaces"(){return require("./rules/conventions/no-console-spaces").noConsoleSpaces},get"no-deprecated-api"(){return require("./rules/deprecation/no-deprecated-api").noDeprecatedApi},get"prefer-dependency-version-strategy"(){return require("./rules/conventions/prefer-dependency-version-strategy").preferDependencyVersionStrategy},get"filename-case"(){return require("./rules/conventions/filename-case").filenameCase},get"consistent-existence-index-check"(){return require("./rules/conventions/consistent-existence-index-check").consistentExistenceIndexCheck},get"no-json-schema-tags"(){return require("./rules/conventions/no-json-schema-tags").noJsonSchemaTags},get"require-data-testid"(){return require("./rules/conventions/require-data-testid").requireDataTestId},get"utm-taxonomy"(){return require("./rules/conventions/utm-taxonomy").utmTaxonomy},get"no-raw-cross-property-href"(){return require("./rules/conventions/no-raw-cross-property-href").noRawCrossPropertyHref},get"analytics-event-naming"(){return require("./rules/conventions/analytics-event-naming").analyticsEventNaming},get"no-magic-numbers"(){return require("./rules/conventions/no-magic-numbers").noMagicNumbers}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-conventions",exports.rules);exports.plugin={meta:{name:"eslint-plugin-conventions",version:"6.0.1"},rules:exports.rules};exports.configs={recommended:{plugins:{conventions:exports.plugin},rules:{"conventions/no-commented-code":"warn","conventions/expiring-todo-comments":"warn","conventions/no-deprecated-api":"warn","conventions/utm-taxonomy":"error","conventions/no-raw-cross-property-href":"error","conventions/analytics-event-naming":"error"}}};exports.default=exports.plugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.consistentExistenceIndexCheck=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.consistentExistenceIndexCheck=(0,eslint_devkit_1.createRule)({name:"consistent-existence-index-check",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/consistent-existence-index-check.md",description:"Enforce consistent style for checking object property existence"},fixable:"code",messages:{consistentExistenceCheck:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Inconsistent Property Check",description:"Use consistent method for property existence checks",severity:"MEDIUM",fix:'Use "{{preferred}}" instead of "{{current}}" for property checks',documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in"})},schema:[{type:"object",properties:{preferred:{type:"string",enum:["in","hasOwnProperty","Object.hasOwn"],default:"
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.consistentExistenceIndexCheck=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.consistentExistenceIndexCheck=(0,eslint_devkit_1.createRule)({name:"consistent-existence-index-check",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/consistent-existence-index-check.md",description:"Enforce consistent style for checking object property existence"},fixable:"code",messages:{consistentExistenceCheck:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Inconsistent Property Check",description:"Use consistent method for property existence checks",severity:"MEDIUM",fix:'Use "{{preferred}}" instead of "{{current}}" for property checks',documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in"})},schema:[{type:"object",properties:{preferred:{type:"string",enum:["in","hasOwnProperty","Object.hasOwn"],default:"Object.hasOwn"}},additionalProperties:false}]},defaultOptions:[{preferred:"Object.hasOwn"}],create(context){const[options]=context.options;const{preferred="Object.hasOwn"}=options||{};function reportInconsistentCheck(node,currentMethod,object,property,surplusArguments=false){let fix;const crossesPrototypeBoundary=currentMethod==="in"!==(preferred==="in");const crossesDispatchBoundary=currentMethod==="hasOwnProperty"||preferred==="hasOwnProperty";const spliceWouldChangeArity=object.type==="SequenceExpression"||property.type==="SequenceExpression";const parent=node.parent;const isStandaloneExpression=!parent||parent.type==="ExpressionStatement"||parent.type==="VariableDeclarator"&&parent.init===node||parent.type==="AssignmentExpression"&&parent.right===node||parent.type==="ReturnStatement"&&parent.argument===node||parent.type==="ArrowFunctionExpression"&&parent.body===node||parent.type==="IfStatement"&&parent.test===node||parent.type==="WhileStatement"&&parent.test===node||parent.type==="DoWhileStatement"&&parent.test===node||parent.type==="ForStatement"&&parent.test===node||parent.type==="ConditionalExpression"&&parent.test===node;if(!crossesPrototypeBoundary&&!crossesDispatchBoundary&&!spliceWouldChangeArity&&!surplusArguments&&preferred==="Object.hasOwn"&&isStandaloneExpression){fix=function(fixer){const objectText=context.sourceCode.getText(object);const propertyText=context.sourceCode.getText(property);return fixer.replaceText(node,`Object.hasOwn(${objectText}, ${propertyText})`)}}context.report({node,messageId:"consistentExistenceCheck",data:{current:currentMethod,preferred},fix})}return{CallExpression(node){if(node.callee.type==="MemberExpression"&&(0,eslint_devkit_1.propertyName)(node.callee)==="hasOwnProperty"&&node.arguments.length===1&&preferred!=="hasOwnProperty"){reportInconsistentCheck(node,"hasOwnProperty",node.callee.object,node.arguments[0])}if(node.callee.type==="MemberExpression"&&node.callee.object.type==="MemberExpression"&&node.callee.object.object.type==="MemberExpression"&&node.callee.object.object.object.type==="Identifier"&&node.callee.object.object.object.name==="Object"&&(0,eslint_devkit_1.propertyName)(node.callee.object.object)==="prototype"&&(0,eslint_devkit_1.propertyName)(node.callee.object)==="hasOwnProperty"&&(0,eslint_devkit_1.propertyName)(node.callee)==="call"&&node.arguments.length>=2&&preferred!=="hasOwnProperty"){reportInconsistentCheck(node,"Object.prototype.hasOwnProperty.call",node.arguments[0],node.arguments[1],node.arguments.length>2)}if(node.callee.type==="MemberExpression"&&node.callee.object.type==="Identifier"&&node.callee.object.name==="Object"&&(0,eslint_devkit_1.propertyName)(node.callee)==="hasOwn"&&node.arguments.length===2&&preferred!=="Object.hasOwn"){reportInconsistentCheck(node,"Object.hasOwn",node.arguments[0],node.arguments[1])}},BinaryExpression(node){if(node.operator==="in"&&preferred!=="in"){reportInconsistentCheck(node,"in",node.right,node.left)}}}}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.filenameCase=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");const DEFAULT_ALLOWED_UPPERCASE_FILES=["README","LICENSE","CHANGELOG","CONTRIBUTING","AUTHORS","COPYING","SECURITY","NOTICE","PATENTS","VERSION"];exports.filenameCase=(0,eslint_devkit_1.createRule)({name:"filename-case",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/filename-case.md",description:"Enforce filename case conventions for consistency"},hasSuggestions:true,messages:{filenameCase:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Filename Case Convention",description:'Filename "{{current}}" violates {{case}} naming convention',severity:"MEDIUM",fix:'Rename file from "{{current}}" to "{{suggested}}" following {{case}} convention',documentationLink:"https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md"})},schema:[{type:"object",properties:{case:{type:"string",enum:["camelCase","kebabCase","pascalCase","snakeCase"],default:"kebabCase"},ignore:{type:"array",items:{anyOf:[{type:"string"},{type:"object"}]},default:[]},allowedUppercaseFiles:{type:"array",items:{type:"string"},description:"List of uppercase filenames to allow (without extension). Defaults to common files like README, LICENSE, etc."},allowedKebabCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use kebab-case regardless of the global case setting.",default:[]},allowedSnakeCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use snake_case regardless of the global case setting.",default:[]},allowedCamelCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use camelCase regardless of the global case setting.",default:[]},allowedPascalCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use PascalCase regardless of the global case setting.",default:[]}},additionalProperties:false}]},defaultOptions:[{case:"kebabCase",ignore:[],allowedUppercaseFiles:DEFAULT_ALLOWED_UPPERCASE_FILES,allowedKebabCase:[],allowedSnakeCase:[],allowedCamelCase:[],allowedPascalCase:[]}],create(context){const[options]=context.options;const{case:caseType="kebabCase",ignore=[],allowedUppercaseFiles=DEFAULT_ALLOWED_UPPERCASE_FILES,allowedKebabCase=[],allowedSnakeCase=[],allowedCamelCase=[],allowedPascalCase=[]}=options||{};function toCamelCase(str){return str.replace(/[-_](.)/g,(_,letter)=>letter.toUpperCase())}function toKebabCase(str){return str.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function toPascalCase(str){const camel=toCamelCase(str);return camel.charAt(0).toUpperCase()+camel.slice(1)}function toSnakeCase(str){return str.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.filenameCase=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");const DEFAULT_ALLOWED_UPPERCASE_FILES=["README","LICENSE","CHANGELOG","CONTRIBUTING","AUTHORS","COPYING","SECURITY","NOTICE","PATENTS","VERSION"];exports.filenameCase=(0,eslint_devkit_1.createRule)({name:"filename-case",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/filename-case.md",description:"Enforce filename case conventions for consistency"},hasSuggestions:true,messages:{filenameCase:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Filename Case Convention",description:'Filename "{{current}}" violates {{case}} naming convention',severity:"MEDIUM",fix:'Rename file from "{{current}}" to "{{suggested}}" following {{case}} convention',documentationLink:"https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md"})},schema:[{type:"object",properties:{case:{type:"string",enum:["camelCase","kebabCase","pascalCase","snakeCase"],default:"kebabCase"},ignore:{type:"array",items:{anyOf:[{type:"string"},{type:"object"}]},default:[]},allowedUppercaseFiles:{type:"array",items:{type:"string"},description:"List of uppercase filenames to allow (without extension). Defaults to common files like README, LICENSE, etc."},allowedKebabCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use kebab-case regardless of the global case setting.",default:[]},allowedSnakeCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use snake_case regardless of the global case setting.",default:[]},allowedCamelCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use camelCase regardless of the global case setting.",default:[]},allowedPascalCase:{type:"array",items:{type:"string"},description:"List of filenames allowed to use PascalCase regardless of the global case setting.",default:[]}},additionalProperties:false}]},defaultOptions:[{case:"kebabCase",ignore:[],allowedUppercaseFiles:DEFAULT_ALLOWED_UPPERCASE_FILES,allowedKebabCase:[],allowedSnakeCase:[],allowedCamelCase:[],allowedPascalCase:[]}],create(context){const[options]=context.options;const{case:caseType="kebabCase",ignore=[],allowedUppercaseFiles=DEFAULT_ALLOWED_UPPERCASE_FILES,allowedKebabCase=[],allowedSnakeCase=[],allowedCamelCase=[],allowedPascalCase=[]}=options||{};function toCamelCase(str){return str.replace(/[-_.](.)/g,(_,letter)=>letter.toUpperCase())}function toKebabCase(str){return str.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_.]+/g,"-").toLowerCase()}function toPascalCase(str){const camel=toCamelCase(str);return camel.charAt(0).toUpperCase()+camel.slice(1)}function toSnakeCase(str){return str.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s\-.]+/g,"_").toLowerCase()}function isCamelCase(str){return/^[a-z][a-zA-Z0-9]*$/.test(str)}function isKebabCase(str){return/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(str)}function isPascalCase(str){return/^[A-Z][a-zA-Z0-9]*$/.test(str)}function isSnakeCase(str){return/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/.test(str)}function matchesCase(str,expectedCase){switch(expectedCase){case"camelCase":return isCamelCase(str);case"kebabCase":return isKebabCase(str);case"pascalCase":return isPascalCase(str);case"snakeCase":return isSnakeCase(str);default:return true}}function getSuggestedName(basename,nameWithoutExt,targetCase){let transformed=nameWithoutExt;switch(targetCase){case"camelCase":transformed=toCamelCase(nameWithoutExt);break;case"kebabCase":transformed=toKebabCase(nameWithoutExt);break;case"pascalCase":transformed=toPascalCase(nameWithoutExt);break;case"snakeCase":transformed=toSnakeCase(nameWithoutExt);break}const ext=basename.slice(nameWithoutExt.length);return transformed+ext}return{Program(node){const filename=context.filename;if(!filename){return}const basename=(0,eslint_devkit_3.getBasename)(filename);const nameWithoutExt=basename.replace(/(\.(spec|test|stories|story|e2e|d))*\.[^.]+$/,"");if(!nameWithoutExt){return}for(const ignorePattern of ignore){if(typeof ignorePattern==="string"){if(basename===ignorePattern){return}}else if(ignorePattern instanceof RegExp){if(ignorePattern.test(basename)){return}}}if(allowedUppercaseFiles.includes(nameWithoutExt)){return}if(basename.startsWith(".")){return}if(allowedKebabCase.includes(nameWithoutExt)&&matchesCase(nameWithoutExt,"kebabCase")){return}if(allowedSnakeCase.includes(nameWithoutExt)&&matchesCase(nameWithoutExt,"snakeCase")){return}if(allowedCamelCase.includes(nameWithoutExt)&&matchesCase(nameWithoutExt,"camelCase")){return}if(allowedPascalCase.includes(nameWithoutExt)&&matchesCase(nameWithoutExt,"pascalCase")){return}if(!matchesCase(nameWithoutExt,caseType)){const suggestedName=getSuggestedName(basename,nameWithoutExt,caseType);context.report({node,messageId:"filenameCase",data:{case:caseType,current:basename,suggested:suggestedName},suggest:[{messageId:"filenameCase",data:{suggestedName},fix(){return null}}]})}}}}});
|