eslint-plugin-mgw-eslint-rules 2.3.16 → 2.3.18

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/dist/index.js CHANGED
@@ -3261,8 +3261,8 @@ var require_RuleCreator = __commonJS({
3261
3261
  exports2.RuleCreator = RuleCreator;
3262
3262
  var applyDefault_1 = require_applyDefault();
3263
3263
  function RuleCreator(urlCreator) {
3264
- return function createNamedRule({ meta, name, ...rule9 }) {
3265
- const ruleWithDocs = createRule9({
3264
+ return function createNamedRule({ meta, name, ...rule10 }) {
3265
+ const ruleWithDocs = createRule10({
3266
3266
  meta: {
3267
3267
  ...meta,
3268
3268
  docs: {
@@ -3271,12 +3271,12 @@ var require_RuleCreator = __commonJS({
3271
3271
  }
3272
3272
  },
3273
3273
  name,
3274
- ...rule9
3274
+ ...rule10
3275
3275
  });
3276
3276
  return ruleWithDocs;
3277
3277
  };
3278
3278
  }
3279
- function createRule9({
3279
+ function createRule10({
3280
3280
  create,
3281
3281
  // Keep accepting deprecated defaultOptions for backward compatibility.
3282
3282
  // eslint-disable-next-line @typescript-eslint/no-deprecated
@@ -3296,7 +3296,7 @@ var require_RuleCreator = __commonJS({
3296
3296
  };
3297
3297
  }
3298
3298
  RuleCreator.withoutDocs = function withoutDocs(args) {
3299
- return createRule9(args);
3299
+ return createRule10(args);
3300
3300
  };
3301
3301
  }
3302
3302
  });
@@ -20621,13 +20621,13 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20621
20621
  }
20622
20622
  _scopeKeyframesRelatedCss(cssText, scopeSelector) {
20623
20623
  const unscopedKeyframesSet = /* @__PURE__ */ new Set();
20624
- const scopedKeyframesCssText = processRules(cssText, (rule9) => this._scopeLocalKeyframeDeclarations(rule9, scopeSelector, unscopedKeyframesSet));
20625
- return processRules(scopedKeyframesCssText, (rule9) => this._scopeAnimationRule(rule9, scopeSelector, unscopedKeyframesSet));
20624
+ const scopedKeyframesCssText = processRules(cssText, (rule10) => this._scopeLocalKeyframeDeclarations(rule10, scopeSelector, unscopedKeyframesSet));
20625
+ return processRules(scopedKeyframesCssText, (rule10) => this._scopeAnimationRule(rule10, scopeSelector, unscopedKeyframesSet));
20626
20626
  }
20627
- _scopeLocalKeyframeDeclarations(rule9, scopeSelector, unscopedKeyframesSet) {
20627
+ _scopeLocalKeyframeDeclarations(rule10, scopeSelector, unscopedKeyframesSet) {
20628
20628
  return {
20629
- ...rule9,
20630
- selector: rule9.selector.replace(/(^@(?:-webkit-)?keyframes(?:\s+))(['"]?)(.+)\2(\s*)$/, (_, start, quote, keyframeName, endSpaces) => {
20629
+ ...rule10,
20630
+ selector: rule10.selector.replace(/(^@(?:-webkit-)?keyframes(?:\s+))(['"]?)(.+)\2(\s*)$/, (_, start, quote, keyframeName, endSpaces) => {
20631
20631
  unscopedKeyframesSet.add(unescapeQuotes(keyframeName, quote));
20632
20632
  return `${start}${quote}${scopeSelector}_${keyframeName}${quote}${endSpaces}`;
20633
20633
  })
@@ -20640,8 +20640,8 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20640
20640
  });
20641
20641
  }
20642
20642
  _animationDeclarationKeyframesRe = /(^|\s+|,)(?:(?:(['"])((?:\\\\|\\\2|(?!\2).)+)\2)|(-?[A-Za-z][\w\-]*))(?=[,\s]|$)/g;
20643
- _scopeAnimationRule(rule9, scopeSelector, unscopedKeyframesSet) {
20644
- let content = rule9.content.replace(/((?:^|\s+|;)(?:-webkit-)?animation\s*:\s*),*([^;]+)/g, (_, start, animationDeclarations) => start + animationDeclarations.replace(this._animationDeclarationKeyframesRe, (original, leadingSpaces, quote = "", quotedName, nonQuotedName) => {
20643
+ _scopeAnimationRule(rule10, scopeSelector, unscopedKeyframesSet) {
20644
+ let content = rule10.content.replace(/((?:^|\s+|;)(?:-webkit-)?animation\s*:\s*),*([^;]+)/g, (_, start, animationDeclarations) => start + animationDeclarations.replace(this._animationDeclarationKeyframesRe, (original, leadingSpaces, quote = "", quotedName, nonQuotedName) => {
20645
20645
  if (quotedName) {
20646
20646
  return `${leadingSpaces}${this._scopeAnimationKeyframe(`${quote}${quotedName}${quote}`, scopeSelector, unscopedKeyframesSet)}`;
20647
20647
  } else {
@@ -20650,7 +20650,7 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20650
20650
  }));
20651
20651
  content = content.replace(/((?:^|\s+|;)(?:-webkit-)?animation-name(?:\s*):(?:\s*))([^;]+)/g, (_match, start, commaSeparatedKeyframes) => `${start}${commaSeparatedKeyframes.split(",").map((keyframe) => this._scopeAnimationKeyframe(keyframe, scopeSelector, unscopedKeyframesSet)).join(",")}`);
20652
20652
  return {
20653
- ...rule9,
20653
+ ...rule10,
20654
20654
  content
20655
20655
  };
20656
20656
  }
@@ -20661,8 +20661,8 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20661
20661
  }
20662
20662
  _insertPolyfillRulesInCssText(cssText) {
20663
20663
  return cssText.replace(_cssContentRuleRe, (...m) => {
20664
- const rule9 = m[0].replace(m[1], "").replace(m[2], "");
20665
- return m[4] + rule9;
20664
+ const rule10 = m[0].replace(m[1], "").replace(m[2], "");
20665
+ return m[4] + rule10;
20666
20666
  });
20667
20667
  }
20668
20668
  _scopeCssText(cssText, scopeSelector, hostSelector) {
@@ -20683,8 +20683,8 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20683
20683
  let m;
20684
20684
  _cssContentUnscopedRuleRe.lastIndex = 0;
20685
20685
  while ((m = _cssContentUnscopedRuleRe.exec(cssText)) !== null) {
20686
- const rule9 = m[0].replace(m[2], "").replace(m[1], m[4]);
20687
- r += rule9 + "\n\n";
20686
+ const rule10 = m[0].replace(m[2], "").replace(m[1], m[4]);
20687
+ r += rule10 + "\n\n";
20688
20688
  }
20689
20689
  return r;
20690
20690
  }
@@ -20769,28 +20769,28 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
20769
20769
  return _shadowDOMSelectorsRe.reduce((result, pattern) => result.replace(pattern, " "), cssText);
20770
20770
  }
20771
20771
  _scopeSelectors(cssText, scopeSelector, hostSelector) {
20772
- return processRules(cssText, (rule9) => {
20773
- let selector = rule9.selector;
20774
- let content = rule9.content;
20775
- if (rule9.selector[0] !== "@") {
20772
+ return processRules(cssText, (rule10) => {
20773
+ let selector = rule10.selector;
20774
+ let content = rule10.content;
20775
+ if (rule10.selector[0] !== "@") {
20776
20776
  selector = this._scopeSelector({
20777
20777
  selector,
20778
20778
  scopeSelector,
20779
20779
  hostSelector,
20780
20780
  isParentSelector: true
20781
20781
  });
20782
- } else if (scopedAtRuleIdentifiers.some((atRule) => rule9.selector.startsWith(atRule))) {
20783
- content = this._scopeSelectors(rule9.content, scopeSelector, hostSelector);
20784
- } else if (rule9.selector.startsWith("@font-face") || rule9.selector.startsWith("@page")) {
20785
- content = this._stripScopingSelectors(rule9.content);
20782
+ } else if (scopedAtRuleIdentifiers.some((atRule) => rule10.selector.startsWith(atRule))) {
20783
+ content = this._scopeSelectors(rule10.content, scopeSelector, hostSelector);
20784
+ } else if (rule10.selector.startsWith("@font-face") || rule10.selector.startsWith("@page")) {
20785
+ content = this._stripScopingSelectors(rule10.content);
20786
20786
  }
20787
20787
  return new CssRule(selector, content);
20788
20788
  });
20789
20789
  }
20790
20790
  _stripScopingSelectors(cssText) {
20791
- return processRules(cssText, (rule9) => {
20792
- const selector = rule9.selector.replace(_shadowDeepSelectors, " ").replace(_polyfillHostNoCombinatorRe, " ");
20793
- return new CssRule(selector, rule9.content);
20791
+ return processRules(cssText, (rule10) => {
20792
+ const selector = rule10.selector.replace(_shadowDeepSelectors, " ").replace(_polyfillHostNoCombinatorRe, " ");
20793
+ return new CssRule(selector, rule10.content);
20794
20794
  });
20795
20795
  }
20796
20796
  _safeSelector;
@@ -21051,8 +21051,8 @@ ${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
21051
21051
  suffix = suffix.substring(BLOCK_PLACEHOLDER.length + 1);
21052
21052
  contentPrefix = "{";
21053
21053
  }
21054
- const rule9 = ruleCallback(new CssRule(selector, content));
21055
- return `${m[1]}${rule9.selector}${m[3]}${contentPrefix}${rule9.content}${suffix}`;
21054
+ const rule10 = ruleCallback(new CssRule(selector, content));
21055
+ return `${m[1]}${rule10.selector}${m[3]}${contentPrefix}${rule10.content}${suffix}`;
21056
21056
  });
21057
21057
  return unescapeInStrings(escapedResult);
21058
21058
  }
@@ -43819,9 +43819,9 @@ var require_parser_services = __commonJS({
43819
43819
  "node_modules/@angular-eslint/utils/dist/eslint-plugin-template/parser-services.js"(exports2) {
43820
43820
  "use strict";
43821
43821
  Object.defineProperty(exports2, "__esModule", { value: true });
43822
- exports2.getTemplateParserServices = getTemplateParserServices2;
43822
+ exports2.getTemplateParserServices = getTemplateParserServices3;
43823
43823
  exports2.ensureTemplateParser = ensureTemplateParser;
43824
- function getTemplateParserServices2(context) {
43824
+ function getTemplateParserServices3(context) {
43825
43825
  ensureTemplateParser(context);
43826
43826
  return context.sourceCode.parserServices;
43827
43827
  }
@@ -43936,7 +43936,7 @@ var createRule = import_utils.ESLintUtils.RuleCreator((name) => `https://github.
43936
43936
  var rule = createRule({
43937
43937
  name: RULE_NAME,
43938
43938
  meta: {
43939
- type: "suggestion",
43939
+ type: "layout",
43940
43940
  docs: {
43941
43941
  description: "Interdit les template literals sans interpolation (backticks sans ${...}).",
43942
43942
  recommended: true
@@ -44007,14 +44007,14 @@ var rule2 = createRule2({
44007
44007
  preferredCase: "lower"
44008
44008
  }
44009
44009
  ],
44010
- create(context, options) {
44010
+ create(context, [{ preferredCase }]) {
44011
44011
  return {
44012
44012
  FunctionDeclaration(node) {
44013
44013
  if (node.id != null) {
44014
- const testName = options[0].preferredCase === "upper" ? /^[a-z]/ : /^[A-Z]/;
44014
+ const testName = preferredCase === "upper" ? /^[a-z]/ : /^[A-Z]/;
44015
44015
  if (testName.test(node.id.name)) {
44016
44016
  context.report({
44017
- messageId: options[0].preferredCase === "upper" ? "uppercase" : "lowercase",
44017
+ messageId: preferredCase === "upper" ? "uppercase" : "lowercase",
44018
44018
  node: node.id
44019
44019
  });
44020
44020
  }
@@ -44031,7 +44031,7 @@ var createRule3 = import_utils3.ESLintUtils.RuleCreator((name) => `https://githu
44031
44031
  var rule3 = createRule3({
44032
44032
  name: RULE_NAME3,
44033
44033
  meta: {
44034
- type: "suggestion",
44034
+ type: "problem",
44035
44035
  docs: {
44036
44036
  description: "Enforce correct usage of Angular signals"
44037
44037
  },
@@ -44086,7 +44086,7 @@ var createRule4 = import_utils4.ESLintUtils.RuleCreator((name) => `https://githu
44086
44086
  var rule4 = createRule4({
44087
44087
  name: RULE_NAME4,
44088
44088
  meta: {
44089
- type: "suggestion",
44089
+ type: "problem",
44090
44090
  docs: {
44091
44091
  description: "Enforce the use of template literals when string contains ${}."
44092
44092
  },
@@ -44126,7 +44126,7 @@ var createRule5 = import_utils5.ESLintUtils.RuleCreator((name) => `https://githu
44126
44126
  var rule5 = createRule5({
44127
44127
  name: RULE_NAME5,
44128
44128
  meta: {
44129
- type: "suggestion",
44129
+ type: "problem",
44130
44130
  docs: {
44131
44131
  description: "Disallow explicit type declarations for readonly properties initialized to a number, string, or boolean",
44132
44132
  recommended: true
@@ -44201,7 +44201,7 @@ var createRule6 = import_utils6.ESLintUtils.RuleCreator((name) => `${DOCS_RULES2
44201
44201
  var rule6 = createRule6({
44202
44202
  name: RULE_NAME6,
44203
44203
  meta: {
44204
- type: "suggestion",
44204
+ type: "problem",
44205
44205
  docs: {
44206
44206
  description: "Enforce using const enum",
44207
44207
  recommended: true
@@ -44308,14 +44308,126 @@ var rule7 = createRule7({
44308
44308
  }
44309
44309
  });
44310
44310
 
44311
- // src/rules/template/prefer-class-style-binding.ts
44311
+ // src/rules/template/attributes-naming-convention.ts
44312
44312
  var import_utils9 = __toESM(require_dist6());
44313
44313
  var import_utils10 = __toESM(require_dist4());
44314
- var RULE_NAME8 = "template/prefer-class-style-binding";
44314
+ var NAMING_CONVENTIONS = ["camelCase", "strictCamelCase", "PascalCase", "StrictPascalCase", "snake_case", "UPPER_CASE", "kebab-case"];
44315
+ var ATTRIBUTE_CONVENTION_POSSIBLE_VALUES = [...NAMING_CONVENTIONS];
44316
+ var RULE_NAME8 = "template/attributes-naming-convention";
44317
+ var ATTRIBUTE_DEFAULT_VALUES = {
44318
+ id: "kebab-case",
44319
+ class: "kebab-case"
44320
+ };
44321
+ var conventionPatterns = {
44322
+ camelCase: /^[a-z][a-zA-Z0-9]*$/,
44323
+ strictCamelCase: /^(?!.*[A-Z]{2})[a-z][a-zA-Z0-9]*$/,
44324
+ PascalCase: /^[A-Z][a-zA-Z0-9]*$/,
44325
+ StrictPascalCase: /^(?!.*[A-Z]{2})[A-Z][a-zA-Z0-9]*$/,
44326
+ snake_case: /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/,
44327
+ UPPER_CASE: /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/,
44328
+ "kebab-case": /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/
44329
+ };
44315
44330
  var DOCS_RULES4 = "https://github.com/developpement-megao/mgw-eslint-rules/tree/main/docs/rules";
44316
44331
  var createRule8 = import_utils10.ESLintUtils.RuleCreator((name) => `${DOCS_RULES4}/${name}.md`);
44317
44332
  var rule8 = createRule8({
44318
44333
  name: RULE_NAME8,
44334
+ meta: {
44335
+ type: "suggestion",
44336
+ docs: {
44337
+ description: "Enforce naming convention (kebab-case) for specified attributes (id and class) values in Angular templates.",
44338
+ category: "Best Practices",
44339
+ recommended: true
44340
+ },
44341
+ messages: {
44342
+ invalidNaming: "Attribute '{{ attribute }}' with value '{{ value }}' must match one of the naming conventions : {{ conventions }}."
44343
+ },
44344
+ schema: [
44345
+ {
44346
+ type: "object",
44347
+ properties: {
44348
+ attributes: {
44349
+ type: "object",
44350
+ description: "Map of attribute names to their allowed naming conventions (single or array).",
44351
+ additionalProperties: {
44352
+ anyOf: [
44353
+ {
44354
+ type: "string",
44355
+ enum: ATTRIBUTE_CONVENTION_POSSIBLE_VALUES
44356
+ },
44357
+ {
44358
+ type: "array",
44359
+ items: {
44360
+ type: "string",
44361
+ enum: ATTRIBUTE_CONVENTION_POSSIBLE_VALUES
44362
+ },
44363
+ minItems: 1
44364
+ }
44365
+ ]
44366
+ }
44367
+ }
44368
+ },
44369
+ //required: ['conventions'],
44370
+ additionalProperties: false
44371
+ }
44372
+ ],
44373
+ hasSuggestions: true
44374
+ },
44375
+ defaultOptions: [
44376
+ {
44377
+ attributes: ATTRIBUTE_DEFAULT_VALUES
44378
+ }
44379
+ ],
44380
+ create(context, [options]) {
44381
+ const parserServices = (0, import_utils9.getTemplateParserServices)(context);
44382
+ const attributesConfig = options.attributes || ATTRIBUTE_DEFAULT_VALUES;
44383
+ const listeAttributes = new Map(
44384
+ Object.entries(attributesConfig).map(([a, n]) => {
44385
+ const listeNommage = typeof n === "string" ? [n] : n;
44386
+ const nommageReg = listeNommage.map((c) => conventionPatterns[c]);
44387
+ return [a, { noms: listeNommage.join(", "), regs: nommageReg }];
44388
+ })
44389
+ );
44390
+ return {
44391
+ // Détecte les attributs dans les templates (parcours global élément (noeud) par élément)
44392
+ //'Element[attributes]'(node: TmplAstElement) {
44393
+ //// const attributes = node.attributes;
44394
+ //// On va parcourir tous les attributs
44395
+ //// for (const attr of attributes) {
44396
+ // Parcours attribut par attribut
44397
+ "Element$1 > TextAttribute"(node) {
44398
+ if (node.value) {
44399
+ const attrNomme = listeAttributes.get(node.name);
44400
+ if (attrNomme) {
44401
+ const attributeValues = node.value.split(/\s+/);
44402
+ for (const attrValue of attributeValues) {
44403
+ if (!attrNomme.regs.some((pattern) => pattern.test(attrValue))) {
44404
+ const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan);
44405
+ context.report({
44406
+ loc,
44407
+ messageId: "invalidNaming",
44408
+ data: {
44409
+ attribute: node.name,
44410
+ value: attrValue,
44411
+ conventions: attrNomme.noms
44412
+ }
44413
+ });
44414
+ }
44415
+ }
44416
+ }
44417
+ }
44418
+ }
44419
+ };
44420
+ }
44421
+ });
44422
+
44423
+ // src/rules/template/prefer-class-style-binding.ts
44424
+ var import_utils11 = __toESM(require_dist6());
44425
+ var import_utils12 = __toESM(require_dist4());
44426
+ var RULE_NAME9 = "template/prefer-class-style-binding";
44427
+ var DOCS_RULES5 = "https://github.com/developpement-megao/mgw-eslint-rules/tree/main/docs/rules";
44428
+ var createRule9 = import_utils12.ESLintUtils.RuleCreator((name) => `${DOCS_RULES5}/${name}.md`);
44429
+ var rule9 = createRule9({
44430
+ name: RULE_NAME9,
44319
44431
  meta: {
44320
44432
  type: "suggestion",
44321
44433
  docs: {
@@ -44330,7 +44442,7 @@ var rule8 = createRule8({
44330
44442
  },
44331
44443
  defaultOptions: [],
44332
44444
  create(context) {
44333
- const parserServices = (0, import_utils9.getTemplateParserServices)(context);
44445
+ const parserServices = (0, import_utils11.getTemplateParserServices)(context);
44334
44446
  return {
44335
44447
  // Détecte les attributs ngClass et ngStyle et inputs [ngClass] et [ngStyle] dans les templates
44336
44448
  Element(node) {
@@ -44356,9 +44468,10 @@ var rules = {
44356
44468
  [RULE_NAME3]: rule3,
44357
44469
  [RULE_NAME4]: rule4,
44358
44470
  [RULE_NAME]: rule,
44359
- [RULE_NAME8]: rule8,
44471
+ [RULE_NAME9]: rule9,
44360
44472
  [RULE_NAME7]: rule7,
44361
- [RULE_NAME2]: rule2
44473
+ [RULE_NAME2]: rule2,
44474
+ [RULE_NAME8]: rule8
44362
44475
  };
44363
44476
  // Annotate the CommonJS export names for ESM import in node:
44364
44477
  0 && (module.exports = {