eslint-plugin-nextfriday 1.6.0 → 1.7.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.cjs CHANGED
@@ -40,7 +40,7 @@ module.exports = __toCommonJS(index_exports);
40
40
  // package.json
41
41
  var package_default = {
42
42
  name: "eslint-plugin-nextfriday",
43
- version: "1.6.0",
43
+ version: "1.7.0",
44
44
  description: "A comprehensive ESLint plugin providing custom rules and configurations for Next Friday development workflows.",
45
45
  keywords: [
46
46
  "eslint",
@@ -154,12 +154,143 @@ var package_default = {
154
154
  }
155
155
  };
156
156
 
157
- // src/rules/enforce-readonly-component-props.ts
157
+ // src/rules/boolean-naming-prefix.ts
158
158
  var import_utils = require("@typescript-eslint/utils");
159
159
  var createRule = import_utils.ESLintUtils.RuleCreator(
160
160
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
161
161
  );
162
- var enforceReadonlyComponentProps = createRule({
162
+ var BOOLEAN_PREFIXES = ["is", "has", "should", "can", "did", "will", "was", "are", "does", "had"];
163
+ var startsWithBooleanPrefix = (name) => {
164
+ const lowerName = name.toLowerCase();
165
+ return BOOLEAN_PREFIXES.some((prefix) => {
166
+ if (!lowerName.startsWith(prefix)) {
167
+ return false;
168
+ }
169
+ if (name.length === prefix.length) {
170
+ return true;
171
+ }
172
+ const nextChar = name.charAt(prefix.length);
173
+ return nextChar === nextChar.toUpperCase();
174
+ });
175
+ };
176
+ var isBooleanLiteral = (node) => node.type === import_utils.AST_NODE_TYPES.Literal && typeof node.value === "boolean";
177
+ var isBooleanExpression = (node) => {
178
+ if (isBooleanLiteral(node)) {
179
+ return true;
180
+ }
181
+ if (node.type === import_utils.AST_NODE_TYPES.UnaryExpression && node.operator === "!") {
182
+ return true;
183
+ }
184
+ if (node.type === import_utils.AST_NODE_TYPES.BinaryExpression) {
185
+ const comparisonOperators = ["===", "!==", "==", "!=", "<", ">", "<=", ">=", "in", "instanceof"];
186
+ return comparisonOperators.includes(node.operator);
187
+ }
188
+ if (node.type === import_utils.AST_NODE_TYPES.LogicalExpression) {
189
+ return node.operator === "&&" || node.operator === "||";
190
+ }
191
+ return false;
192
+ };
193
+ var hasBooleanTypeAnnotation = (node) => {
194
+ if (node.type === import_utils.AST_NODE_TYPES.Identifier) {
195
+ const { typeAnnotation } = node;
196
+ if (typeAnnotation?.typeAnnotation.type === import_utils.AST_NODE_TYPES.TSBooleanKeyword) {
197
+ return true;
198
+ }
199
+ }
200
+ if ("id" in node && node.id.type === import_utils.AST_NODE_TYPES.Identifier) {
201
+ const { typeAnnotation } = node.id;
202
+ if (typeAnnotation?.typeAnnotation.type === import_utils.AST_NODE_TYPES.TSBooleanKeyword) {
203
+ return true;
204
+ }
205
+ }
206
+ return false;
207
+ };
208
+ var booleanNamingPrefix = createRule({
209
+ name: "boolean-naming-prefix",
210
+ meta: {
211
+ type: "suggestion",
212
+ docs: {
213
+ description: "Enforce boolean variables and parameters to have a prefix like is, has, should, can, did, will for better readability"
214
+ },
215
+ messages: {
216
+ missingPrefix: "Boolean variable '{{name}}' should have a prefix like is, has, should, can, did, or will. Example: 'is{{suggestedName}}' or 'has{{suggestedName}}'."
217
+ },
218
+ schema: []
219
+ },
220
+ defaultOptions: [],
221
+ create(context) {
222
+ const checkBooleanNaming = (name, node) => {
223
+ if (startsWithBooleanPrefix(name)) {
224
+ return;
225
+ }
226
+ const suggestedName = name.charAt(0).toUpperCase() + name.slice(1);
227
+ context.report({
228
+ node,
229
+ messageId: "missingPrefix",
230
+ data: { name, suggestedName }
231
+ });
232
+ };
233
+ return {
234
+ VariableDeclarator(node) {
235
+ if (node.id.type !== import_utils.AST_NODE_TYPES.Identifier) {
236
+ return;
237
+ }
238
+ const { name } = node.id;
239
+ if (hasBooleanTypeAnnotation(node)) {
240
+ checkBooleanNaming(name, node.id);
241
+ return;
242
+ }
243
+ if (node.init && isBooleanExpression(node.init)) {
244
+ checkBooleanNaming(name, node.id);
245
+ }
246
+ },
247
+ FunctionDeclaration(node) {
248
+ node.params.forEach((param) => {
249
+ if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
250
+ checkBooleanNaming(param.name, param);
251
+ }
252
+ if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
253
+ if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
254
+ checkBooleanNaming(param.left.name, param.left);
255
+ }
256
+ }
257
+ });
258
+ },
259
+ FunctionExpression(node) {
260
+ node.params.forEach((param) => {
261
+ if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
262
+ checkBooleanNaming(param.name, param);
263
+ }
264
+ if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
265
+ if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
266
+ checkBooleanNaming(param.left.name, param.left);
267
+ }
268
+ }
269
+ });
270
+ },
271
+ ArrowFunctionExpression(node) {
272
+ node.params.forEach((param) => {
273
+ if (param.type === import_utils.AST_NODE_TYPES.Identifier && hasBooleanTypeAnnotation(param)) {
274
+ checkBooleanNaming(param.name, param);
275
+ }
276
+ if (param.type === import_utils.AST_NODE_TYPES.AssignmentPattern) {
277
+ if (param.left.type === import_utils.AST_NODE_TYPES.Identifier && param.right && isBooleanLiteral(param.right)) {
278
+ checkBooleanNaming(param.left.name, param.left);
279
+ }
280
+ }
281
+ });
282
+ }
283
+ };
284
+ }
285
+ });
286
+ var boolean_naming_prefix_default = booleanNamingPrefix;
287
+
288
+ // src/rules/enforce-readonly-component-props.ts
289
+ var import_utils2 = require("@typescript-eslint/utils");
290
+ var createRule2 = import_utils2.ESLintUtils.RuleCreator(
291
+ (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
292
+ );
293
+ var enforceReadonlyComponentProps = createRule2({
163
294
  name: "enforce-readonly-component-props",
164
295
  meta: {
165
296
  type: "suggestion",
@@ -175,54 +306,54 @@ var enforceReadonlyComponentProps = createRule({
175
306
  defaultOptions: [],
176
307
  create(context) {
177
308
  function hasJSXInConditional(node) {
178
- return node.consequent.type === import_utils.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils.AST_NODE_TYPES.JSXFragment;
309
+ return node.consequent.type === import_utils2.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils2.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils2.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils2.AST_NODE_TYPES.JSXFragment;
179
310
  }
180
311
  function hasJSXInLogical(node) {
181
- return node.right.type === import_utils.AST_NODE_TYPES.JSXElement || node.right.type === import_utils.AST_NODE_TYPES.JSXFragment;
312
+ return node.right.type === import_utils2.AST_NODE_TYPES.JSXElement || node.right.type === import_utils2.AST_NODE_TYPES.JSXFragment;
182
313
  }
183
314
  function hasJSXReturn(block) {
184
315
  return block.body.some((stmt) => {
185
- if (stmt.type === import_utils.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
186
- return stmt.argument.type === import_utils.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
316
+ if (stmt.type === import_utils2.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
317
+ return stmt.argument.type === import_utils2.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils2.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils2.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils2.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
187
318
  }
188
319
  return false;
189
320
  });
190
321
  }
191
- function isReactComponent(node) {
192
- if (node.type === import_utils.AST_NODE_TYPES.ArrowFunctionExpression) {
193
- if (node.body.type === import_utils.AST_NODE_TYPES.JSXElement || node.body.type === import_utils.AST_NODE_TYPES.JSXFragment) {
322
+ function isReactComponent2(node) {
323
+ if (node.type === import_utils2.AST_NODE_TYPES.ArrowFunctionExpression) {
324
+ if (node.body.type === import_utils2.AST_NODE_TYPES.JSXElement || node.body.type === import_utils2.AST_NODE_TYPES.JSXFragment) {
194
325
  return true;
195
326
  }
196
- if (node.body.type === import_utils.AST_NODE_TYPES.BlockStatement) {
327
+ if (node.body.type === import_utils2.AST_NODE_TYPES.BlockStatement) {
197
328
  return hasJSXReturn(node.body);
198
329
  }
199
- } else if (node.type === import_utils.AST_NODE_TYPES.FunctionExpression || node.type === import_utils.AST_NODE_TYPES.FunctionDeclaration) {
200
- if (node.body && node.body.type === import_utils.AST_NODE_TYPES.BlockStatement) {
330
+ } else if (node.type === import_utils2.AST_NODE_TYPES.FunctionExpression || node.type === import_utils2.AST_NODE_TYPES.FunctionDeclaration) {
331
+ if (node.body && node.body.type === import_utils2.AST_NODE_TYPES.BlockStatement) {
201
332
  return hasJSXReturn(node.body);
202
333
  }
203
334
  }
204
335
  return false;
205
336
  }
206
337
  function isNamedType(node) {
207
- return node.type === import_utils.AST_NODE_TYPES.TSTypeReference;
338
+ return node.type === import_utils2.AST_NODE_TYPES.TSTypeReference;
208
339
  }
209
340
  function isAlreadyReadonly(node) {
210
- if (node.type === import_utils.AST_NODE_TYPES.TSTypeReference && node.typeName) {
211
- if (node.typeName.type === import_utils.AST_NODE_TYPES.Identifier && node.typeName.name === "Readonly") {
341
+ if (node.type === import_utils2.AST_NODE_TYPES.TSTypeReference && node.typeName) {
342
+ if (node.typeName.type === import_utils2.AST_NODE_TYPES.Identifier && node.typeName.name === "Readonly") {
212
343
  return true;
213
344
  }
214
345
  }
215
346
  return false;
216
347
  }
217
348
  function checkFunction(node) {
218
- if (!isReactComponent(node)) {
349
+ if (!isReactComponent2(node)) {
219
350
  return;
220
351
  }
221
352
  if (node.params.length !== 1) {
222
353
  return;
223
354
  }
224
355
  const param = node.params[0];
225
- if (param.type === import_utils.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
356
+ if (param.type === import_utils2.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
226
357
  const { typeAnnotation } = param.typeAnnotation;
227
358
  if (isNamedType(typeAnnotation) && !isAlreadyReadonly(typeAnnotation)) {
228
359
  const { sourceCode } = context;
@@ -247,11 +378,11 @@ var enforceReadonlyComponentProps = createRule({
247
378
  var enforce_readonly_component_props_default = enforceReadonlyComponentProps;
248
379
 
249
380
  // src/rules/enforce-sorted-destructuring.ts
250
- var import_utils2 = require("@typescript-eslint/utils");
251
- var createRule2 = import_utils2.ESLintUtils.RuleCreator(
381
+ var import_utils3 = require("@typescript-eslint/utils");
382
+ var createRule3 = import_utils3.ESLintUtils.RuleCreator(
252
383
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
253
384
  );
254
- var enforceSortedDestructuring = createRule2({
385
+ var enforceSortedDestructuring = createRule3({
255
386
  name: "enforce-sorted-destructuring",
256
387
  meta: {
257
388
  type: "suggestion",
@@ -266,16 +397,16 @@ var enforceSortedDestructuring = createRule2({
266
397
  defaultOptions: [],
267
398
  create(context) {
268
399
  function getPropertyName(property) {
269
- if (property.type === import_utils2.AST_NODE_TYPES.RestElement) {
400
+ if (property.type === import_utils3.AST_NODE_TYPES.RestElement) {
270
401
  return null;
271
402
  }
272
- if (property.key.type === import_utils2.AST_NODE_TYPES.Identifier) {
403
+ if (property.key.type === import_utils3.AST_NODE_TYPES.Identifier) {
273
404
  return property.key.name;
274
405
  }
275
406
  return null;
276
407
  }
277
408
  function hasDefaultValue(property) {
278
- return property.value.type === import_utils2.AST_NODE_TYPES.AssignmentPattern && Boolean(property.value.right);
409
+ return property.value.type === import_utils3.AST_NODE_TYPES.AssignmentPattern && Boolean(property.value.right);
279
410
  }
280
411
  function getDefaultValueType(property) {
281
412
  if (!hasDefaultValue(property)) {
@@ -287,7 +418,7 @@ var enforceSortedDestructuring = createRule2({
287
418
  return "none";
288
419
  }
289
420
  switch (right.type) {
290
- case import_utils2.AST_NODE_TYPES.Literal:
421
+ case import_utils3.AST_NODE_TYPES.Literal:
291
422
  if (typeof right.value === "string") {
292
423
  return "string";
293
424
  }
@@ -298,10 +429,10 @@ var enforceSortedDestructuring = createRule2({
298
429
  return "boolean";
299
430
  }
300
431
  return "other";
301
- case import_utils2.AST_NODE_TYPES.TemplateLiteral:
432
+ case import_utils3.AST_NODE_TYPES.TemplateLiteral:
302
433
  return "string";
303
- case import_utils2.AST_NODE_TYPES.ObjectExpression:
304
- case import_utils2.AST_NODE_TYPES.ArrayExpression:
434
+ case import_utils3.AST_NODE_TYPES.ObjectExpression:
435
+ case import_utils3.AST_NODE_TYPES.ArrayExpression:
305
436
  return "object";
306
437
  default:
307
438
  return "other";
@@ -319,7 +450,7 @@ var enforceSortedDestructuring = createRule2({
319
450
  return order[type] ?? 5;
320
451
  }
321
452
  function checkVariableDeclarator(node) {
322
- if (node.id.type !== import_utils2.AST_NODE_TYPES.ObjectPattern) {
453
+ if (node.id.type !== import_utils3.AST_NODE_TYPES.ObjectPattern) {
323
454
  return;
324
455
  }
325
456
  const { properties } = node.id;
@@ -327,7 +458,7 @@ var enforceSortedDestructuring = createRule2({
327
458
  return;
328
459
  }
329
460
  const propertyInfo = properties.map((prop) => {
330
- if (prop.type === import_utils2.AST_NODE_TYPES.RestElement) {
461
+ if (prop.type === import_utils3.AST_NODE_TYPES.RestElement) {
331
462
  return null;
332
463
  }
333
464
  return {
@@ -369,8 +500,8 @@ var enforce_sorted_destructuring_default = enforceSortedDestructuring;
369
500
 
370
501
  // src/rules/file-kebab-case.ts
371
502
  var import_path = __toESM(require("path"), 1);
372
- var import_utils3 = require("@typescript-eslint/utils");
373
- var createRule3 = import_utils3.ESLintUtils.RuleCreator(
503
+ var import_utils4 = require("@typescript-eslint/utils");
504
+ var createRule4 = import_utils4.ESLintUtils.RuleCreator(
374
505
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
375
506
  );
376
507
  var isKebabCase = (str) => {
@@ -379,7 +510,7 @@ var isKebabCase = (str) => {
379
510
  }
380
511
  return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str);
381
512
  };
382
- var fileKebabCase = createRule3({
513
+ var fileKebabCase = createRule4({
383
514
  name: "file-kebab-case",
384
515
  meta: {
385
516
  type: "problem",
@@ -415,12 +546,12 @@ var file_kebab_case_default = fileKebabCase;
415
546
 
416
547
  // src/rules/jsx-pascal-case.ts
417
548
  var import_path2 = __toESM(require("path"), 1);
418
- var import_utils4 = require("@typescript-eslint/utils");
419
- var createRule4 = import_utils4.ESLintUtils.RuleCreator(
549
+ var import_utils5 = require("@typescript-eslint/utils");
550
+ var createRule5 = import_utils5.ESLintUtils.RuleCreator(
420
551
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
421
552
  );
422
553
  var isPascalCase = (str) => /^[A-Z][a-zA-Z0-9]*$/.test(str) && !/^[A-Z]+$/.test(str);
423
- var jsxPascalCase = createRule4({
554
+ var jsxPascalCase = createRule5({
424
555
  name: "jsx-pascal-case",
425
556
  meta: {
426
557
  type: "problem",
@@ -454,12 +585,64 @@ var jsxPascalCase = createRule4({
454
585
  });
455
586
  var jsx_pascal_case_default = jsxPascalCase;
456
587
 
588
+ // src/rules/no-direct-date.ts
589
+ var import_utils6 = require("@typescript-eslint/utils");
590
+ var createRule6 = import_utils6.ESLintUtils.RuleCreator(
591
+ (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
592
+ );
593
+ var noDirectDate = createRule6({
594
+ name: "no-direct-date",
595
+ meta: {
596
+ type: "problem",
597
+ docs: {
598
+ description: "Disallow direct usage of Date constructor and methods to enforce centralized date utilities"
599
+ },
600
+ messages: {
601
+ noNewDate: "Avoid using 'new Date()'. Use a centralized date utility like dayjs instead.",
602
+ noDateNow: "Avoid using 'Date.now()'. Use a centralized date utility like dayjs instead.",
603
+ noDateParse: "Avoid using 'Date.parse()'. Use a centralized date utility like dayjs instead."
604
+ },
605
+ schema: []
606
+ },
607
+ defaultOptions: [],
608
+ create(context) {
609
+ return {
610
+ NewExpression(node) {
611
+ if (node.callee.type === import_utils6.AST_NODE_TYPES.Identifier && node.callee.name === "Date") {
612
+ context.report({
613
+ node,
614
+ messageId: "noNewDate"
615
+ });
616
+ }
617
+ },
618
+ CallExpression(node) {
619
+ if (node.callee.type === import_utils6.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils6.AST_NODE_TYPES.Identifier && node.callee.object.name === "Date" && node.callee.property.type === import_utils6.AST_NODE_TYPES.Identifier) {
620
+ const methodName = node.callee.property.name;
621
+ if (methodName === "now") {
622
+ context.report({
623
+ node,
624
+ messageId: "noDateNow"
625
+ });
626
+ }
627
+ if (methodName === "parse") {
628
+ context.report({
629
+ node,
630
+ messageId: "noDateParse"
631
+ });
632
+ }
633
+ }
634
+ }
635
+ };
636
+ }
637
+ });
638
+ var no_direct_date_default = noDirectDate;
639
+
457
640
  // src/rules/jsx-no-variable-in-callback.ts
458
- var import_utils5 = require("@typescript-eslint/utils");
459
- var createRule5 = import_utils5.ESLintUtils.RuleCreator(
641
+ var import_utils7 = require("@typescript-eslint/utils");
642
+ var createRule7 = import_utils7.ESLintUtils.RuleCreator(
460
643
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
461
644
  );
462
- var jsxNoVariableInCallback = createRule5({
645
+ var jsxNoVariableInCallback = createRule7({
463
646
  name: "jsx-no-variable-in-callback",
464
647
  meta: {
465
648
  type: "suggestion",
@@ -476,7 +659,7 @@ var jsxNoVariableInCallback = createRule5({
476
659
  function isInsideJSX(node) {
477
660
  let current = node.parent;
478
661
  while (current) {
479
- if (current.type === import_utils5.AST_NODE_TYPES.JSXElement || current.type === import_utils5.AST_NODE_TYPES.JSXFragment) {
662
+ if (current.type === import_utils7.AST_NODE_TYPES.JSXElement || current.type === import_utils7.AST_NODE_TYPES.JSXFragment) {
480
663
  return true;
481
664
  }
482
665
  current = current.parent;
@@ -490,11 +673,11 @@ var jsxNoVariableInCallback = createRule5({
490
673
  if (!isInsideJSX(node)) {
491
674
  return false;
492
675
  }
493
- if (node.parent.type === import_utils5.AST_NODE_TYPES.CallExpression || node.parent.type === import_utils5.AST_NODE_TYPES.JSXExpressionContainer) {
676
+ if (node.parent.type === import_utils7.AST_NODE_TYPES.CallExpression || node.parent.type === import_utils7.AST_NODE_TYPES.JSXExpressionContainer) {
494
677
  return true;
495
678
  }
496
- if (node.parent.type === import_utils5.AST_NODE_TYPES.ArrayExpression && node.parent.parent) {
497
- if (node.parent.parent.type === import_utils5.AST_NODE_TYPES.CallExpression || node.parent.parent.type === import_utils5.AST_NODE_TYPES.JSXExpressionContainer) {
679
+ if (node.parent.type === import_utils7.AST_NODE_TYPES.ArrayExpression && node.parent.parent) {
680
+ if (node.parent.parent.type === import_utils7.AST_NODE_TYPES.CallExpression || node.parent.parent.type === import_utils7.AST_NODE_TYPES.JSXExpressionContainer) {
498
681
  return true;
499
682
  }
500
683
  }
@@ -505,11 +688,11 @@ var jsxNoVariableInCallback = createRule5({
505
688
  return;
506
689
  }
507
690
  const { body } = node;
508
- if (body.type !== import_utils5.AST_NODE_TYPES.BlockStatement) {
691
+ if (body.type !== import_utils7.AST_NODE_TYPES.BlockStatement) {
509
692
  return;
510
693
  }
511
694
  body.body.forEach((statement) => {
512
- if (statement.type === import_utils5.AST_NODE_TYPES.VariableDeclaration) {
695
+ if (statement.type === import_utils7.AST_NODE_TYPES.VariableDeclaration) {
513
696
  context.report({
514
697
  node: statement,
515
698
  messageId: "noVariableInCallback"
@@ -527,11 +710,11 @@ var jsx_no_variable_in_callback_default = jsxNoVariableInCallback;
527
710
 
528
711
  // src/rules/md-filename-case-restriction.ts
529
712
  var import_path3 = __toESM(require("path"), 1);
530
- var import_utils6 = require("@typescript-eslint/utils");
531
- var createRule6 = import_utils6.ESLintUtils.RuleCreator(
713
+ var import_utils8 = require("@typescript-eslint/utils");
714
+ var createRule8 = import_utils8.ESLintUtils.RuleCreator(
532
715
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
533
716
  );
534
- var mdFilenameCaseRestriction = createRule6({
717
+ var mdFilenameCaseRestriction = createRule8({
535
718
  name: "md-filename-case-restriction",
536
719
  meta: {
537
720
  type: "problem",
@@ -572,11 +755,11 @@ var mdFilenameCaseRestriction = createRule6({
572
755
  var md_filename_case_restriction_default = mdFilenameCaseRestriction;
573
756
 
574
757
  // src/rules/no-complex-inline-return.ts
575
- var import_utils7 = require("@typescript-eslint/utils");
576
- var createRule7 = import_utils7.ESLintUtils.RuleCreator(
758
+ var import_utils9 = require("@typescript-eslint/utils");
759
+ var createRule9 = import_utils9.ESLintUtils.RuleCreator(
577
760
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
578
761
  );
579
- var noComplexInlineReturn = createRule7({
762
+ var noComplexInlineReturn = createRule9({
580
763
  name: "no-complex-inline-return",
581
764
  meta: {
582
765
  type: "suggestion",
@@ -592,13 +775,13 @@ var noComplexInlineReturn = createRule7({
592
775
  create(context) {
593
776
  const isComplexExpression = (node) => {
594
777
  if (!node) return false;
595
- if (node.type === import_utils7.AST_NODE_TYPES.ConditionalExpression) {
778
+ if (node.type === import_utils9.AST_NODE_TYPES.ConditionalExpression) {
596
779
  return true;
597
780
  }
598
- if (node.type === import_utils7.AST_NODE_TYPES.LogicalExpression) {
781
+ if (node.type === import_utils9.AST_NODE_TYPES.LogicalExpression) {
599
782
  return true;
600
783
  }
601
- if (node.type === import_utils7.AST_NODE_TYPES.NewExpression) {
784
+ if (node.type === import_utils9.AST_NODE_TYPES.NewExpression) {
602
785
  return true;
603
786
  }
604
787
  return false;
@@ -619,11 +802,11 @@ var no_complex_inline_return_default = noComplexInlineReturn;
619
802
 
620
803
  // src/rules/no-emoji.ts
621
804
  var import_emoji_regex = __toESM(require("emoji-regex"), 1);
622
- var import_utils8 = require("@typescript-eslint/utils");
623
- var createRule8 = import_utils8.ESLintUtils.RuleCreator(
805
+ var import_utils10 = require("@typescript-eslint/utils");
806
+ var createRule10 = import_utils10.ESLintUtils.RuleCreator(
624
807
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
625
808
  );
626
- var noEmoji = createRule8({
809
+ var noEmoji = createRule10({
627
810
  name: "no-emoji",
628
811
  meta: {
629
812
  type: "problem",
@@ -657,11 +840,11 @@ var noEmoji = createRule8({
657
840
  var no_emoji_default = noEmoji;
658
841
 
659
842
  // src/rules/no-env-fallback.ts
660
- var import_utils9 = require("@typescript-eslint/utils");
661
- var createRule9 = import_utils9.ESLintUtils.RuleCreator(
843
+ var import_utils11 = require("@typescript-eslint/utils");
844
+ var createRule11 = import_utils11.ESLintUtils.RuleCreator(
662
845
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
663
846
  );
664
- var noEnvFallback = createRule9({
847
+ var noEnvFallback = createRule11({
665
848
  name: "no-env-fallback",
666
849
  meta: {
667
850
  type: "problem",
@@ -676,16 +859,16 @@ var noEnvFallback = createRule9({
676
859
  defaultOptions: [],
677
860
  create(context) {
678
861
  const isProcessEnvAccess = (node) => {
679
- if (node.type !== import_utils9.AST_NODE_TYPES.MemberExpression) {
862
+ if (node.type !== import_utils11.AST_NODE_TYPES.MemberExpression) {
680
863
  return false;
681
864
  }
682
865
  const { object } = node;
683
- if (object.type !== import_utils9.AST_NODE_TYPES.MemberExpression) {
866
+ if (object.type !== import_utils11.AST_NODE_TYPES.MemberExpression) {
684
867
  return false;
685
868
  }
686
869
  const processNode = object.object;
687
870
  const envNode = object.property;
688
- return processNode.type === import_utils9.AST_NODE_TYPES.Identifier && processNode.name === "process" && envNode.type === import_utils9.AST_NODE_TYPES.Identifier && envNode.name === "env";
871
+ return processNode.type === import_utils11.AST_NODE_TYPES.Identifier && processNode.name === "process" && envNode.type === import_utils11.AST_NODE_TYPES.Identifier && envNode.name === "env";
689
872
  };
690
873
  return {
691
874
  LogicalExpression(node) {
@@ -709,38 +892,93 @@ var noEnvFallback = createRule9({
709
892
  });
710
893
  var no_env_fallback_default = noEnvFallback;
711
894
 
712
- // src/rules/no-explicit-return-type.ts
713
- var import_utils10 = require("@typescript-eslint/utils");
714
- var createRule10 = import_utils10.ESLintUtils.RuleCreator(
895
+ // src/rules/require-explicit-return-type.ts
896
+ var import_utils12 = require("@typescript-eslint/utils");
897
+ var createRule12 = import_utils12.ESLintUtils.RuleCreator(
715
898
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
716
899
  );
717
- var noExplicitReturnType = createRule10({
718
- name: "no-explicit-return-type",
900
+ var isReactComponent = (node) => {
901
+ if (node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression) {
902
+ const { parent } = node;
903
+ if (parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator) {
904
+ const { id } = parent;
905
+ if (id.type === import_utils12.AST_NODE_TYPES.Identifier) {
906
+ return /^[A-Z]/.test(id.name);
907
+ }
908
+ }
909
+ }
910
+ if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration && node.id) {
911
+ return /^[A-Z]/.test(node.id.name);
912
+ }
913
+ return false;
914
+ };
915
+ var isCallbackFunction = (node) => {
916
+ if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration) {
917
+ return false;
918
+ }
919
+ const { parent } = node;
920
+ if (!parent) {
921
+ return false;
922
+ }
923
+ if (parent.type === import_utils12.AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
924
+ return true;
925
+ }
926
+ if (parent.type === import_utils12.AST_NODE_TYPES.Property) {
927
+ return true;
928
+ }
929
+ if (parent.type === import_utils12.AST_NODE_TYPES.ArrayExpression) {
930
+ return true;
931
+ }
932
+ return false;
933
+ };
934
+ var getFunctionName = (node) => {
935
+ if (node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration && node.id) {
936
+ return node.id.name;
937
+ }
938
+ if (node.type === import_utils12.AST_NODE_TYPES.FunctionExpression && node.id) {
939
+ return node.id.name;
940
+ }
941
+ if ((node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils12.AST_NODE_TYPES.FunctionExpression) && node.parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
942
+ return node.parent.id.name;
943
+ }
944
+ return null;
945
+ };
946
+ var requireExplicitReturnType = createRule12({
947
+ name: "require-explicit-return-type",
719
948
  meta: {
720
949
  type: "suggestion",
721
950
  docs: {
722
- description: "Disallow explicit return types on functions"
951
+ description: "Require explicit return types on functions for better code documentation and type safety"
723
952
  },
724
- fixable: "code",
725
- schema: [],
726
953
  messages: {
727
- noExplicitReturnType: "Remove explicit return type '{{returnType}}' - TypeScript can infer it automatically"
728
- }
954
+ missingReturnType: "Function '{{name}}' is missing an explicit return type. Add a return type annotation for better documentation.",
955
+ missingReturnTypeAnonymous: "Function is missing an explicit return type. Add a return type annotation for better documentation."
956
+ },
957
+ schema: []
729
958
  },
730
959
  defaultOptions: [],
731
960
  create(context) {
732
961
  const checkFunction = (node) => {
733
962
  if (node.returnType) {
734
- const returnTypeText = context.sourceCode.getText(node.returnType);
963
+ return;
964
+ }
965
+ if (isCallbackFunction(node)) {
966
+ return;
967
+ }
968
+ if (isReactComponent(node)) {
969
+ return;
970
+ }
971
+ const functionName = getFunctionName(node);
972
+ if (functionName) {
735
973
  context.report({
736
- node: node.returnType,
737
- messageId: "noExplicitReturnType",
738
- data: {
739
- returnType: returnTypeText
740
- },
741
- fix(fixer) {
742
- return fixer.remove(node.returnType);
743
- }
974
+ node,
975
+ messageId: "missingReturnType",
976
+ data: { name: functionName }
977
+ });
978
+ } else {
979
+ context.report({
980
+ node,
981
+ messageId: "missingReturnTypeAnonymous"
744
982
  });
745
983
  }
746
984
  };
@@ -751,21 +989,21 @@ var noExplicitReturnType = createRule10({
751
989
  };
752
990
  }
753
991
  });
754
- var no_explicit_return_type_default = noExplicitReturnType;
992
+ var require_explicit_return_type_default = requireExplicitReturnType;
755
993
 
756
994
  // src/rules/jsx-no-non-component-function.ts
757
- var import_utils12 = require("@typescript-eslint/utils");
995
+ var import_utils14 = require("@typescript-eslint/utils");
758
996
 
759
997
  // src/utils.ts
760
998
  var import_node_path = require("path");
761
- var import_utils11 = require("@typescript-eslint/utils");
999
+ var import_utils13 = require("@typescript-eslint/utils");
762
1000
  var getFileExtension = (filename) => (0, import_node_path.extname)(filename).slice(1);
763
1001
 
764
1002
  // src/rules/jsx-no-non-component-function.ts
765
- var createRule11 = import_utils12.ESLintUtils.RuleCreator(
1003
+ var createRule13 = import_utils14.ESLintUtils.RuleCreator(
766
1004
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
767
1005
  );
768
- var jsxNoNonComponentFunction = createRule11({
1006
+ var jsxNoNonComponentFunction = createRule13({
769
1007
  name: "jsx-no-non-component-function",
770
1008
  meta: {
771
1009
  type: "problem",
@@ -784,14 +1022,14 @@ var jsxNoNonComponentFunction = createRule11({
784
1022
  if (extension !== "tsx" && extension !== "jsx") {
785
1023
  return {};
786
1024
  }
787
- function isReactComponent(node) {
788
- const functionName = node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration && node.id ? node.id.name : null;
1025
+ function isReactComponent2(node) {
1026
+ const functionName = node.type === import_utils14.AST_NODE_TYPES.FunctionDeclaration && node.id ? node.id.name : null;
789
1027
  if (functionName && /^[A-Z]/.test(functionName)) {
790
1028
  return true;
791
1029
  }
792
1030
  if (node.returnType?.typeAnnotation) {
793
1031
  const returnTypeNode = node.returnType.typeAnnotation;
794
- if (returnTypeNode.type === import_utils12.AST_NODE_TYPES.TSTypeReference && returnTypeNode.typeName.type === import_utils12.AST_NODE_TYPES.Identifier) {
1032
+ if (returnTypeNode.type === import_utils14.AST_NODE_TYPES.TSTypeReference && returnTypeNode.typeName.type === import_utils14.AST_NODE_TYPES.Identifier) {
795
1033
  const typeName = returnTypeNode.typeName.name;
796
1034
  if (typeName === "JSX" || typeName === "ReactElement" || typeName === "ReactNode") {
797
1035
  return true;
@@ -801,20 +1039,20 @@ var jsxNoNonComponentFunction = createRule11({
801
1039
  return false;
802
1040
  }
803
1041
  function checkTopLevelFunction(node, declaratorNode) {
804
- if (isReactComponent(node)) {
1042
+ if (isReactComponent2(node)) {
805
1043
  return;
806
1044
  }
807
1045
  const { parent } = node;
808
1046
  if (!parent) {
809
1047
  return;
810
1048
  }
811
- if (parent.type === import_utils12.AST_NODE_TYPES.ExportDefaultDeclaration || parent.type === import_utils12.AST_NODE_TYPES.ExportNamedDeclaration) {
1049
+ if (parent.type === import_utils14.AST_NODE_TYPES.ExportDefaultDeclaration || parent.type === import_utils14.AST_NODE_TYPES.ExportNamedDeclaration) {
812
1050
  return;
813
1051
  }
814
- if (declaratorNode?.parent?.parent?.type === import_utils12.AST_NODE_TYPES.ExportNamedDeclaration) {
1052
+ if (declaratorNode?.parent?.parent?.type === import_utils14.AST_NODE_TYPES.ExportNamedDeclaration) {
815
1053
  return;
816
1054
  }
817
- if (declaratorNode?.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
1055
+ if (declaratorNode?.id.type === import_utils14.AST_NODE_TYPES.Identifier) {
818
1056
  const varName = declaratorNode.id.name;
819
1057
  if (/^[A-Z]/.test(varName)) {
820
1058
  return;
@@ -839,11 +1077,11 @@ var jsxNoNonComponentFunction = createRule11({
839
1077
  var jsx_no_non_component_function_default = jsxNoNonComponentFunction;
840
1078
 
841
1079
  // src/rules/no-logic-in-params.ts
842
- var import_utils14 = require("@typescript-eslint/utils");
843
- var createRule12 = import_utils14.ESLintUtils.RuleCreator(
1080
+ var import_utils16 = require("@typescript-eslint/utils");
1081
+ var createRule14 = import_utils16.ESLintUtils.RuleCreator(
844
1082
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
845
1083
  );
846
- var noLogicInParams = createRule12({
1084
+ var noLogicInParams = createRule14({
847
1085
  name: "no-logic-in-params",
848
1086
  meta: {
849
1087
  type: "suggestion",
@@ -858,20 +1096,20 @@ var noLogicInParams = createRule12({
858
1096
  defaultOptions: [],
859
1097
  create(context) {
860
1098
  const isComplexExpression = (node) => {
861
- if (node.type === import_utils14.AST_NODE_TYPES.SpreadElement) {
1099
+ if (node.type === import_utils16.AST_NODE_TYPES.SpreadElement) {
862
1100
  return false;
863
1101
  }
864
- if (node.type === import_utils14.AST_NODE_TYPES.ConditionalExpression) {
1102
+ if (node.type === import_utils16.AST_NODE_TYPES.ConditionalExpression) {
865
1103
  return true;
866
1104
  }
867
- if (node.type === import_utils14.AST_NODE_TYPES.LogicalExpression) {
1105
+ if (node.type === import_utils16.AST_NODE_TYPES.LogicalExpression) {
868
1106
  return true;
869
1107
  }
870
- if (node.type === import_utils14.AST_NODE_TYPES.BinaryExpression) {
1108
+ if (node.type === import_utils16.AST_NODE_TYPES.BinaryExpression) {
871
1109
  const logicalOperators = ["==", "===", "!=", "!==", "<", ">", "<=", ">=", "in", "instanceof"];
872
1110
  return logicalOperators.includes(node.operator);
873
1111
  }
874
- if (node.type === import_utils14.AST_NODE_TYPES.UnaryExpression) {
1112
+ if (node.type === import_utils16.AST_NODE_TYPES.UnaryExpression) {
875
1113
  return node.operator === "!";
876
1114
  }
877
1115
  return false;
@@ -902,12 +1140,127 @@ var noLogicInParams = createRule12({
902
1140
  });
903
1141
  var no_logic_in_params_default = noLogicInParams;
904
1142
 
1143
+ // src/rules/no-single-char-variables.ts
1144
+ var import_utils17 = require("@typescript-eslint/utils");
1145
+ var createRule15 = import_utils17.ESLintUtils.RuleCreator(
1146
+ (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1147
+ );
1148
+ var ALLOWED_IN_FOR_LOOPS = /* @__PURE__ */ new Set(["i", "j", "k", "n"]);
1149
+ var ALLOWED_UNDERSCORE = "_";
1150
+ var isForLoopInit = (node) => {
1151
+ let current = node;
1152
+ while (current) {
1153
+ const parentNode = current.parent;
1154
+ if (!parentNode) {
1155
+ return false;
1156
+ }
1157
+ if (parentNode.type === import_utils17.AST_NODE_TYPES.ForStatement) {
1158
+ const { init } = parentNode;
1159
+ if (init && init === current) {
1160
+ return true;
1161
+ }
1162
+ }
1163
+ current = parentNode;
1164
+ }
1165
+ return false;
1166
+ };
1167
+ var isAllowedInContext = (name, node) => {
1168
+ if (name === ALLOWED_UNDERSCORE) {
1169
+ return true;
1170
+ }
1171
+ if (ALLOWED_IN_FOR_LOOPS.has(name) && isForLoopInit(node)) {
1172
+ return true;
1173
+ }
1174
+ return false;
1175
+ };
1176
+ var noSingleCharVariables = createRule15({
1177
+ name: "no-single-char-variables",
1178
+ meta: {
1179
+ type: "suggestion",
1180
+ docs: {
1181
+ description: "Disallow single character variable and parameter names for better code readability"
1182
+ },
1183
+ messages: {
1184
+ noSingleChar: "Avoid single character variable name '{{name}}'. Use a descriptive name that clearly indicates the purpose."
1185
+ },
1186
+ schema: []
1187
+ },
1188
+ defaultOptions: [],
1189
+ create(context) {
1190
+ const checkIdentifier = (node, declarationNode) => {
1191
+ const { name } = node;
1192
+ if (name.length !== 1) {
1193
+ return;
1194
+ }
1195
+ if (isAllowedInContext(name, declarationNode)) {
1196
+ return;
1197
+ }
1198
+ context.report({
1199
+ node,
1200
+ messageId: "noSingleChar",
1201
+ data: { name }
1202
+ });
1203
+ };
1204
+ const checkPattern = (pattern, declarationNode) => {
1205
+ if (pattern.type === import_utils17.AST_NODE_TYPES.Identifier) {
1206
+ checkIdentifier(pattern, declarationNode);
1207
+ } else if (pattern.type === import_utils17.AST_NODE_TYPES.ObjectPattern) {
1208
+ pattern.properties.forEach((prop) => {
1209
+ if (prop.type === import_utils17.AST_NODE_TYPES.Property && prop.value.type === import_utils17.AST_NODE_TYPES.Identifier) {
1210
+ checkIdentifier(prop.value, declarationNode);
1211
+ } else if (prop.type === import_utils17.AST_NODE_TYPES.RestElement && prop.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
1212
+ checkIdentifier(prop.argument, declarationNode);
1213
+ }
1214
+ });
1215
+ } else if (pattern.type === import_utils17.AST_NODE_TYPES.ArrayPattern) {
1216
+ pattern.elements.forEach((element) => {
1217
+ if (element?.type === import_utils17.AST_NODE_TYPES.Identifier) {
1218
+ checkIdentifier(element, declarationNode);
1219
+ } else if (element?.type === import_utils17.AST_NODE_TYPES.RestElement && element.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
1220
+ checkIdentifier(element.argument, declarationNode);
1221
+ }
1222
+ });
1223
+ } else if (pattern.type === import_utils17.AST_NODE_TYPES.AssignmentPattern && pattern.left.type === import_utils17.AST_NODE_TYPES.Identifier) {
1224
+ checkIdentifier(pattern.left, declarationNode);
1225
+ } else if (pattern.type === import_utils17.AST_NODE_TYPES.RestElement && pattern.argument.type === import_utils17.AST_NODE_TYPES.Identifier) {
1226
+ checkIdentifier(pattern.argument, declarationNode);
1227
+ }
1228
+ };
1229
+ return {
1230
+ VariableDeclarator(node) {
1231
+ checkPattern(node.id, node);
1232
+ },
1233
+ FunctionDeclaration(node) {
1234
+ if (node.id) {
1235
+ checkIdentifier(node.id, node);
1236
+ }
1237
+ node.params.forEach((param) => checkPattern(param, node));
1238
+ },
1239
+ FunctionExpression(node) {
1240
+ if (node.id) {
1241
+ checkIdentifier(node.id, node);
1242
+ }
1243
+ node.params.forEach((param) => checkPattern(param, node));
1244
+ },
1245
+ ArrowFunctionExpression(node) {
1246
+ node.params.forEach((param) => checkPattern(param, node));
1247
+ },
1248
+ CatchClause(node) {
1249
+ if (node.param) {
1250
+ checkPattern(node.param, node);
1251
+ }
1252
+ }
1253
+ };
1254
+ }
1255
+ });
1256
+ var no_single_char_variables_default = noSingleCharVariables;
1257
+
905
1258
  // src/rules/prefer-destructuring-params.ts
906
- var import_utils15 = require("@typescript-eslint/utils");
907
- var createRule13 = import_utils15.ESLintUtils.RuleCreator(
1259
+ var import_utils18 = require("@typescript-eslint/utils");
1260
+ var createRule16 = import_utils18.ESLintUtils.RuleCreator(
908
1261
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
909
1262
  );
910
- var preferDestructuringParams = createRule13({
1263
+ var preferDestructuringParams = createRule16({
911
1264
  name: "prefer-destructuring-params",
912
1265
  meta: {
913
1266
  type: "suggestion",
@@ -921,20 +1274,20 @@ var preferDestructuringParams = createRule13({
921
1274
  },
922
1275
  defaultOptions: [],
923
1276
  create(context) {
924
- const isCallbackFunction = (node) => {
1277
+ const isCallbackFunction2 = (node) => {
925
1278
  const { parent } = node;
926
- return parent?.type === import_utils15.AST_NODE_TYPES.CallExpression;
1279
+ return parent?.type === import_utils18.AST_NODE_TYPES.CallExpression;
927
1280
  };
928
1281
  const isDeveloperFunction = (node) => {
929
- if (node.type === import_utils15.AST_NODE_TYPES.FunctionDeclaration) {
1282
+ if (node.type === import_utils18.AST_NODE_TYPES.FunctionDeclaration) {
930
1283
  return true;
931
1284
  }
932
- if (node.type === import_utils15.AST_NODE_TYPES.FunctionExpression || node.type === import_utils15.AST_NODE_TYPES.ArrowFunctionExpression) {
933
- if (isCallbackFunction(node)) {
1285
+ if (node.type === import_utils18.AST_NODE_TYPES.FunctionExpression || node.type === import_utils18.AST_NODE_TYPES.ArrowFunctionExpression) {
1286
+ if (isCallbackFunction2(node)) {
934
1287
  return false;
935
1288
  }
936
1289
  const { parent } = node;
937
- return parent?.type === import_utils15.AST_NODE_TYPES.VariableDeclarator || parent?.type === import_utils15.AST_NODE_TYPES.AssignmentExpression || parent?.type === import_utils15.AST_NODE_TYPES.Property || parent?.type === import_utils15.AST_NODE_TYPES.MethodDefinition;
1290
+ return parent?.type === import_utils18.AST_NODE_TYPES.VariableDeclarator || parent?.type === import_utils18.AST_NODE_TYPES.AssignmentExpression || parent?.type === import_utils18.AST_NODE_TYPES.Property || parent?.type === import_utils18.AST_NODE_TYPES.MethodDefinition;
938
1291
  }
939
1292
  return false;
940
1293
  };
@@ -946,7 +1299,7 @@ var preferDestructuringParams = createRule13({
946
1299
  if (!isDeveloperFunction(node)) {
947
1300
  return;
948
1301
  }
949
- if (node.type === import_utils15.AST_NODE_TYPES.FunctionDeclaration && node.id) {
1302
+ if (node.type === import_utils18.AST_NODE_TYPES.FunctionDeclaration && node.id) {
950
1303
  const functionName = node.id.name;
951
1304
  if (functionName.startsWith("_") || functionName.includes("$") || /^[A-Z][a-zA-Z]*$/.test(functionName)) {
952
1305
  return;
@@ -956,7 +1309,7 @@ var preferDestructuringParams = createRule13({
956
1309
  return;
957
1310
  }
958
1311
  const hasNonDestructuredParams = node.params.some(
959
- (param) => param.type !== import_utils15.AST_NODE_TYPES.ObjectPattern && param.type !== import_utils15.AST_NODE_TYPES.RestElement
1312
+ (param) => param.type !== import_utils18.AST_NODE_TYPES.ObjectPattern && param.type !== import_utils18.AST_NODE_TYPES.RestElement
960
1313
  );
961
1314
  if (hasNonDestructuredParams) {
962
1315
  context.report({
@@ -974,12 +1327,103 @@ var preferDestructuringParams = createRule13({
974
1327
  });
975
1328
  var prefer_destructuring_params_default = preferDestructuringParams;
976
1329
 
1330
+ // src/rules/prefer-function-declaration.ts
1331
+ var import_utils19 = require("@typescript-eslint/utils");
1332
+ var createRule17 = import_utils19.ESLintUtils.RuleCreator(
1333
+ (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1334
+ );
1335
+ var isTsFile = (filename) => filename.endsWith(".ts") && !filename.endsWith(".d.ts");
1336
+ var isCallbackContext = (node) => {
1337
+ const { parent } = node;
1338
+ if (!parent) {
1339
+ return false;
1340
+ }
1341
+ if (parent.type === import_utils19.AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
1342
+ return true;
1343
+ }
1344
+ if (parent.type === import_utils19.AST_NODE_TYPES.NewExpression && parent.arguments.includes(node)) {
1345
+ return true;
1346
+ }
1347
+ if (parent.type === import_utils19.AST_NODE_TYPES.ReturnStatement) {
1348
+ return true;
1349
+ }
1350
+ if (parent.type === import_utils19.AST_NODE_TYPES.Property) {
1351
+ return true;
1352
+ }
1353
+ if (parent.type === import_utils19.AST_NODE_TYPES.ArrayExpression) {
1354
+ return true;
1355
+ }
1356
+ if (parent.type === import_utils19.AST_NODE_TYPES.ConditionalExpression) {
1357
+ return true;
1358
+ }
1359
+ if (parent.type === import_utils19.AST_NODE_TYPES.LogicalExpression) {
1360
+ return true;
1361
+ }
1362
+ if (parent.type === import_utils19.AST_NODE_TYPES.AssignmentExpression && parent.left !== node) {
1363
+ return true;
1364
+ }
1365
+ return false;
1366
+ };
1367
+ var preferFunctionDeclaration = createRule17({
1368
+ name: "prefer-function-declaration",
1369
+ meta: {
1370
+ type: "suggestion",
1371
+ docs: {
1372
+ description: "Enforce function declarations over arrow functions assigned to variables in .ts files for better readability and hoisting"
1373
+ },
1374
+ messages: {
1375
+ preferDeclaration: "Use function declaration instead of arrow function. Replace 'const {{name}} = () => ...' with 'function {{name}}() ...'",
1376
+ preferDeclarationExpr: "Use function declaration instead of function expression. Replace 'const {{name}} = function() ...' with 'function {{name}}() ...'"
1377
+ },
1378
+ schema: []
1379
+ },
1380
+ defaultOptions: [],
1381
+ create(context) {
1382
+ const { filename } = context;
1383
+ if (!isTsFile(filename)) {
1384
+ return {};
1385
+ }
1386
+ return {
1387
+ VariableDeclarator(node) {
1388
+ if (node.id.type !== import_utils19.AST_NODE_TYPES.Identifier) {
1389
+ return;
1390
+ }
1391
+ const { init } = node;
1392
+ if (!init) {
1393
+ return;
1394
+ }
1395
+ if (init.type === import_utils19.AST_NODE_TYPES.ArrowFunctionExpression) {
1396
+ if (isCallbackContext(init)) {
1397
+ return;
1398
+ }
1399
+ context.report({
1400
+ node: init,
1401
+ messageId: "preferDeclaration",
1402
+ data: { name: node.id.name }
1403
+ });
1404
+ }
1405
+ if (init.type === import_utils19.AST_NODE_TYPES.FunctionExpression) {
1406
+ if (isCallbackContext(init)) {
1407
+ return;
1408
+ }
1409
+ context.report({
1410
+ node: init,
1411
+ messageId: "preferDeclarationExpr",
1412
+ data: { name: node.id.name }
1413
+ });
1414
+ }
1415
+ }
1416
+ };
1417
+ }
1418
+ });
1419
+ var prefer_function_declaration_default = preferFunctionDeclaration;
1420
+
977
1421
  // src/rules/prefer-import-type.ts
978
- var import_utils16 = require("@typescript-eslint/utils");
979
- var createRule14 = import_utils16.ESLintUtils.RuleCreator(
1422
+ var import_utils20 = require("@typescript-eslint/utils");
1423
+ var createRule18 = import_utils20.ESLintUtils.RuleCreator(
980
1424
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
981
1425
  );
982
- var preferImportType = createRule14({
1426
+ var preferImportType = createRule18({
983
1427
  name: "prefer-import-type",
984
1428
  meta: {
985
1429
  type: "suggestion",
@@ -998,22 +1442,22 @@ var preferImportType = createRule14({
998
1442
  let current = node;
999
1443
  while (current) {
1000
1444
  switch (current.type) {
1001
- case import_utils16.AST_NODE_TYPES.TSTypeReference:
1002
- case import_utils16.AST_NODE_TYPES.TSTypeAnnotation:
1003
- case import_utils16.AST_NODE_TYPES.TSTypeParameterInstantiation:
1004
- case import_utils16.AST_NODE_TYPES.TSInterfaceHeritage:
1005
- case import_utils16.AST_NODE_TYPES.TSClassImplements:
1006
- case import_utils16.AST_NODE_TYPES.TSTypeQuery:
1007
- case import_utils16.AST_NODE_TYPES.TSTypeAssertion:
1008
- case import_utils16.AST_NODE_TYPES.TSAsExpression:
1009
- case import_utils16.AST_NODE_TYPES.TSSatisfiesExpression:
1010
- case import_utils16.AST_NODE_TYPES.TSTypeAliasDeclaration:
1011
- case import_utils16.AST_NODE_TYPES.TSInterfaceDeclaration:
1012
- case import_utils16.AST_NODE_TYPES.TSTypeParameter:
1013
- case import_utils16.AST_NODE_TYPES.TSQualifiedName:
1445
+ case import_utils20.AST_NODE_TYPES.TSTypeReference:
1446
+ case import_utils20.AST_NODE_TYPES.TSTypeAnnotation:
1447
+ case import_utils20.AST_NODE_TYPES.TSTypeParameterInstantiation:
1448
+ case import_utils20.AST_NODE_TYPES.TSInterfaceHeritage:
1449
+ case import_utils20.AST_NODE_TYPES.TSClassImplements:
1450
+ case import_utils20.AST_NODE_TYPES.TSTypeQuery:
1451
+ case import_utils20.AST_NODE_TYPES.TSTypeAssertion:
1452
+ case import_utils20.AST_NODE_TYPES.TSAsExpression:
1453
+ case import_utils20.AST_NODE_TYPES.TSSatisfiesExpression:
1454
+ case import_utils20.AST_NODE_TYPES.TSTypeAliasDeclaration:
1455
+ case import_utils20.AST_NODE_TYPES.TSInterfaceDeclaration:
1456
+ case import_utils20.AST_NODE_TYPES.TSTypeParameter:
1457
+ case import_utils20.AST_NODE_TYPES.TSQualifiedName:
1014
1458
  return true;
1015
- case import_utils16.AST_NODE_TYPES.MemberExpression:
1016
- case import_utils16.AST_NODE_TYPES.Identifier:
1459
+ case import_utils20.AST_NODE_TYPES.MemberExpression:
1460
+ case import_utils20.AST_NODE_TYPES.Identifier:
1017
1461
  current = current.parent;
1018
1462
  break;
1019
1463
  default:
@@ -1043,26 +1487,26 @@ var preferImportType = createRule14({
1043
1487
  return false;
1044
1488
  }
1045
1489
  switch (parent.type) {
1046
- case import_utils16.AST_NODE_TYPES.CallExpression:
1047
- case import_utils16.AST_NODE_TYPES.NewExpression:
1048
- case import_utils16.AST_NODE_TYPES.JSXOpeningElement:
1049
- case import_utils16.AST_NODE_TYPES.JSXClosingElement:
1050
- case import_utils16.AST_NODE_TYPES.MemberExpression:
1051
- case import_utils16.AST_NODE_TYPES.VariableDeclarator:
1052
- case import_utils16.AST_NODE_TYPES.TaggedTemplateExpression:
1053
- case import_utils16.AST_NODE_TYPES.SpreadElement:
1054
- case import_utils16.AST_NODE_TYPES.ExportSpecifier:
1055
- case import_utils16.AST_NODE_TYPES.ArrayExpression:
1056
- case import_utils16.AST_NODE_TYPES.ObjectExpression:
1057
- case import_utils16.AST_NODE_TYPES.BinaryExpression:
1058
- case import_utils16.AST_NODE_TYPES.LogicalExpression:
1059
- case import_utils16.AST_NODE_TYPES.UnaryExpression:
1060
- case import_utils16.AST_NODE_TYPES.ReturnStatement:
1061
- case import_utils16.AST_NODE_TYPES.ArrowFunctionExpression:
1062
- case import_utils16.AST_NODE_TYPES.ConditionalExpression:
1063
- case import_utils16.AST_NODE_TYPES.AwaitExpression:
1064
- case import_utils16.AST_NODE_TYPES.YieldExpression:
1065
- case import_utils16.AST_NODE_TYPES.Property:
1490
+ case import_utils20.AST_NODE_TYPES.CallExpression:
1491
+ case import_utils20.AST_NODE_TYPES.NewExpression:
1492
+ case import_utils20.AST_NODE_TYPES.JSXOpeningElement:
1493
+ case import_utils20.AST_NODE_TYPES.JSXClosingElement:
1494
+ case import_utils20.AST_NODE_TYPES.MemberExpression:
1495
+ case import_utils20.AST_NODE_TYPES.VariableDeclarator:
1496
+ case import_utils20.AST_NODE_TYPES.TaggedTemplateExpression:
1497
+ case import_utils20.AST_NODE_TYPES.SpreadElement:
1498
+ case import_utils20.AST_NODE_TYPES.ExportSpecifier:
1499
+ case import_utils20.AST_NODE_TYPES.ArrayExpression:
1500
+ case import_utils20.AST_NODE_TYPES.ObjectExpression:
1501
+ case import_utils20.AST_NODE_TYPES.BinaryExpression:
1502
+ case import_utils20.AST_NODE_TYPES.LogicalExpression:
1503
+ case import_utils20.AST_NODE_TYPES.UnaryExpression:
1504
+ case import_utils20.AST_NODE_TYPES.ReturnStatement:
1505
+ case import_utils20.AST_NODE_TYPES.ArrowFunctionExpression:
1506
+ case import_utils20.AST_NODE_TYPES.ConditionalExpression:
1507
+ case import_utils20.AST_NODE_TYPES.AwaitExpression:
1508
+ case import_utils20.AST_NODE_TYPES.YieldExpression:
1509
+ case import_utils20.AST_NODE_TYPES.Property:
1066
1510
  return true;
1067
1511
  default:
1068
1512
  return false;
@@ -1086,13 +1530,13 @@ var preferImportType = createRule14({
1086
1530
  }
1087
1531
  const scope = context.sourceCode.getScope(node);
1088
1532
  const isTypeOnlyImport = node.specifiers.every((specifier) => {
1089
- if (specifier.type === import_utils16.AST_NODE_TYPES.ImportDefaultSpecifier) {
1533
+ if (specifier.type === import_utils20.AST_NODE_TYPES.ImportDefaultSpecifier) {
1090
1534
  return false;
1091
1535
  }
1092
- if (specifier.type === import_utils16.AST_NODE_TYPES.ImportNamespaceSpecifier) {
1536
+ if (specifier.type === import_utils20.AST_NODE_TYPES.ImportNamespaceSpecifier) {
1093
1537
  return false;
1094
1538
  }
1095
- if (specifier.type === import_utils16.AST_NODE_TYPES.ImportSpecifier) {
1539
+ if (specifier.type === import_utils20.AST_NODE_TYPES.ImportSpecifier) {
1096
1540
  const localName = specifier.local.name;
1097
1541
  return !isUsedAsValue(localName, scope);
1098
1542
  }
@@ -1118,11 +1562,11 @@ var preferImportType = createRule14({
1118
1562
  var prefer_import_type_default = preferImportType;
1119
1563
 
1120
1564
  // src/rules/prefer-interface-over-inline-types.ts
1121
- var import_utils17 = require("@typescript-eslint/utils");
1122
- var createRule15 = import_utils17.ESLintUtils.RuleCreator(
1565
+ var import_utils21 = require("@typescript-eslint/utils");
1566
+ var createRule19 = import_utils21.ESLintUtils.RuleCreator(
1123
1567
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1124
1568
  );
1125
- var preferInterfaceOverInlineTypes = createRule15({
1569
+ var preferInterfaceOverInlineTypes = createRule19({
1126
1570
  name: "prefer-interface-over-inline-types",
1127
1571
  meta: {
1128
1572
  type: "suggestion",
@@ -1138,67 +1582,67 @@ var preferInterfaceOverInlineTypes = createRule15({
1138
1582
  defaultOptions: [],
1139
1583
  create(context) {
1140
1584
  function hasJSXInConditional(node) {
1141
- return node.consequent.type === import_utils17.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils17.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils17.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils17.AST_NODE_TYPES.JSXFragment;
1585
+ return node.consequent.type === import_utils21.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils21.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXFragment;
1142
1586
  }
1143
1587
  function hasJSXInLogical(node) {
1144
- return node.right.type === import_utils17.AST_NODE_TYPES.JSXElement || node.right.type === import_utils17.AST_NODE_TYPES.JSXFragment;
1588
+ return node.right.type === import_utils21.AST_NODE_TYPES.JSXElement || node.right.type === import_utils21.AST_NODE_TYPES.JSXFragment;
1145
1589
  }
1146
1590
  function hasJSXReturn(block) {
1147
1591
  return block.body.some((stmt) => {
1148
- if (stmt.type === import_utils17.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
1149
- return stmt.argument.type === import_utils17.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils17.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils17.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils17.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
1592
+ if (stmt.type === import_utils21.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
1593
+ return stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils21.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils21.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
1150
1594
  }
1151
1595
  return false;
1152
1596
  });
1153
1597
  }
1154
- function isReactComponent(node) {
1155
- if (node.type === import_utils17.AST_NODE_TYPES.ArrowFunctionExpression) {
1156
- if (node.body.type === import_utils17.AST_NODE_TYPES.JSXElement || node.body.type === import_utils17.AST_NODE_TYPES.JSXFragment) {
1598
+ function isReactComponent2(node) {
1599
+ if (node.type === import_utils21.AST_NODE_TYPES.ArrowFunctionExpression) {
1600
+ if (node.body.type === import_utils21.AST_NODE_TYPES.JSXElement || node.body.type === import_utils21.AST_NODE_TYPES.JSXFragment) {
1157
1601
  return true;
1158
1602
  }
1159
- if (node.body.type === import_utils17.AST_NODE_TYPES.BlockStatement) {
1603
+ if (node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
1160
1604
  return hasJSXReturn(node.body);
1161
1605
  }
1162
- } else if (node.type === import_utils17.AST_NODE_TYPES.FunctionExpression || node.type === import_utils17.AST_NODE_TYPES.FunctionDeclaration) {
1163
- if (node.body && node.body.type === import_utils17.AST_NODE_TYPES.BlockStatement) {
1606
+ } else if (node.type === import_utils21.AST_NODE_TYPES.FunctionExpression || node.type === import_utils21.AST_NODE_TYPES.FunctionDeclaration) {
1607
+ if (node.body && node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
1164
1608
  return hasJSXReturn(node.body);
1165
1609
  }
1166
1610
  }
1167
1611
  return false;
1168
1612
  }
1169
1613
  function isInlineTypeAnnotation(node) {
1170
- if (node.type === import_utils17.AST_NODE_TYPES.TSTypeLiteral) {
1614
+ if (node.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral) {
1171
1615
  return true;
1172
1616
  }
1173
- if (node.type === import_utils17.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
1174
- return node.typeArguments.params.some((param) => param.type === import_utils17.AST_NODE_TYPES.TSTypeLiteral);
1617
+ if (node.type === import_utils21.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
1618
+ return node.typeArguments.params.some((param) => param.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral);
1175
1619
  }
1176
- if (node.type === import_utils17.AST_NODE_TYPES.TSUnionType) {
1620
+ if (node.type === import_utils21.AST_NODE_TYPES.TSUnionType) {
1177
1621
  return node.types.some((type) => isInlineTypeAnnotation(type));
1178
1622
  }
1179
1623
  return false;
1180
1624
  }
1181
1625
  function hasInlineObjectType(node) {
1182
- if (node.type === import_utils17.AST_NODE_TYPES.TSTypeLiteral) {
1626
+ if (node.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral) {
1183
1627
  return true;
1184
1628
  }
1185
- if (node.type === import_utils17.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
1186
- return node.typeArguments.params.some((param) => param.type === import_utils17.AST_NODE_TYPES.TSTypeLiteral);
1629
+ if (node.type === import_utils21.AST_NODE_TYPES.TSTypeReference && node.typeArguments) {
1630
+ return node.typeArguments.params.some((param) => param.type === import_utils21.AST_NODE_TYPES.TSTypeLiteral);
1187
1631
  }
1188
- if (node.type === import_utils17.AST_NODE_TYPES.TSUnionType) {
1632
+ if (node.type === import_utils21.AST_NODE_TYPES.TSUnionType) {
1189
1633
  return node.types.some((type) => hasInlineObjectType(type));
1190
1634
  }
1191
1635
  return false;
1192
1636
  }
1193
1637
  function checkFunction(node) {
1194
- if (!isReactComponent(node)) {
1638
+ if (!isReactComponent2(node)) {
1195
1639
  return;
1196
1640
  }
1197
1641
  if (node.params.length !== 1) {
1198
1642
  return;
1199
1643
  }
1200
1644
  const param = node.params[0];
1201
- if (param.type === import_utils17.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
1645
+ if (param.type === import_utils21.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
1202
1646
  const { typeAnnotation } = param.typeAnnotation;
1203
1647
  if (isInlineTypeAnnotation(typeAnnotation) && hasInlineObjectType(typeAnnotation)) {
1204
1648
  context.report({
@@ -1218,11 +1662,11 @@ var preferInterfaceOverInlineTypes = createRule15({
1218
1662
  var prefer_interface_over_inline_types_default = preferInterfaceOverInlineTypes;
1219
1663
 
1220
1664
  // src/rules/prefer-jsx-template-literals.ts
1221
- var import_utils18 = require("@typescript-eslint/utils");
1222
- var createRule16 = import_utils18.ESLintUtils.RuleCreator(
1665
+ var import_utils22 = require("@typescript-eslint/utils");
1666
+ var createRule20 = import_utils22.ESLintUtils.RuleCreator(
1223
1667
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1224
1668
  );
1225
- var preferJSXTemplateLiterals = createRule16({
1669
+ var preferJSXTemplateLiterals = createRule20({
1226
1670
  name: "prefer-jsx-template-literals",
1227
1671
  meta: {
1228
1672
  type: "suggestion",
@@ -1291,9 +1735,9 @@ var preferJSXTemplateLiterals = createRule16({
1291
1735
  if (!child || !nextChild) {
1292
1736
  return;
1293
1737
  }
1294
- if (child.type === import_utils18.AST_NODE_TYPES.JSXText && nextChild.type === import_utils18.AST_NODE_TYPES.JSXExpressionContainer) {
1738
+ if (child.type === import_utils22.AST_NODE_TYPES.JSXText && nextChild.type === import_utils22.AST_NODE_TYPES.JSXExpressionContainer) {
1295
1739
  handleTextBeforeExpression(child, nextChild);
1296
- } else if (child.type === import_utils18.AST_NODE_TYPES.JSXExpressionContainer && nextChild.type === import_utils18.AST_NODE_TYPES.JSXText) {
1740
+ } else if (child.type === import_utils22.AST_NODE_TYPES.JSXExpressionContainer && nextChild.type === import_utils22.AST_NODE_TYPES.JSXText) {
1297
1741
  handleExpressionBeforeText(child, nextChild);
1298
1742
  }
1299
1743
  }
@@ -1306,11 +1750,11 @@ var preferJSXTemplateLiterals = createRule16({
1306
1750
  var prefer_jsx_template_literals_default = preferJSXTemplateLiterals;
1307
1751
 
1308
1752
  // src/rules/prefer-named-param-types.ts
1309
- var import_utils19 = require("@typescript-eslint/utils");
1310
- var createRule17 = import_utils19.ESLintUtils.RuleCreator(
1753
+ var import_utils23 = require("@typescript-eslint/utils");
1754
+ var createRule21 = import_utils23.ESLintUtils.RuleCreator(
1311
1755
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1312
1756
  );
1313
- var preferNamedParamTypes = createRule17({
1757
+ var preferNamedParamTypes = createRule21({
1314
1758
  name: "prefer-named-param-types",
1315
1759
  meta: {
1316
1760
  type: "suggestion",
@@ -1325,16 +1769,16 @@ var preferNamedParamTypes = createRule17({
1325
1769
  defaultOptions: [],
1326
1770
  create(context) {
1327
1771
  function hasInlineObjectType(param) {
1328
- if (param.type === import_utils19.AST_NODE_TYPES.AssignmentPattern) {
1772
+ if (param.type === import_utils23.AST_NODE_TYPES.AssignmentPattern) {
1329
1773
  return hasInlineObjectType(param.left);
1330
1774
  }
1331
- if (param.type === import_utils19.AST_NODE_TYPES.ObjectPattern) {
1332
- if (param.typeAnnotation?.typeAnnotation.type === import_utils19.AST_NODE_TYPES.TSTypeLiteral) {
1775
+ if (param.type === import_utils23.AST_NODE_TYPES.ObjectPattern) {
1776
+ if (param.typeAnnotation?.typeAnnotation.type === import_utils23.AST_NODE_TYPES.TSTypeLiteral) {
1333
1777
  return true;
1334
1778
  }
1335
1779
  }
1336
- if (param.type === import_utils19.AST_NODE_TYPES.Identifier) {
1337
- if (param.typeAnnotation?.typeAnnotation.type === import_utils19.AST_NODE_TYPES.TSTypeLiteral) {
1780
+ if (param.type === import_utils23.AST_NODE_TYPES.Identifier) {
1781
+ if (param.typeAnnotation?.typeAnnotation.type === import_utils23.AST_NODE_TYPES.TSTypeLiteral) {
1338
1782
  return true;
1339
1783
  }
1340
1784
  }
@@ -1368,11 +1812,11 @@ var preferNamedParamTypes = createRule17({
1368
1812
  var prefer_named_param_types_default = preferNamedParamTypes;
1369
1813
 
1370
1814
  // src/rules/prefer-react-import-types.ts
1371
- var import_utils20 = require("@typescript-eslint/utils");
1372
- var createRule18 = import_utils20.ESLintUtils.RuleCreator(
1815
+ var import_utils24 = require("@typescript-eslint/utils");
1816
+ var createRule22 = import_utils24.ESLintUtils.RuleCreator(
1373
1817
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1374
1818
  );
1375
- var preferReactImportTypes = createRule18({
1819
+ var preferReactImportTypes = createRule22({
1376
1820
  name: "prefer-react-import-types",
1377
1821
  meta: {
1378
1822
  type: "suggestion",
@@ -1448,7 +1892,7 @@ var preferReactImportTypes = createRule18({
1448
1892
  ]);
1449
1893
  const allReactExports = /* @__PURE__ */ new Set([...reactTypes, ...reactRuntimeExports]);
1450
1894
  function checkMemberExpression(node) {
1451
- if (node.object.type === import_utils20.AST_NODE_TYPES.Identifier && node.object.name === "React" && node.property.type === import_utils20.AST_NODE_TYPES.Identifier && allReactExports.has(node.property.name)) {
1895
+ if (node.object.type === import_utils24.AST_NODE_TYPES.Identifier && node.object.name === "React" && node.property.type === import_utils24.AST_NODE_TYPES.Identifier && allReactExports.has(node.property.name)) {
1452
1896
  const typeName = node.property.name;
1453
1897
  const isType = reactTypes.has(typeName);
1454
1898
  const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
@@ -1465,7 +1909,7 @@ var preferReactImportTypes = createRule18({
1465
1909
  return {
1466
1910
  MemberExpression: checkMemberExpression,
1467
1911
  "TSTypeReference > TSQualifiedName": (node) => {
1468
- if (node.left.type === import_utils20.AST_NODE_TYPES.Identifier && node.left.name === "React" && node.right.type === import_utils20.AST_NODE_TYPES.Identifier && allReactExports.has(node.right.name)) {
1912
+ if (node.left.type === import_utils24.AST_NODE_TYPES.Identifier && node.left.name === "React" && node.right.type === import_utils24.AST_NODE_TYPES.Identifier && allReactExports.has(node.right.name)) {
1469
1913
  const typeName = node.right.name;
1470
1914
  const isType = reactTypes.has(typeName);
1471
1915
  const importStatement = isType ? `import type { ${typeName} } from "react"` : `import { ${typeName} } from "react"`;
@@ -1485,11 +1929,11 @@ var preferReactImportTypes = createRule18({
1485
1929
  var prefer_react_import_types_default = preferReactImportTypes;
1486
1930
 
1487
1931
  // src/rules/react-props-destructure.ts
1488
- var import_utils21 = require("@typescript-eslint/utils");
1489
- var createRule19 = import_utils21.ESLintUtils.RuleCreator(
1932
+ var import_utils25 = require("@typescript-eslint/utils");
1933
+ var createRule23 = import_utils25.ESLintUtils.RuleCreator(
1490
1934
  (name) => `https://github.com/next-friday/eslint-plugin-nextfriday/blob/main/docs/rules/${name.replaceAll("-", "_").toUpperCase()}.md`
1491
1935
  );
1492
- var reactPropsDestructure = createRule19({
1936
+ var reactPropsDestructure = createRule23({
1493
1937
  name: "react-props-destructure",
1494
1938
  meta: {
1495
1939
  type: "suggestion",
@@ -1505,45 +1949,45 @@ var reactPropsDestructure = createRule19({
1505
1949
  defaultOptions: [],
1506
1950
  create(context) {
1507
1951
  function hasJSXInConditional(node) {
1508
- return node.consequent.type === import_utils21.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils21.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils21.AST_NODE_TYPES.JSXFragment;
1952
+ return node.consequent.type === import_utils25.AST_NODE_TYPES.JSXElement || node.consequent.type === import_utils25.AST_NODE_TYPES.JSXFragment || node.alternate.type === import_utils25.AST_NODE_TYPES.JSXElement || node.alternate.type === import_utils25.AST_NODE_TYPES.JSXFragment;
1509
1953
  }
1510
1954
  function hasJSXInLogical(node) {
1511
- return node.right.type === import_utils21.AST_NODE_TYPES.JSXElement || node.right.type === import_utils21.AST_NODE_TYPES.JSXFragment;
1955
+ return node.right.type === import_utils25.AST_NODE_TYPES.JSXElement || node.right.type === import_utils25.AST_NODE_TYPES.JSXFragment;
1512
1956
  }
1513
1957
  function hasJSXReturn(block) {
1514
1958
  return block.body.some((stmt) => {
1515
- if (stmt.type === import_utils21.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
1516
- return stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils21.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils21.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils21.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
1959
+ if (stmt.type === import_utils25.AST_NODE_TYPES.ReturnStatement && stmt.argument) {
1960
+ return stmt.argument.type === import_utils25.AST_NODE_TYPES.JSXElement || stmt.argument.type === import_utils25.AST_NODE_TYPES.JSXFragment || stmt.argument.type === import_utils25.AST_NODE_TYPES.ConditionalExpression && hasJSXInConditional(stmt.argument) || stmt.argument.type === import_utils25.AST_NODE_TYPES.LogicalExpression && hasJSXInLogical(stmt.argument);
1517
1961
  }
1518
1962
  return false;
1519
1963
  });
1520
1964
  }
1521
- function isReactComponent(node) {
1522
- if (node.type === import_utils21.AST_NODE_TYPES.ArrowFunctionExpression) {
1523
- if (node.body.type === import_utils21.AST_NODE_TYPES.JSXElement || node.body.type === import_utils21.AST_NODE_TYPES.JSXFragment) {
1965
+ function isReactComponent2(node) {
1966
+ if (node.type === import_utils25.AST_NODE_TYPES.ArrowFunctionExpression) {
1967
+ if (node.body.type === import_utils25.AST_NODE_TYPES.JSXElement || node.body.type === import_utils25.AST_NODE_TYPES.JSXFragment) {
1524
1968
  return true;
1525
1969
  }
1526
- if (node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
1970
+ if (node.body.type === import_utils25.AST_NODE_TYPES.BlockStatement) {
1527
1971
  return hasJSXReturn(node.body);
1528
1972
  }
1529
- } else if (node.type === import_utils21.AST_NODE_TYPES.FunctionExpression || node.type === import_utils21.AST_NODE_TYPES.FunctionDeclaration) {
1530
- if (node.body && node.body.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
1973
+ } else if (node.type === import_utils25.AST_NODE_TYPES.FunctionExpression || node.type === import_utils25.AST_NODE_TYPES.FunctionDeclaration) {
1974
+ if (node.body && node.body.type === import_utils25.AST_NODE_TYPES.BlockStatement) {
1531
1975
  return hasJSXReturn(node.body);
1532
1976
  }
1533
1977
  }
1534
1978
  return false;
1535
1979
  }
1536
1980
  function checkFunction(node) {
1537
- if (!isReactComponent(node)) {
1981
+ if (!isReactComponent2(node)) {
1538
1982
  return;
1539
1983
  }
1540
1984
  if (node.params.length !== 1) {
1541
1985
  return;
1542
1986
  }
1543
1987
  const param = node.params[0];
1544
- if (param.type === import_utils21.AST_NODE_TYPES.ObjectPattern) {
1545
- const properties = param.properties.filter((prop) => prop.type === import_utils21.AST_NODE_TYPES.Property).map((prop) => {
1546
- if (prop.key.type === import_utils21.AST_NODE_TYPES.Identifier) {
1988
+ if (param.type === import_utils25.AST_NODE_TYPES.ObjectPattern) {
1989
+ const properties = param.properties.filter((prop) => prop.type === import_utils25.AST_NODE_TYPES.Property).map((prop) => {
1990
+ if (prop.key.type === import_utils25.AST_NODE_TYPES.Identifier) {
1547
1991
  return prop.key.name;
1548
1992
  }
1549
1993
  return null;
@@ -1575,6 +2019,7 @@ var meta = {
1575
2019
  version: package_default.version
1576
2020
  };
1577
2021
  var rules = {
2022
+ "boolean-naming-prefix": boolean_naming_prefix_default,
1578
2023
  "enforce-readonly-component-props": enforce_readonly_component_props_default,
1579
2024
  "enforce-sorted-destructuring": enforce_sorted_destructuring_default,
1580
2025
  "file-kebab-case": file_kebab_case_default,
@@ -1583,11 +2028,14 @@ var rules = {
1583
2028
  "jsx-no-variable-in-callback": jsx_no_variable_in_callback_default,
1584
2029
  "md-filename-case-restriction": md_filename_case_restriction_default,
1585
2030
  "no-complex-inline-return": no_complex_inline_return_default,
2031
+ "no-direct-date": no_direct_date_default,
1586
2032
  "no-emoji": no_emoji_default,
1587
2033
  "no-env-fallback": no_env_fallback_default,
1588
- "no-explicit-return-type": no_explicit_return_type_default,
2034
+ "require-explicit-return-type": require_explicit_return_type_default,
1589
2035
  "no-logic-in-params": no_logic_in_params_default,
2036
+ "no-single-char-variables": no_single_char_variables_default,
1590
2037
  "prefer-destructuring-params": prefer_destructuring_params_default,
2038
+ "prefer-function-declaration": prefer_function_declaration_default,
1591
2039
  "prefer-import-type": prefer_import_type_default,
1592
2040
  "prefer-interface-over-inline-types": prefer_interface_over_inline_types_default,
1593
2041
  "prefer-jsx-template-literals": prefer_jsx_template_literals_default,
@@ -1600,32 +2048,40 @@ var plugin = {
1600
2048
  rules
1601
2049
  };
1602
2050
  var baseRules = {
2051
+ "nextfriday/boolean-naming-prefix": "warn",
1603
2052
  "nextfriday/no-emoji": "warn",
1604
2053
  "nextfriday/enforce-sorted-destructuring": "warn",
1605
2054
  "nextfriday/file-kebab-case": "warn",
1606
2055
  "nextfriday/md-filename-case-restriction": "warn",
1607
2056
  "nextfriday/prefer-destructuring-params": "warn",
1608
- "nextfriday/no-explicit-return-type": "warn",
2057
+ "nextfriday/prefer-function-declaration": "warn",
2058
+ "nextfriday/require-explicit-return-type": "warn",
1609
2059
  "nextfriday/prefer-import-type": "warn",
1610
2060
  "nextfriday/prefer-named-param-types": "warn",
1611
2061
  "nextfriday/prefer-react-import-types": "warn",
1612
2062
  "nextfriday/no-complex-inline-return": "warn",
2063
+ "nextfriday/no-direct-date": "warn",
1613
2064
  "nextfriday/no-logic-in-params": "warn",
1614
- "nextfriday/no-env-fallback": "warn"
2065
+ "nextfriday/no-env-fallback": "warn",
2066
+ "nextfriday/no-single-char-variables": "warn"
1615
2067
  };
1616
2068
  var baseRecommendedRules = {
2069
+ "nextfriday/boolean-naming-prefix": "error",
1617
2070
  "nextfriday/no-emoji": "error",
1618
2071
  "nextfriday/enforce-sorted-destructuring": "error",
1619
2072
  "nextfriday/file-kebab-case": "error",
1620
2073
  "nextfriday/md-filename-case-restriction": "error",
1621
2074
  "nextfriday/prefer-destructuring-params": "error",
1622
- "nextfriday/no-explicit-return-type": "error",
2075
+ "nextfriday/prefer-function-declaration": "error",
2076
+ "nextfriday/require-explicit-return-type": "error",
1623
2077
  "nextfriday/prefer-import-type": "error",
1624
2078
  "nextfriday/prefer-named-param-types": "error",
1625
2079
  "nextfriday/prefer-react-import-types": "error",
1626
2080
  "nextfriday/no-complex-inline-return": "error",
2081
+ "nextfriday/no-direct-date": "error",
1627
2082
  "nextfriday/no-logic-in-params": "error",
1628
- "nextfriday/no-env-fallback": "error"
2083
+ "nextfriday/no-env-fallback": "error",
2084
+ "nextfriday/no-single-char-variables": "error"
1629
2085
  };
1630
2086
  var jsxRules = {
1631
2087
  "nextfriday/jsx-pascal-case": "warn",