eslint-plugin-react-naming-convention 2.13.0-next.1 → 2.13.0-next.2

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.
Files changed (2) hide show
  1. package/dist/index.js +196 -198
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -5,10 +5,10 @@ import { findEnclosingAssignmentTarget } from "@eslint-react/var";
5
5
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
6
6
  import { compare } from "compare-versions";
7
7
  import { P, match } from "ts-pattern";
8
- import path from "node:path";
8
+ import * as ast from "@eslint-react/ast";
9
9
  import { camelCase, kebabCase, pascalCase, snakeCase } from "string-ts";
10
+ import path from "node:path";
10
11
  import { isObject } from "@eslint-react/eff";
11
- import * as ast from "@eslint-react/ast";
12
12
 
13
13
  //#region \0rolldown/runtime.js
14
14
  var __defProp = Object.defineProperty;
@@ -43,7 +43,7 @@ const rules = {
43
43
  //#endregion
44
44
  //#region package.json
45
45
  var name = "eslint-plugin-react-naming-convention";
46
- var version = "2.13.0-next.1";
46
+ var version = "2.13.0-next.2";
47
47
 
48
48
  //#endregion
49
49
  //#region src/utils/create-rule.ts
@@ -184,9 +184,175 @@ function create$5(context) {
184
184
  }
185
185
 
186
186
  //#endregion
187
- //#region src/rules/file-name.ts
188
- const RULE_NAME$4 = "file-name";
187
+ //#region src/rules/id-name.ts
188
+ const RULE_NAME$4 = "id-name";
189
+ var id_name_default = createRule({
190
+ meta: {
191
+ type: "suggestion",
192
+ docs: { description: "Enforces identifier names assigned from 'useId' calls to be either 'id' or end with 'Id'." },
193
+ messages: { invalidIdName: "An identifier assigned from 'useId' must be named 'id' or end with 'Id'." },
194
+ schema: []
195
+ },
196
+ name: RULE_NAME$4,
197
+ create: create$4,
198
+ defaultOptions: []
199
+ });
200
+ function create$4(context) {
201
+ if (!context.sourceCode.text.includes("useId")) return {};
202
+ return { CallExpression(node) {
203
+ if (!core.isUseIdCall(node)) return;
204
+ const [id, name] = match(findEnclosingAssignmentTarget(node)).with({
205
+ type: AST_NODE_TYPES.Identifier,
206
+ name: P.string
207
+ }, (id) => [id, id.name]).with({
208
+ type: AST_NODE_TYPES.MemberExpression,
209
+ property: { name: P.string }
210
+ }, (id) => [id, id.property.name]).otherwise(() => [null, null]);
211
+ if (id == null) return;
212
+ if (name.endsWith("Id") || name === "id") return;
213
+ context.report({
214
+ messageId: "invalidIdName",
215
+ node: id
216
+ });
217
+ } };
218
+ }
219
+
220
+ //#endregion
221
+ //#region src/rules/ref-name.ts
222
+ const RULE_NAME$3 = "ref-name";
223
+ var ref_name_default = createRule({
224
+ meta: {
225
+ type: "suggestion",
226
+ docs: { description: "Enforces identifier names assigned from 'useRef' calls to be either 'ref' or end with 'Ref'." },
227
+ messages: { invalidRefName: "A ref identifier must be named 'ref' or ending in 'Ref'." },
228
+ schema: []
229
+ },
230
+ name: RULE_NAME$3,
231
+ create: create$3,
232
+ defaultOptions: []
233
+ });
234
+ function create$3(context) {
235
+ if (!context.sourceCode.text.includes("useRef")) return {};
236
+ return { CallExpression(node) {
237
+ if (!core.isUseRefCall(node)) return;
238
+ if (ast.getUnderlyingExpression(node.parent).type === AST_NODE_TYPES.MemberExpression) return;
239
+ const [id, name] = match(findEnclosingAssignmentTarget(node)).with({
240
+ type: AST_NODE_TYPES.Identifier,
241
+ name: P.string
242
+ }, (id) => [id, id.name]).with({
243
+ type: AST_NODE_TYPES.MemberExpression,
244
+ property: { name: P.string }
245
+ }, (id) => [id, id.property.name]).otherwise(() => [null, null]);
246
+ if (id == null) return;
247
+ if (name.endsWith("Ref") || name === "ref") return;
248
+ context.report({
249
+ messageId: "invalidRefName",
250
+ node: id
251
+ });
252
+ } };
253
+ }
254
+
255
+ //#endregion
256
+ //#region src/rules/use-state.ts
257
+ const RULE_NAME$2 = "use-state";
189
258
  const defaultOptions$2 = [{
259
+ enforceAssignment: false,
260
+ enforceSetterName: true
261
+ }];
262
+ const schema$2 = [{
263
+ type: "object",
264
+ additionalProperties: false,
265
+ properties: {
266
+ enforceAssignment: {
267
+ type: "boolean",
268
+ default: false
269
+ },
270
+ enforceSetterName: {
271
+ type: "boolean",
272
+ default: true
273
+ }
274
+ }
275
+ }];
276
+ var use_state_default = createRule({
277
+ meta: {
278
+ type: "suggestion",
279
+ docs: { description: "Enforces destructuring and symmetric naming of the 'useState' hook value and setter." },
280
+ messages: {
281
+ invalidAssignment: "useState should be destructured into a value and setter pair, e.g., const [state, setState] = useState(...).",
282
+ invalidSetterName: "The setter should be named 'set' followed by the capitalized state variable name, e.g., 'setState' for 'state'."
283
+ },
284
+ schema: schema$2
285
+ },
286
+ name: RULE_NAME$2,
287
+ create: create$2,
288
+ defaultOptions: defaultOptions$2
289
+ });
290
+ function create$2(context) {
291
+ const { enforceAssignment = false, enforceSetterName = true } = context.options[0] ?? defaultOptions$2[0];
292
+ return { CallExpression(node) {
293
+ if (!core.isUseStateCall(node)) return;
294
+ if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
295
+ if (!enforceAssignment) return;
296
+ context.report({
297
+ messageId: "invalidAssignment",
298
+ node
299
+ });
300
+ return;
301
+ }
302
+ const id = findEnclosingAssignmentTarget(node);
303
+ if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
304
+ if (!enforceAssignment) return;
305
+ context.report({
306
+ messageId: "invalidAssignment",
307
+ node: id ?? node
308
+ });
309
+ return;
310
+ }
311
+ const [value, setter] = id.elements;
312
+ if (value == null) {
313
+ if (!enforceAssignment) return;
314
+ context.report({
315
+ messageId: "invalidAssignment",
316
+ node: id
317
+ });
318
+ return;
319
+ }
320
+ if (setter == null || !enforceSetterName) return;
321
+ const setterName = match(setter).with({ type: AST_NODE_TYPES.Identifier }, (id) => id.name).otherwise(() => null);
322
+ if (setterName == null || !setterName.startsWith("set")) {
323
+ context.report({
324
+ messageId: "invalidSetterName",
325
+ node: setter
326
+ });
327
+ return;
328
+ }
329
+ const valueName = match(value).with({ type: AST_NODE_TYPES.Identifier }, ({ name }) => snakeCase(name)).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
330
+ return properties.reduce((acc, prop) => {
331
+ if (prop.type === AST_NODE_TYPES.Property && prop.key.type === AST_NODE_TYPES.Identifier) return [...acc, prop.key.name];
332
+ return acc;
333
+ }, []).join("_");
334
+ }).otherwise(() => null);
335
+ if (valueName == null) {
336
+ context.report({
337
+ messageId: "invalidSetterName",
338
+ node: value
339
+ });
340
+ return;
341
+ }
342
+ if (snakeCase(setterName) !== `set_${valueName}`) {
343
+ context.report({
344
+ messageId: "invalidSetterName",
345
+ node: setter
346
+ });
347
+ return;
348
+ }
349
+ } };
350
+ }
351
+
352
+ //#endregion
353
+ //#region src/rules-removed/filename.ts
354
+ const RULE_NAME$1 = "filename";
355
+ const defaultOptions$1 = [{
190
356
  excepts: [
191
357
  "index",
192
358
  String.raw`/^_/`,
@@ -196,7 +362,7 @@ const defaultOptions$2 = [{
196
362
  ],
197
363
  rule: "PascalCase"
198
364
  }];
199
- const schema$2 = [{ anyOf: [{
365
+ const schema$1 = [{ anyOf: [{
200
366
  type: "string",
201
367
  enum: [
202
368
  "PascalCase",
@@ -231,23 +397,23 @@ const schema$2 = [{ anyOf: [{
231
397
  }
232
398
  }
233
399
  }] }];
234
- var file_name_default = createRule({
400
+ var filename_default = createRule({
235
401
  meta: {
236
402
  type: "suggestion",
237
- defaultOptions: [...defaultOptions$2],
403
+ defaultOptions: [...defaultOptions$1],
238
404
  docs: { description: "Enforces consistent file-naming conventions." },
239
405
  messages: {
240
406
  fileNameEmpty: "A source file must have non-empty name.",
241
407
  fileNameInvalidCase: "A source file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'."
242
408
  },
243
- schema: schema$2
409
+ schema: schema$1
244
410
  },
245
- name: RULE_NAME$4,
246
- create: create$4,
247
- defaultOptions: defaultOptions$2
411
+ name: RULE_NAME$1,
412
+ create: create$1,
413
+ defaultOptions: defaultOptions$1
248
414
  });
249
- function create$4(context) {
250
- const options = context.options[0] ?? defaultOptions$2[0];
415
+ function create$1(context) {
416
+ const options = context.options[0] ?? defaultOptions$1[0];
251
417
  const rule = typeof options === "string" ? options : options.rule ?? "PascalCase";
252
418
  const excepts = typeof options === "string" ? [] : (options.excepts ?? []).map((s) => toRegExp(s));
253
419
  function validate(name, casing = rule, ignores = excepts) {
@@ -282,14 +448,14 @@ function create$4(context) {
282
448
  }
283
449
 
284
450
  //#endregion
285
- //#region src/rules/file-name-extension.ts
286
- const RULE_NAME$3 = "file-name-extension";
287
- const defaultOptions$1 = [{
451
+ //#region src/rules-removed/filename-extension.ts
452
+ const RULE_NAME = "filename-extension";
453
+ const defaultOptions = [{
288
454
  allow: "as-needed",
289
455
  extensions: [".jsx", ".tsx"],
290
456
  ignoreFilesWithoutCode: false
291
457
  }];
292
- const schema$1 = [{ anyOf: [{
458
+ const schema = [{ anyOf: [{
293
459
  type: "string",
294
460
  enum: ["always", "as-needed"]
295
461
  }, {
@@ -308,25 +474,25 @@ const schema$1 = [{ anyOf: [{
308
474
  ignoreFilesWithoutCode: { type: "boolean" }
309
475
  }
310
476
  }] }];
311
- var file_name_extension_default = createRule({
477
+ var filename_extension_default = createRule({
312
478
  meta: {
313
479
  type: "suggestion",
314
- defaultOptions: [...defaultOptions$1],
480
+ defaultOptions: [...defaultOptions],
315
481
  docs: { description: "Enforces consistent use of the JSX file extension." },
316
482
  messages: {
317
483
  missingJsxExtension: "Use {{extensions}} file extension for JSX files.",
318
484
  unnecessaryJsxExtension: "Do not use {{extensions}} file extension for files without JSX."
319
485
  },
320
- schema: schema$1
486
+ schema
321
487
  },
322
- name: RULE_NAME$3,
323
- create: create$3,
324
- defaultOptions: defaultOptions$1
488
+ name: RULE_NAME,
489
+ create,
490
+ defaultOptions
325
491
  });
326
- function create$3(context) {
327
- const options = context.options[0] ?? defaultOptions$1[0];
492
+ function create(context) {
493
+ const options = context.options[0] ?? defaultOptions[0];
328
494
  const allow = isObject(options) ? options.allow : options;
329
- const extensions = isObject(options) && "extensions" in options ? options.extensions : defaultOptions$1[0].extensions;
495
+ const extensions = isObject(options) && "extensions" in options ? options.extensions : defaultOptions[0].extensions;
330
496
  const extensionsString = extensions.map((ext) => `'${ext}'`).join(", ");
331
497
  const filename = context.filename;
332
498
  let hasJSXNode = false;
@@ -360,172 +526,6 @@ function create$3(context) {
360
526
  };
361
527
  }
362
528
 
363
- //#endregion
364
- //#region src/rules/id-name.ts
365
- const RULE_NAME$2 = "id-name";
366
- var id_name_default = createRule({
367
- meta: {
368
- type: "suggestion",
369
- docs: { description: "Enforces identifier names assigned from 'useId' calls to be either 'id' or end with 'Id'." },
370
- messages: { invalidIdName: "An identifier assigned from 'useId' must be named 'id' or end with 'Id'." },
371
- schema: []
372
- },
373
- name: RULE_NAME$2,
374
- create: create$2,
375
- defaultOptions: []
376
- });
377
- function create$2(context) {
378
- if (!context.sourceCode.text.includes("useId")) return {};
379
- return { CallExpression(node) {
380
- if (!core.isUseIdCall(node)) return;
381
- const [id, name] = match(findEnclosingAssignmentTarget(node)).with({
382
- type: AST_NODE_TYPES.Identifier,
383
- name: P.string
384
- }, (id) => [id, id.name]).with({
385
- type: AST_NODE_TYPES.MemberExpression,
386
- property: { name: P.string }
387
- }, (id) => [id, id.property.name]).otherwise(() => [null, null]);
388
- if (id == null) return;
389
- if (name.endsWith("Id") || name === "id") return;
390
- context.report({
391
- messageId: "invalidIdName",
392
- node: id
393
- });
394
- } };
395
- }
396
-
397
- //#endregion
398
- //#region src/rules/ref-name.ts
399
- const RULE_NAME$1 = "ref-name";
400
- var ref_name_default = createRule({
401
- meta: {
402
- type: "suggestion",
403
- docs: { description: "Enforces identifier names assigned from 'useRef' calls to be either 'ref' or end with 'Ref'." },
404
- messages: { invalidRefName: "A ref identifier must be named 'ref' or ending in 'Ref'." },
405
- schema: []
406
- },
407
- name: RULE_NAME$1,
408
- create: create$1,
409
- defaultOptions: []
410
- });
411
- function create$1(context) {
412
- if (!context.sourceCode.text.includes("useRef")) return {};
413
- return { CallExpression(node) {
414
- if (!core.isUseRefCall(node)) return;
415
- if (ast.getUnderlyingExpression(node.parent).type === AST_NODE_TYPES.MemberExpression) return;
416
- const [id, name] = match(findEnclosingAssignmentTarget(node)).with({
417
- type: AST_NODE_TYPES.Identifier,
418
- name: P.string
419
- }, (id) => [id, id.name]).with({
420
- type: AST_NODE_TYPES.MemberExpression,
421
- property: { name: P.string }
422
- }, (id) => [id, id.property.name]).otherwise(() => [null, null]);
423
- if (id == null) return;
424
- if (name.endsWith("Ref") || name === "ref") return;
425
- context.report({
426
- messageId: "invalidRefName",
427
- node: id
428
- });
429
- } };
430
- }
431
-
432
- //#endregion
433
- //#region src/rules/use-state.ts
434
- const RULE_NAME = "use-state";
435
- const defaultOptions = [{
436
- enforceAssignment: false,
437
- enforceSetterName: true
438
- }];
439
- const schema = [{
440
- type: "object",
441
- additionalProperties: false,
442
- properties: {
443
- enforceAssignment: {
444
- type: "boolean",
445
- default: false
446
- },
447
- enforceSetterName: {
448
- type: "boolean",
449
- default: true
450
- }
451
- }
452
- }];
453
- var use_state_default = createRule({
454
- meta: {
455
- type: "suggestion",
456
- docs: { description: "Enforces destructuring and symmetric naming of the 'useState' hook value and setter." },
457
- messages: {
458
- invalidAssignment: "useState should be destructured into a value and setter pair, e.g., const [state, setState] = useState(...).",
459
- invalidSetterName: "The setter should be named 'set' followed by the capitalized state variable name, e.g., 'setState' for 'state'."
460
- },
461
- schema
462
- },
463
- name: RULE_NAME,
464
- create,
465
- defaultOptions
466
- });
467
- function create(context) {
468
- const { enforceAssignment = false, enforceSetterName = true } = context.options[0] ?? defaultOptions[0];
469
- return { CallExpression(node) {
470
- if (!core.isUseStateCall(node)) return;
471
- if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
472
- if (!enforceAssignment) return;
473
- context.report({
474
- messageId: "invalidAssignment",
475
- node
476
- });
477
- return;
478
- }
479
- const id = findEnclosingAssignmentTarget(node);
480
- if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
481
- if (!enforceAssignment) return;
482
- context.report({
483
- messageId: "invalidAssignment",
484
- node: id ?? node
485
- });
486
- return;
487
- }
488
- const [value, setter] = id.elements;
489
- if (value == null) {
490
- if (!enforceAssignment) return;
491
- context.report({
492
- messageId: "invalidAssignment",
493
- node: id
494
- });
495
- return;
496
- }
497
- if (setter == null || !enforceSetterName) return;
498
- const setterName = match(setter).with({ type: AST_NODE_TYPES.Identifier }, (id) => id.name).otherwise(() => null);
499
- if (setterName == null || !setterName.startsWith("set")) {
500
- context.report({
501
- messageId: "invalidSetterName",
502
- node: setter
503
- });
504
- return;
505
- }
506
- const valueName = match(value).with({ type: AST_NODE_TYPES.Identifier }, ({ name }) => snakeCase(name)).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
507
- return properties.reduce((acc, prop) => {
508
- if (prop.type === AST_NODE_TYPES.Property && prop.key.type === AST_NODE_TYPES.Identifier) return [...acc, prop.key.name];
509
- return acc;
510
- }, []).join("_");
511
- }).otherwise(() => null);
512
- if (valueName == null) {
513
- context.report({
514
- messageId: "invalidSetterName",
515
- node: value
516
- });
517
- return;
518
- }
519
- if (snakeCase(setterName) !== `set_${valueName}`) {
520
- context.report({
521
- messageId: "invalidSetterName",
522
- node: setter
523
- });
524
- return;
525
- }
526
- } };
527
- }
528
-
529
529
  //#endregion
530
530
  //#region src/plugin.ts
531
531
  const plugin = {
@@ -536,13 +536,11 @@ const plugin = {
536
536
  rules: {
537
537
  ["component-name"]: component_name_default,
538
538
  ["context-name"]: context_name_default,
539
- ["file-name"]: file_name_default,
540
- ["file-name-extension"]: file_name_extension_default,
541
- ["filename"]: file_name_default,
542
- ["filename-extension"]: file_name_extension_default,
543
539
  ["id-name"]: id_name_default,
544
540
  ["ref-name"]: ref_name_default,
545
- ["use-state"]: use_state_default
541
+ ["use-state"]: use_state_default,
542
+ ["filename"]: filename_default,
543
+ ["filename-extension"]: filename_extension_default
546
544
  }
547
545
  };
548
546
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-naming-convention",
3
- "version": "2.13.0-next.1",
3
+ "version": "2.13.0-next.2",
4
4
  "description": "ESLint React's ESLint plugin for naming convention related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -45,11 +45,11 @@
45
45
  "compare-versions": "^6.1.1",
46
46
  "string-ts": "^2.3.1",
47
47
  "ts-pattern": "^5.9.0",
48
- "@eslint-react/ast": "2.13.0-next.1",
49
- "@eslint-react/eff": "2.13.0-next.1",
50
- "@eslint-react/core": "2.13.0-next.1",
51
- "@eslint-react/shared": "2.13.0-next.1",
52
- "@eslint-react/var": "2.13.0-next.1"
48
+ "@eslint-react/ast": "2.13.0-next.2",
49
+ "@eslint-react/core": "2.13.0-next.2",
50
+ "@eslint-react/eff": "2.13.0-next.2",
51
+ "@eslint-react/shared": "2.13.0-next.2",
52
+ "@eslint-react/var": "2.13.0-next.2"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/react": "^19.2.14",