Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-lit

Package Overview
Dependencies
Maintainers
0
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-lit - npm Package Compare versions

Comparing version 1.14.0 to 1.15.0

52

docs/rules/attribute-names.md

@@ -7,3 +7,3 @@ # Enforces attribute naming conventions

Further, camelCase names should ideally be exposed as snake-case attributes.
Further, camelCase names should ideally be exposed as kebab-case attributes.

@@ -37,2 +37,5 @@ ## Rule Details

@property({attribute: 'camel-case-other-name'})
camelCaseName: string;
@property()

@@ -42,2 +45,49 @@ lower: string;

## Options
### `convention`
You can specify a `convention` to enforce a particular naming convention
on element attributes.
The available values are:
- `none` (default, no convention is enforced)
- `kebab`
- `snake`
For example for a property named `camelCaseProp`, expected attribute names are:
| Convention | Attribute |
|------------|----------------------|
| none | any lower case value |
| kebab | camel-case-prop |
| snake | camel_case_prop |
The following patterns are considered warnings with `{"convention": "kebab"}`
specified:
```ts
// Should have an attribute set to `camel-case-name`
@property() camelCaseName: string;
// Attribute should match the property name when a convention is set
@property({attribute: 'camel-case-other-name'})
camelCaseName: string;
```
The following patterns are not warnings with `{"convention": "kebab"}`
specified:
```ts
@property({attribute: 'camel-case-name'})
camelCaseName: string;
@property({attribute: false})
camelCaseName: string;
@property()
lower: string;
```
## When Not To Use It

@@ -44,0 +94,0 @@

@@ -17,3 +17,11 @@ "use strict";

},
schema: [],
schema: [
{
type: 'object',
properties: {
convention: { type: 'string', enum: ['none', 'kebab', 'snake'] }
},
additionalProperties: false
}
],
messages: {

@@ -24,9 +32,13 @@ casedAttribute: 'Attributes are case-insensitive and therefore should be ' +

'instead have an explicit `attribute` set to the lower case ' +
'name (usually snake-case)'
'name (usually snake-case)',
casedAttributeConvention: 'Attribute should be property name written in {{convention}} ' +
'as "{{name}}"'
}
},
create(context) {
var _a, _b;
const convention = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.convention) !== null && _b !== void 0 ? _b : 'none';
return {
ClassDeclaration: (node) => {
var _a;
var _a, _b;
if ((0, util_1.isLitClass)(node)) {

@@ -54,2 +66,28 @@ const propertyMap = (0, util_1.getPropertyMap)(node);

}
else if (convention !== 'none') {
let conventionName;
let expectedAttributeName;
switch (convention) {
case 'snake':
conventionName = 'snake_case';
expectedAttributeName = (0, util_1.toSnakeCase)(prop);
break;
case 'kebab':
conventionName = 'kebab-case';
expectedAttributeName = (0, util_1.toKebabCase)(prop);
break;
}
if (expectedAttributeName &&
conventionName &&
propConfig.attributeName !== expectedAttributeName) {
context.report({
node: (_b = propConfig.expr) !== null && _b !== void 0 ? _b : propConfig.key,
messageId: 'casedAttributeConvention',
data: {
convention: conventionName,
name: expectedAttributeName
}
});
}
}
}

@@ -56,0 +94,0 @@ }

5

lib/rules/lifecycle-super.js

@@ -6,2 +6,3 @@ "use strict";

*/
const util_1 = require("../util");
const methodNames = ['connectedCallback', 'disconnectedCallback', 'update'];

@@ -39,5 +40,3 @@ //------------------------------------------------------------------------------

function classEnter(node) {
if (!node.superClass ||
node.superClass.type !== 'Identifier' ||
node.superClass.name !== 'LitElement') {
if (!(0, util_1.isLitClass)(node)) {
return;

@@ -44,0 +43,0 @@ }

@@ -41,5 +41,3 @@ "use strict";

function classEnter(node) {
if (!node.superClass ||
node.superClass.type !== 'Identifier' ||
node.superClass.name !== 'LitElement') {
if (!(0, util_1.isLitClass)(node)) {
return;

@@ -46,0 +44,0 @@ }

@@ -6,2 +6,3 @@ "use strict";

*/
const util_1 = require("../util");
//------------------------------------------------------------------------------

@@ -34,5 +35,3 @@ // Rule Definition

function classEnter(node) {
if (!node.superClass ||
node.superClass.type !== 'Identifier' ||
node.superClass.name !== 'LitElement') {
if (!(0, util_1.isLitClass)(node)) {
return;

@@ -39,0 +38,0 @@ }

@@ -32,2 +32,3 @@ "use strict";

const alwaysQuote = context.options[0] === 'always';
const quotePattern = /=(["'])?$/;
//----------------------------------------------------------------------

@@ -48,12 +49,10 @@ // Helpers

const nextQuasi = node.quasi.quasis[i + 1];
const isAttribute = /=["']?$/.test(previousQuasi.value.raw);
const quoteMatch = previousQuasi.value.raw.match(quotePattern);
// don't care about non-attribute bindings
if (!isAttribute) {
if (!quoteMatch) {
continue;
}
const isQuoted = (previousQuasi.value.raw.endsWith('="') &&
nextQuasi.value.raw.startsWith('"')) ||
(previousQuasi.value.raw.endsWith("='") &&
nextQuasi.value.raw.startsWith("'"));
if (alwaysQuote && !isQuoted) {
const hasStartQuote = quoteMatch[1] !== undefined;
const isQuoted = hasStartQuote && nextQuasi.value.raw.startsWith(quoteMatch[1]);
if (alwaysQuote && !hasStartQuote) {
context.report({

@@ -60,0 +59,0 @@ node: expression,

@@ -81,1 +81,15 @@ import * as ESTree from 'estree';

export declare function templateExpressionToHtml(node: ESTree.TaggedTemplateExpression): string;
/**
* Converts a camelCase string to snake_case string
*
* @param {string} camelCaseStr String to convert
* @return {string}
*/
export declare function toSnakeCase(camelCaseStr: string): string;
/**
* Converts a camelCase string to kebab-case string
*
* @param {string} camelCaseStr String to convert
* @return {string}
*/
export declare function toKebabCase(camelCaseStr: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.templateExpressionToHtml = exports.isExpressionPlaceholder = exports.getExpressionPlaceholder = exports.hasLitPropertyDecorator = exports.getPropertyMap = exports.getClassFields = exports.extractPropertyEntry = exports.getIdentifierName = exports.isLitClass = void 0;
exports.toKebabCase = exports.toSnakeCase = exports.templateExpressionToHtml = exports.isExpressionPlaceholder = exports.getExpressionPlaceholder = exports.hasLitPropertyDecorator = exports.getPropertyMap = exports.getClassFields = exports.extractPropertyEntry = exports.getIdentifierName = exports.isLitClass = void 0;
/**
* Returns if given node has a customElement decorator
* @param {ESTree.Class} node
* @return {boolean}
*/
function hasCustomElementDecorator(node) {
const decoratedNode = node;
if (!decoratedNode.decorators || !Array.isArray(decoratedNode.decorators)) {
return false;
}
for (const decorator of decoratedNode.decorators) {
if (decorator.expression.type === 'CallExpression' &&
decorator.expression.callee.type === 'Identifier' &&
decorator.expression.callee.name === 'customElement') {
return true;
}
}
return false;
}
/**
* Returns if given node has a lit identifier

@@ -34,2 +53,5 @@ * @param {ESTree.Node} node

function isLitClass(clazz) {
if (hasCustomElementDecorator(clazz)) {
return true;
}
if (clazz.superClass) {

@@ -263,1 +285,21 @@ return (hasLitIdentifier(clazz.superClass) || isLitByExpression(clazz.superClass));

exports.templateExpressionToHtml = templateExpressionToHtml;
/**
* Converts a camelCase string to snake_case string
*
* @param {string} camelCaseStr String to convert
* @return {string}
*/
function toSnakeCase(camelCaseStr) {
return camelCaseStr.replace(/[A-Z]/g, (m) => '_' + m.toLowerCase());
}
exports.toSnakeCase = toSnakeCase;
/**
* Converts a camelCase string to kebab-case string
*
* @param {string} camelCaseStr String to convert
* @return {string}
*/
function toKebabCase(camelCaseStr) {
return camelCaseStr.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
}
exports.toKebabCase = toKebabCase;
{
"name": "eslint-plugin-lit",
"version": "1.14.0",
"version": "1.15.0",
"description": "lit-html support for ESLint",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -39,2 +39,18 @@ <div align="center">

Or if you're using (flat) config files, add to your `eslint.config.js`:
```ts
import {configs} from 'eslint-plugin-lit';
export default [
configs['flat/recommended'],
// or if you want to specify `files`, or other options
{
...configs['flat/recommended'],
files: ['test/**/*.js']
}
];
```
### Custom Configuration

@@ -41,0 +57,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc