eslint-plugin-nextfriday 1.1.1 → 1.2.0

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/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "eslint-plugin-nextfriday",
4
- version: "1.1.1",
4
+ version: "1.2.0",
5
5
  description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
6
6
  keywords: [
7
7
  "eslint",
@@ -116,10 +116,102 @@ var package_default = {
116
116
  }
117
117
  };
118
118
 
119
+ // src/rules/enforce-readonly-component-props.ts
120
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
121
+ var createRule = ESLintUtils.RuleCreator(
122
+ (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
123
+ );
124
+ var enforceReadonlyComponentProps = createRule({
125
+ name: "enforce-readonly-component-props",
126
+ meta: {
127
+ type: "suggestion",
128
+ docs: {
129
+ description: "Enforce Readonly wrapper for React component props when using named types or interfaces"
130
+ },
131
+ fixable: "code",
132
+ schema: [],
133
+ messages: {
134
+ useReadonly: "Component props should be wrapped with Readonly<> for immutability"
135
+ }
136
+ },
137
+ defaultOptions: [],
138
+ create(context) {
139
+ function hasJSXInConditional(node) {
140
+ return node.consequent.type === AST_NODE_TYPES.JSXElement || node.consequent.type === AST_NODE_TYPES.JSXFragment || node.alternate.type === AST_NODE_TYPES.JSXElement || node.alternate.type === AST_NODE_TYPES.JSXFragment;
141
+ }
142
+ function hasJSXInLogical(node) {
143
+ return node.right.type === AST_NODE_TYPES.JSXElement || node.right.type === AST_NODE_TYPES.JSXFragment;
144
+ }
145
+ function hasJSXReturn(block) {
146
+ return block.body.some((stmt) => {
147
+ if (stmt.type === AST_NODE_TYPES.ReturnStatement && stmt.argument) {
148
+ return stmt.argument.type === AST_NODE_TYPES.JSXElement || stmt.argument.type === AST_NODE_TYPES.JSXFragment || stmt.argument.type === AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
149
+ }
150
+ return false;
151
+ });
152
+ }
153
+ function isReactComponent(node) {
154
+ if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
155
+ if (node.body.type === AST_NODE_TYPES.JSXElement || node.body.type === AST_NODE_TYPES.JSXFragment) {
156
+ return true;
157
+ }
158
+ if (node.body.type === AST_NODE_TYPES.BlockStatement) {
159
+ return hasJSXReturn(node.body);
160
+ }
161
+ } else if (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.FunctionDeclaration) {
162
+ if (node.body && node.body.type === AST_NODE_TYPES.BlockStatement) {
163
+ return hasJSXReturn(node.body);
164
+ }
165
+ }
166
+ return false;
167
+ }
168
+ function isNamedType(node) {
169
+ return node.type === AST_NODE_TYPES.TSTypeReference;
170
+ }
171
+ function isAlreadyReadonly(node) {
172
+ if (node.type === AST_NODE_TYPES.TSTypeReference && node.typeName) {
173
+ if (node.typeName.type === AST_NODE_TYPES.Identifier && node.typeName.name === "Readonly") {
174
+ return true;
175
+ }
176
+ }
177
+ return false;
178
+ }
179
+ function checkFunction(node) {
180
+ if (!isReactComponent(node)) {
181
+ return;
182
+ }
183
+ if (node.params.length !== 1) {
184
+ return;
185
+ }
186
+ const param = node.params[0];
187
+ if (param.type === AST_NODE_TYPES.Identifier && param.typeAnnotation) {
188
+ const { typeAnnotation } = param.typeAnnotation;
189
+ if (isNamedType(typeAnnotation) && !isAlreadyReadonly(typeAnnotation)) {
190
+ const { sourceCode } = context;
191
+ const typeText = sourceCode.getText(typeAnnotation);
192
+ context.report({
193
+ node: param.typeAnnotation,
194
+ messageId: "useReadonly",
195
+ fix(fixer) {
196
+ return fixer.replaceText(typeAnnotation, `Readonly<${typeText}>`);
197
+ }
198
+ });
199
+ }
200
+ }
201
+ }
202
+ return {
203
+ ArrowFunctionExpression: checkFunction,
204
+ FunctionExpression: checkFunction,
205
+ FunctionDeclaration: checkFunction
206
+ };
207
+ }
208
+ });
209
+ var enforce_readonly_component_props_default = enforceReadonlyComponentProps;
210
+
119
211
  // src/rules/file-kebab-case.ts
120
212
  import path from "path";
121
- import { ESLintUtils } from "@typescript-eslint/utils";
122
- var createRule = ESLintUtils.RuleCreator(
213
+ import { ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
214
+ var createRule2 = ESLintUtils2.RuleCreator(
123
215
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
124
216
  );
125
217
  var isKebabCase = (str) => {
@@ -128,7 +220,7 @@ var isKebabCase = (str) => {
128
220
  }
129
221
  return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str);
130
222
  };
131
- var fileKebabCase = createRule({
223
+ var fileKebabCase = createRule2({
132
224
  name: "file-kebab-case",
133
225
  meta: {
134
226
  type: "problem",
@@ -164,12 +256,12 @@ var file_kebab_case_default = fileKebabCase;
164
256
 
165
257
  // src/rules/jsx-pascal-case.ts
166
258
  import path2 from "path";
167
- import { ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
168
- var createRule2 = ESLintUtils2.RuleCreator(
259
+ import { ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
260
+ var createRule3 = ESLintUtils3.RuleCreator(
169
261
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
170
262
  );
171
263
  var isPascalCase = (str) => /^[A-Z][a-zA-Z0-9]*$/.test(str) && !/^[A-Z]+$/.test(str);
172
- var jsxPascalCase = createRule2({
264
+ var jsxPascalCase = createRule3({
173
265
  name: "jsx-pascal-case",
174
266
  meta: {
175
267
  type: "problem",
@@ -205,11 +297,11 @@ var jsx_pascal_case_default = jsxPascalCase;
205
297
 
206
298
  // src/rules/md-filename-case-restriction.ts
207
299
  import path3 from "path";
208
- import { ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
209
- var createRule3 = ESLintUtils3.RuleCreator(
300
+ import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
301
+ var createRule4 = ESLintUtils4.RuleCreator(
210
302
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
211
303
  );
212
- var mdFilenameCaseRestriction = createRule3({
304
+ var mdFilenameCaseRestriction = createRule4({
213
305
  name: "md-filename-case-restriction",
214
306
  meta: {
215
307
  type: "problem",
@@ -251,11 +343,11 @@ var md_filename_case_restriction_default = mdFilenameCaseRestriction;
251
343
 
252
344
  // src/rules/no-emoji.ts
253
345
  import emojiRegex from "emoji-regex";
254
- import { ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
255
- var createRule4 = ESLintUtils4.RuleCreator(
346
+ import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
347
+ var createRule5 = ESLintUtils5.RuleCreator(
256
348
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
257
349
  );
258
- var noEmoji = createRule4({
350
+ var noEmoji = createRule5({
259
351
  name: "no-emoji",
260
352
  meta: {
261
353
  type: "problem",
@@ -289,11 +381,11 @@ var noEmoji = createRule4({
289
381
  var no_emoji_default = noEmoji;
290
382
 
291
383
  // src/rules/no-explicit-return-type.ts
292
- import { ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
293
- var createRule5 = ESLintUtils5.RuleCreator(
384
+ import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
385
+ var createRule6 = ESLintUtils6.RuleCreator(
294
386
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
295
387
  );
296
- var noExplicitReturnType = createRule5({
388
+ var noExplicitReturnType = createRule6({
297
389
  name: "no-explicit-return-type",
298
390
  meta: {
299
391
  type: "suggestion",
@@ -333,11 +425,11 @@ var noExplicitReturnType = createRule5({
333
425
  var no_explicit_return_type_default = noExplicitReturnType;
334
426
 
335
427
  // src/rules/prefer-destructuring-params.ts
336
- import { AST_NODE_TYPES, ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
337
- var createRule6 = ESLintUtils6.RuleCreator(
428
+ import { AST_NODE_TYPES as AST_NODE_TYPES2, ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
429
+ var createRule7 = ESLintUtils7.RuleCreator(
338
430
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
339
431
  );
340
- var preferDestructuringParams = createRule6({
432
+ var preferDestructuringParams = createRule7({
341
433
  name: "prefer-destructuring-params",
342
434
  meta: {
343
435
  type: "suggestion",
@@ -356,7 +448,7 @@ var preferDestructuringParams = createRule6({
356
448
  return;
357
449
  }
358
450
  const hasNonDestructuredParams = node.params.some(
359
- (param) => param.type !== AST_NODE_TYPES.ObjectPattern && param.type !== AST_NODE_TYPES.RestElement
451
+ (param) => param.type !== AST_NODE_TYPES2.ObjectPattern && param.type !== AST_NODE_TYPES2.RestElement
360
452
  );
361
453
  if (hasNonDestructuredParams) {
362
454
  context.report({
@@ -375,11 +467,11 @@ var preferDestructuringParams = createRule6({
375
467
  var prefer_destructuring_params_default = preferDestructuringParams;
376
468
 
377
469
  // src/rules/prefer-import-type.ts
378
- import { AST_NODE_TYPES as AST_NODE_TYPES2, ESLintUtils as ESLintUtils7 } from "@typescript-eslint/utils";
379
- var createRule7 = ESLintUtils7.RuleCreator(
470
+ import { AST_NODE_TYPES as AST_NODE_TYPES3, ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
471
+ var createRule8 = ESLintUtils8.RuleCreator(
380
472
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
381
473
  );
382
- var preferImportType = createRule7({
474
+ var preferImportType = createRule8({
383
475
  name: "prefer-import-type",
384
476
  meta: {
385
477
  type: "suggestion",
@@ -410,14 +502,14 @@ var preferImportType = createRule7({
410
502
  return;
411
503
  }
412
504
  const isTypeOnlyImport = node.specifiers.every((specifier) => {
413
- if (specifier.type === AST_NODE_TYPES2.ImportDefaultSpecifier) {
505
+ if (specifier.type === AST_NODE_TYPES3.ImportDefaultSpecifier) {
414
506
  return false;
415
507
  }
416
- if (specifier.type === AST_NODE_TYPES2.ImportNamespaceSpecifier) {
508
+ if (specifier.type === AST_NODE_TYPES3.ImportNamespaceSpecifier) {
417
509
  return false;
418
510
  }
419
- if (specifier.type === AST_NODE_TYPES2.ImportSpecifier) {
420
- const importedName = specifier.imported.type === AST_NODE_TYPES2.Identifier ? specifier.imported.name : specifier.imported.value;
511
+ if (specifier.type === AST_NODE_TYPES3.ImportSpecifier) {
512
+ const importedName = specifier.imported.type === AST_NODE_TYPES3.Identifier ? specifier.imported.name : specifier.imported.value;
421
513
  const isKnownTypeOnly = node.source.value === "@typescript-eslint/utils" && ["TSESTree", "RuleContext"].includes(importedName) || node.source.value === "react" && ["Component", "ComponentProps", "ReactNode", "FC", "JSX", "ReactElement", "PropsWithChildren"].includes(
422
514
  importedName
423
515
  ) || importedName.endsWith("Type") || importedName.endsWith("Interface") || importedName.endsWith("Props");
@@ -445,11 +537,11 @@ var preferImportType = createRule7({
445
537
  var prefer_import_type_default = preferImportType;
446
538
 
447
539
  // src/rules/prefer-interface-over-inline-types.ts
448
- import { AST_NODE_TYPES as AST_NODE_TYPES3, ESLintUtils as ESLintUtils8 } from "@typescript-eslint/utils";
449
- var createRule8 = ESLintUtils8.RuleCreator(
540
+ import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
541
+ var createRule9 = ESLintUtils9.RuleCreator(
450
542
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
451
543
  );
452
- var preferInterfaceOverInlineTypes = createRule8({
544
+ var preferInterfaceOverInlineTypes = createRule9({
453
545
  name: "prefer-interface-over-inline-types",
454
546
  meta: {
455
547
  type: "suggestion",
@@ -465,54 +557,54 @@ var preferInterfaceOverInlineTypes = createRule8({
465
557
  defaultOptions: [],
466
558
  create(context) {
467
559
  function hasJSXInConditional(node) {
468
- return node.consequent.type === AST_NODE_TYPES3.JSXElement || node.consequent.type === AST_NODE_TYPES3.JSXFragment || node.alternate.type === AST_NODE_TYPES3.JSXElement || node.alternate.type === AST_NODE_TYPES3.JSXFragment;
560
+ return node.consequent.type === AST_NODE_TYPES4.JSXElement || node.consequent.type === AST_NODE_TYPES4.JSXFragment || node.alternate.type === AST_NODE_TYPES4.JSXElement || node.alternate.type === AST_NODE_TYPES4.JSXFragment;
469
561
  }
470
562
  function hasJSXInLogical(node) {
471
- return node.right.type === AST_NODE_TYPES3.JSXElement || node.right.type === AST_NODE_TYPES3.JSXFragment;
563
+ return node.right.type === AST_NODE_TYPES4.JSXElement || node.right.type === AST_NODE_TYPES4.JSXFragment;
472
564
  }
473
565
  function hasJSXReturn(block) {
474
566
  return block.body.some((stmt) => {
475
- if (stmt.type === AST_NODE_TYPES3.ReturnStatement && stmt.argument) {
476
- return stmt.argument.type === AST_NODE_TYPES3.JSXElement || stmt.argument.type === AST_NODE_TYPES3.JSXFragment || stmt.argument.type === AST_NODE_TYPES3.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES3.LogicalExpression && hasJSXInLogical(stmt.argument);
567
+ if (stmt.type === AST_NODE_TYPES4.ReturnStatement && stmt.argument) {
568
+ return stmt.argument.type === AST_NODE_TYPES4.JSXElement || stmt.argument.type === AST_NODE_TYPES4.JSXFragment || stmt.argument.type === AST_NODE_TYPES4.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES4.LogicalExpression && hasJSXInLogical(stmt.argument);
477
569
  }
478
570
  return false;
479
571
  });
480
572
  }
481
573
  function isReactComponent(node) {
482
- if (node.type === AST_NODE_TYPES3.ArrowFunctionExpression) {
483
- if (node.body.type === AST_NODE_TYPES3.JSXElement || node.body.type === AST_NODE_TYPES3.JSXFragment) {
574
+ if (node.type === AST_NODE_TYPES4.ArrowFunctionExpression) {
575
+ if (node.body.type === AST_NODE_TYPES4.JSXElement || node.body.type === AST_NODE_TYPES4.JSXFragment) {
484
576
  return true;
485
577
  }
486
- if (node.body.type === AST_NODE_TYPES3.BlockStatement) {
578
+ if (node.body.type === AST_NODE_TYPES4.BlockStatement) {
487
579
  return hasJSXReturn(node.body);
488
580
  }
489
- } else if (node.type === AST_NODE_TYPES3.FunctionExpression || node.type === AST_NODE_TYPES3.FunctionDeclaration) {
490
- if (node.body && node.body.type === AST_NODE_TYPES3.BlockStatement) {
581
+ } else if (node.type === AST_NODE_TYPES4.FunctionExpression || node.type === AST_NODE_TYPES4.FunctionDeclaration) {
582
+ if (node.body && node.body.type === AST_NODE_TYPES4.BlockStatement) {
491
583
  return hasJSXReturn(node.body);
492
584
  }
493
585
  }
494
586
  return false;
495
587
  }
496
588
  function isInlineTypeAnnotation(node) {
497
- if (node.type === AST_NODE_TYPES3.TSTypeLiteral) {
589
+ if (node.type === AST_NODE_TYPES4.TSTypeLiteral) {
498
590
  return true;
499
591
  }
500
- if (node.type === AST_NODE_TYPES3.TSTypeReference && node.typeArguments) {
501
- return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES3.TSTypeLiteral);
592
+ if (node.type === AST_NODE_TYPES4.TSTypeReference && node.typeArguments) {
593
+ return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES4.TSTypeLiteral);
502
594
  }
503
- if (node.type === AST_NODE_TYPES3.TSUnionType) {
595
+ if (node.type === AST_NODE_TYPES4.TSUnionType) {
504
596
  return node.types.some((type) => isInlineTypeAnnotation(type));
505
597
  }
506
598
  return false;
507
599
  }
508
600
  function hasInlineObjectType(node) {
509
- if (node.type === AST_NODE_TYPES3.TSTypeLiteral) {
601
+ if (node.type === AST_NODE_TYPES4.TSTypeLiteral) {
510
602
  return true;
511
603
  }
512
- if (node.type === AST_NODE_TYPES3.TSTypeReference && node.typeArguments) {
513
- return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES3.TSTypeLiteral);
604
+ if (node.type === AST_NODE_TYPES4.TSTypeReference && node.typeArguments) {
605
+ return node.typeArguments.params.some((param) => param.type === AST_NODE_TYPES4.TSTypeLiteral);
514
606
  }
515
- if (node.type === AST_NODE_TYPES3.TSUnionType) {
607
+ if (node.type === AST_NODE_TYPES4.TSUnionType) {
516
608
  return node.types.some((type) => hasInlineObjectType(type));
517
609
  }
518
610
  return false;
@@ -525,7 +617,7 @@ var preferInterfaceOverInlineTypes = createRule8({
525
617
  return;
526
618
  }
527
619
  const param = node.params[0];
528
- if (param.type === AST_NODE_TYPES3.Identifier && param.typeAnnotation) {
620
+ if (param.type === AST_NODE_TYPES4.Identifier && param.typeAnnotation) {
529
621
  const { typeAnnotation } = param.typeAnnotation;
530
622
  if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
531
623
  context.report({
@@ -545,11 +637,11 @@ var preferInterfaceOverInlineTypes = createRule8({
545
637
  var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
546
638
 
547
639
  // src/rules/prefer-react-import-types.ts
548
- import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils9 } from "@typescript-eslint/utils";
549
- var createRule9 = ESLintUtils9.RuleCreator(
640
+ import { AST_NODE_TYPES as AST_NODE_TYPES5, ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
641
+ var createRule10 = ESLintUtils10.RuleCreator(
550
642
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
551
643
  );
552
- var preferReactImportTypes = createRule9({
644
+ var preferReactImportTypes = createRule10({
553
645
  name: "prefer-react-import-types",
554
646
  meta: {
555
647
  type: "suggestion",
@@ -625,7 +717,7 @@ var preferReactImportTypes = createRule9({
625
717
  ]);
626
718
  const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
627
719
  function checkMemberExpression(node) {
628
- if (node.object.type === AST_NODE_TYPES4.Identifier && node.object.name === "React" && node.property.type === AST_NODE_TYPES4.Identifier && allReactExports.has(node.property.name)) {
720
+ if (node.object.type === AST_NODE_TYPES5.Identifier && node.object.name === "React" && node.property.type === AST_NODE_TYPES5.Identifier && allReactExports.has(node.property.name)) {
629
721
  const typeName = node.property.name;
630
722
  const isType = reactTypes.has(typeName);
631
723
  const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
@@ -642,7 +734,7 @@ var preferReactImportTypes = createRule9({
642
734
  return {
643
735
  MemberExpression: checkMemberExpression,
644
736
  "TSTypeReference > TSQualifiedName": (node) => {
645
- if (node.left.type === AST_NODE_TYPES4.Identifier && node.left.name === "React" && node.right.type === AST_NODE_TYPES4.Identifier && allReactExports.has(node.right.name)) {
737
+ if (node.left.type === AST_NODE_TYPES5.Identifier && node.left.name === "React" && node.right.type === AST_NODE_TYPES5.Identifier && allReactExports.has(node.right.name)) {
646
738
  const typeName = node.right.name;
647
739
  const isType = reactTypes.has(typeName);
648
740
  const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
@@ -662,11 +754,11 @@ var preferReactImportTypes = createRule9({
662
754
  var prefer_react_import_types_default = preferReactImportTypes;
663
755
 
664
756
  // src/rules/react-props-destructure.ts
665
- import { AST_NODE_TYPES as AST_NODE_TYPES5, ESLintUtils as ESLintUtils10 } from "@typescript-eslint/utils";
666
- var createRule10 = ESLintUtils10.RuleCreator(
757
+ import { AST_NODE_TYPES as AST_NODE_TYPES6, ESLintUtils as ESLintUtils11 } from "@typescript-eslint/utils";
758
+ var createRule11 = ESLintUtils11.RuleCreator(
667
759
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name}.md`
668
760
  );
669
- var reactPropsDestructure = createRule10({
761
+ var reactPropsDestructure = createRule11({
670
762
  name: "react-props-destructure",
671
763
  meta: {
672
764
  type: "suggestion",
@@ -682,29 +774,29 @@ var reactPropsDestructure = createRule10({
682
774
  defaultOptions: [],
683
775
  create(context) {
684
776
  function hasJSXInConditional(node) {
685
- return node.consequent.type === AST_NODE_TYPES5.JSXElement || node.consequent.type === AST_NODE_TYPES5.JSXFragment || node.alternate.type === AST_NODE_TYPES5.JSXElement || node.alternate.type === AST_NODE_TYPES5.JSXFragment;
777
+ return node.consequent.type === AST_NODE_TYPES6.JSXElement || node.consequent.type === AST_NODE_TYPES6.JSXFragment || node.alternate.type === AST_NODE_TYPES6.JSXElement || node.alternate.type === AST_NODE_TYPES6.JSXFragment;
686
778
  }
687
779
  function hasJSXInLogical(node) {
688
- return node.right.type === AST_NODE_TYPES5.JSXElement || node.right.type === AST_NODE_TYPES5.JSXFragment;
780
+ return node.right.type === AST_NODE_TYPES6.JSXElement || node.right.type === AST_NODE_TYPES6.JSXFragment;
689
781
  }
690
782
  function hasJSXReturn(block) {
691
783
  return block.body.some((stmt) => {
692
- if (stmt.type === AST_NODE_TYPES5.ReturnStatement && stmt.argument) {
693
- return stmt.argument.type === AST_NODE_TYPES5.JSXElement || stmt.argument.type === AST_NODE_TYPES5.JSXFragment || stmt.argument.type === AST_NODE_TYPES5.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES5.LogicalExpression && hasJSXInLogical(stmt.argument);
784
+ if (stmt.type === AST_NODE_TYPES6.ReturnStatement && stmt.argument) {
785
+ return stmt.argument.type === AST_NODE_TYPES6.JSXElement || stmt.argument.type === AST_NODE_TYPES6.JSXFragment || stmt.argument.type === AST_NODE_TYPES6.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === AST_NODE_TYPES6.LogicalExpression && hasJSXInLogical(stmt.argument);
694
786
  }
695
787
  return false;
696
788
  });
697
789
  }
698
790
  function isReactComponent(node) {
699
- if (node.type === AST_NODE_TYPES5.ArrowFunctionExpression) {
700
- if (node.body.type === AST_NODE_TYPES5.JSXElement || node.body.type === AST_NODE_TYPES5.JSXFragment) {
791
+ if (node.type === AST_NODE_TYPES6.ArrowFunctionExpression) {
792
+ if (node.body.type === AST_NODE_TYPES6.JSXElement || node.body.type === AST_NODE_TYPES6.JSXFragment) {
701
793
  return true;
702
794
  }
703
- if (node.body.type === AST_NODE_TYPES5.BlockStatement) {
795
+ if (node.body.type === AST_NODE_TYPES6.BlockStatement) {
704
796
  return hasJSXReturn(node.body);
705
797
  }
706
- } else if (node.type === AST_NODE_TYPES5.FunctionExpression || node.type === AST_NODE_TYPES5.FunctionDeclaration) {
707
- if (node.body && node.body.type === AST_NODE_TYPES5.BlockStatement) {
798
+ } else if (node.type === AST_NODE_TYPES6.FunctionExpression || node.type === AST_NODE_TYPES6.FunctionDeclaration) {
799
+ if (node.body && node.body.type === AST_NODE_TYPES6.BlockStatement) {
708
800
  return hasJSXReturn(node.body);
709
801
  }
710
802
  }
@@ -718,9 +810,9 @@ var reactPropsDestructure = createRule10({
718
810
  return;
719
811
  }
720
812
  const param = node.params[0];
721
- if (param.type === AST_NODE_TYPES5.ObjectPattern) {
722
- const properties = param.properties.filter((prop) => prop.type === AST_NODE_TYPES5.Property).map((prop) => {
723
- if (prop.key.type === AST_NODE_TYPES5.Identifier) {
813
+ if (param.type === AST_NODE_TYPES6.ObjectPattern) {
814
+ const properties = param.properties.filter((prop) => prop.type === AST_NODE_TYPES6.Property).map((prop) => {
815
+ if (prop.key.type === AST_NODE_TYPES6.Identifier) {
724
816
  return prop.key.name;
725
817
  }
726
818
  return null;
@@ -752,6 +844,7 @@ var meta = {
752
844
  version: package_default.version
753
845
  };
754
846
  var rules = {
847
+ "enforce-readonly-component-props": enforce_readonly_component_props_default,
755
848
  "file-kebab-case": file_kebab_case_default,
756
849
  "jsx-pascal-case": jsx_pascal_case_default,
757
850
  "md-filename-case-restriction": md_filename_case_restriction_default,
@@ -788,12 +881,14 @@ var baseRecommendedRules = {
788
881
  var jsxRules = {
789
882
  "nextfriday/jsx-pascal-case": "warn",
790
883
  "nextfriday/prefer-interface-over-inline-types": "warn",
791
- "nextfriday/react-props-destructure": "warn"
884
+ "nextfriday/react-props-destructure": "warn",
885
+ "nextfriday/enforce-readonly-component-props": "warn"
792
886
  };
793
887
  var jsxRecommendedRules = {
794
888
  "nextfriday/jsx-pascal-case": "error",
795
889
  "nextfriday/prefer-interface-over-inline-types": "error",
796
- "nextfriday/react-props-destructure": "error"
890
+ "nextfriday/react-props-destructure": "error",
891
+ "nextfriday/enforce-readonly-component-props": "error"
797
892
  };
798
893
  var createConfig = (configRules) => ({
799
894
  plugins: {