@cookshack/eslint-config 3.0.0 → 5.0.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/dist/index.js CHANGED
@@ -11,7 +11,7 @@ function print
11
11
  printBuffer.push(args.join(' '));
12
12
  }
13
13
 
14
- function trace$1
14
+ function trace$2
15
15
  (...args) {
16
16
  }
17
17
 
@@ -120,7 +120,8 @@ function getConditionalContext
120
120
  return ''
121
121
  }
122
122
 
123
- function nodeContains(node, target) {
123
+ function nodeContains
124
+ (node, target) {
124
125
  if (node == target)
125
126
  return true
126
127
  if (node && typeof node == 'object')
@@ -130,7 +131,8 @@ function nodeContains(node, target) {
130
131
  return false
131
132
  }
132
133
 
133
- function nodeHas(value, target) {
134
+ function nodeHas
135
+ (value, target) {
134
136
  if (value == target)
135
137
  return true
136
138
  if (Array.isArray(value))
@@ -194,7 +196,8 @@ function mayBeReadBeforeAnyWrite
194
196
  }
195
197
  }
196
198
 
197
- function scopeStart(scope) {
199
+ function scopeStart
200
+ (scope) {
198
201
  if (scope.block == null)
199
202
  return Infinity
200
203
  if (scope.type == 'function' && scope.block.id)
@@ -222,12 +225,11 @@ function buildScopeTree
222
225
  (scope, prefix, scopeToNode, astToTree) {
223
226
  let node, siblingNum;
224
227
 
225
- node = {
226
- scope,
227
- prefix,
228
- items: [],
229
- children: []
230
- };
228
+ node = { scope,
229
+ prefix,
230
+ items: [],
231
+ children: [] };
232
+
231
233
  scopeToNode.set(scope, node);
232
234
  if (scope.block && astToTree)
233
235
  astToTree.set(scope.block, node);
@@ -329,38 +331,36 @@ function checkScopeNode
329
331
 
330
332
  defScope = getDefinitionScope(variable);
331
333
  defNodePrefix = scopeToNode.get(defScope)?.prefix ?? '?';
332
- trace$1(indent, '1 found decl scope of', variable.name + ':', defNodePrefix + ' ' + defScope.type.toUpperCase());
334
+ trace$2(indent, '1 found decl scope of', variable.name + ':', defNodePrefix + ' ' + defScope.type.toUpperCase());
333
335
 
334
336
  narrowestScope = getNarrowestScope(variable);
335
337
  if (narrowestScope) {
336
338
  let narrowestPrefix;
337
339
 
338
340
  narrowestPrefix = scopeToNode.get(narrowestScope)?.prefix ?? '?';
339
- trace$1(indent, '2 found narrowest scope of', variable.name + ':', narrowestPrefix + ' ' + narrowestScope?.type.toUpperCase());
341
+ trace$2(indent, '2 found narrowest scope of', variable.name + ':', narrowestPrefix + ' ' + narrowestScope?.type.toUpperCase());
340
342
 
341
343
  markConditionalRefs(variable, scopeToNode, narrowestScope);
342
344
 
343
345
  if (defScope == narrowestScope)
344
346
  continue
345
- trace$1(indent, '3', variable.name, 'could be moved to a narrower scope');
347
+ trace$2(indent, '3', variable.name, 'could be moved to a narrower scope');
346
348
 
347
349
  if (defScope.type == 'for') {
348
- trace$1(indent, '4 exception:', variable.name, 'is in a for loop header');
350
+ trace$2(indent, '4 exception:', variable.name, 'is in a for loop header');
349
351
  continue
350
352
  }
351
353
  if (mayBeReadBeforeAnyWrite(variable, scopeToNode, narrowestScope)) {
352
- trace$1(indent, '4 exception:', variable.name, 'mayBeReadBeforeAnyWrite');
354
+ trace$2(indent, '4 exception:', variable.name, 'mayBeReadBeforeAnyWrite');
353
355
  continue
354
356
  }
355
357
 
356
- trace$1(indent, '5', variable.name, 'is too broad');
358
+ trace$2(indent, '5', variable.name, 'is too broad');
357
359
 
358
360
  reported.add(variable);
359
- context.report({
360
- node: defNode,
361
- messageId: 'tooBroad',
362
- data: { name: variable.name }
363
- });
361
+ context.report({ node: defNode,
362
+ messageId: 'tooBroad',
363
+ data: { name: variable.name } });
364
364
  }
365
365
  }
366
366
  }
@@ -405,17 +405,16 @@ function createNarrowestScope
405
405
  clearPrintBuffer();
406
406
  scopeManager = context.sourceCode.scopeManager;
407
407
  if (scopeManager)
408
- return {
409
- 'Program:exit'() {
410
- let tree, scopeToNode;
411
-
412
- scopeToNode = new Map;
413
- nextVarId = 0;
414
- tree = buildScopeTree(scopeManager.scopes[0], '1', scopeToNode);
415
- checkScopeNode(context, tree, null, scopeToNode);
416
- printTree(tree, 0);
417
- }
418
- }
408
+ return { 'Program:exit'
409
+ () {
410
+ let tree, scopeToNode;
411
+
412
+ scopeToNode = new Map;
413
+ nextVarId = 0;
414
+ tree = buildScopeTree(scopeManager.scopes[0], '1', scopeToNode);
415
+ checkScopeNode(context, tree, null, scopeToNode);
416
+ printTree(tree, 0);
417
+ } }
419
418
  }
420
419
 
421
420
  var narrowestScopePlugin = { meta: { type: 'suggestion',
@@ -426,21 +425,21 @@ var narrowestScopePlugin = { meta: { type: 'suggestion',
426
425
 
427
426
  function createPositiveVibes
428
427
  (context) {
429
- return {
430
- UnaryExpression(node) {
431
- if (node.operator == '!')
432
- context.report({ node,
433
- messageId: 'positiveVibes' });
434
- },
435
- BinaryExpression(node) {
436
- if (node.operator == '!=')
437
- context.report({ node,
438
- messageId: 'equality' });
439
- else if (node.operator == '!==')
440
- context.report({ node,
441
- messageId: 'strictEquality' });
442
- }
443
- }
428
+ return { UnaryExpression
429
+ (node) {
430
+ if (node.operator == '!')
431
+ context.report({ node,
432
+ messageId: 'positiveVibes' });
433
+ },
434
+ BinaryExpression
435
+ (node) {
436
+ if (node.operator == '!=')
437
+ context.report({ node,
438
+ messageId: 'equality' });
439
+ else if (node.operator == '!==')
440
+ context.report({ node,
441
+ messageId: 'strictEquality' });
442
+ } }
444
443
  }
445
444
 
446
445
  var positiveVibesPlugin = { meta: { type: 'problem',
@@ -455,57 +454,60 @@ var useRiskyEqualPlugin = { meta: { type: 'problem',
455
454
  docs: { description: 'Enforce use of == instead of ===.' },
456
455
  messages: { risky: 'Use ==.' },
457
456
  schema: [] },
458
- create(context) {
459
- return { BinaryExpression(node) {
460
- if (node.operator == '===')
461
- context.report({ node, messageId: 'risky' });
462
- } }
457
+ create
458
+ (context) {
459
+ return { BinaryExpression
460
+ (node) {
461
+ if (node.operator == '===')
462
+ context.report({ node, messageId: 'risky' });
463
+ } }
463
464
  } };
464
465
 
465
- function create$2
466
+ function create$4
466
467
  (context) {
467
- return { VariableDeclaration(node) {
468
- if (node.kind == 'const' || node.kind == 'var')
469
- context.report({ node, messageId: 'useLet' });
470
- } }
468
+ return { VariableDeclaration
469
+ (node) {
470
+ if (node.kind == 'const' || node.kind == 'var')
471
+ context.report({ node, messageId: 'useLet' });
472
+ } }
471
473
  }
472
474
 
473
475
  var alwaysLetPlugin = { meta: { type: 'problem',
474
476
  docs: { description: 'Enforce use of let instead of const or var.' },
475
477
  messages: { useLet: 'Use let.' },
476
478
  schema: [] },
477
- create: create$2 };
479
+ create: create$4 };
478
480
 
479
- let ostIdCounter, ost;
481
+ let ostIdCounter, $lastOst;
480
482
 
481
483
  ostIdCounter = 0;
482
- ost = 0;
484
+ $lastOst = 0;
483
485
 
484
- function trace
486
+ function trace$1
485
487
  (...args) {
486
488
  }
487
489
 
488
- function createInitBeforeUse(context) {
490
+ function createInitBeforeUse
491
+ (context) {
489
492
  let scopeManager;
490
493
 
491
494
  scopeManager = context.sourceCode.scopeManager;
492
495
  if (scopeManager)
493
- return {
494
- 'Program:exit'() {
495
- let scopeToNode, astToTree, astToOst;
496
- scopeToNode = new Map;
497
- astToTree = new Map;
498
- astToOst = new Map;
499
- buildScopeTree(scopeManager.scopes[0], '1', scopeToNode, astToTree);
496
+ return { 'Program:exit'
497
+ () {
498
+ let scopeToNode, astToTree, astToOst;
499
+ scopeToNode = new Map;
500
+ astToTree = new Map;
501
+ astToOst = new Map;
502
+ buildScopeTree(scopeManager.scopes[0], '1', scopeToNode, astToTree);
500
503
 
501
- ostIdCounter = 0;
502
- ost = processAst(context.sourceCode.ast, null, astToTree, astToOst, '', new Set());
504
+ ostIdCounter = 0;
505
+ $lastOst = processAst(context.sourceCode.ast, null, astToTree, astToOst, '', new Set());
503
506
 
504
- ostAnnotate(ost, astToOst, context);
507
+ ostAnnotate($lastOst, astToOst, context);
505
508
 
506
- ostCheck(ost, context);
507
- }
508
- }
509
+ ostCheck($lastOst, context);
510
+ } }
509
511
  }
510
512
 
511
513
  function isRegularDeclaration
@@ -518,7 +520,8 @@ function isRegularDeclaration
518
520
  return 0
519
521
  }
520
522
 
521
- function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
523
+ function processAst
524
+ (astNode, parentOst, astToTree, astToOst, indent, visited) {
522
525
  if (astNode) {
523
526
  let treeNode, scopeName, lets, reads, writes, ost, children;
524
527
 
@@ -531,7 +534,7 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
531
534
  scopeName = treeNode?.scope ? `${treeNode.scope.type}` : 'no-scope';
532
535
  if (treeNode?.scope?.block?.id?.name)
533
536
  scopeName += `(${treeNode.scope.block.id.name})`;
534
- trace(`${indent}${astNode.type}`);
537
+ trace$1(`${indent}${astNode.type}`);
535
538
 
536
539
  lets = [];
537
540
  reads = [];
@@ -544,31 +547,29 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
544
547
  scopeCreator = treeNode?.scope?.block;
545
548
  if (scopeCreator && astNode == scopeCreator) {
546
549
  lets.push({ item });
547
- trace(`${indent} | LET ${item.name}:${item.varId}`);
550
+ trace$1(`${indent} | LET ${item.name}:${item.varId}`);
548
551
  }
549
552
  }
550
553
  else if (item.ref)
551
554
  if (astNode == item.ref.identifier)
552
555
  if (item.type == 'READ') {
553
556
  reads.push({ item });
554
- trace(`${indent} | READ ${item.name}:${item.varId}`);
557
+ trace$1(`${indent} | READ ${item.name}:${item.varId}`);
555
558
  }
556
559
  else if (item.type == 'WRITE') {
557
560
  writes.push({ item });
558
- trace(`${indent} | WRITE ${item.name}:${item.varId}`);
561
+ trace$1(`${indent} | WRITE ${item.name}:${item.varId}`);
559
562
  }
560
563
 
561
- ost = {
562
- id: ostIdCounter++,
563
- astNode,
564
- treeNode,
565
- scopeItems: treeNode?.items ?? [],
566
- lets,
567
- reads,
568
- writes,
569
- children: [],
570
- fnDefOst: null
571
- };
564
+ ost = { id: ostIdCounter++,
565
+ astNode,
566
+ treeNode,
567
+ scopeItems: treeNode?.items ?? [],
568
+ lets,
569
+ reads,
570
+ writes,
571
+ children: [],
572
+ fnDefOst: null };
572
573
 
573
574
  astToOst.set(astNode, ost);
574
575
 
@@ -654,7 +655,8 @@ function processAst(astNode, parentOst, astToTree, astToOst, indent, visited) {
654
655
  }
655
656
  }
656
657
 
657
- function ostAnnotate(ost, astToOst, context) {
658
+ function ostAnnotate
659
+ (ost, astToOst, context) {
658
660
  if (ost) {
659
661
  for (let letInfo of ost.lets) {
660
662
  let writeOst;
@@ -665,11 +667,9 @@ function ostAnnotate(ost, astToOst, context) {
665
667
  continue
666
668
  if (letInfo.item.defType == 'ImportBinding')
667
669
  continue
668
- context.report({
669
- node: letInfo.item.identifier,
670
- messageId: 'mustInit',
671
- data: { name: letInfo.item.name }
672
- });
670
+ context.report({ node: letInfo.item.identifier,
671
+ messageId: 'mustInit',
672
+ data: { name: letInfo.item.name } });
673
673
  }
674
674
 
675
675
  if (ost.astNode.type == 'CallExpression' && ost.astNode.callee?.type == 'Identifier')
@@ -700,7 +700,8 @@ function ostAnnotate(ost, astToOst, context) {
700
700
  }
701
701
  }
702
702
 
703
- function findFirstWrite(ost, letInfo) {
703
+ function findFirstWrite
704
+ (ost, letInfo) {
704
705
  if (ost.astNode.type == 'FunctionDeclaration' || ost.astNode.type == 'ArrowFunctionExpression' || ost.astNode.type == 'FunctionExpression')
705
706
  for (let child of ost.children)
706
707
  if (child.astNode.type == 'BlockStatement')
@@ -708,7 +709,8 @@ function findFirstWrite(ost, letInfo) {
708
709
  return findFirstWriteInSubtree(ost, letInfo)
709
710
  }
710
711
 
711
- function findFirstWriteInSubtree(ost, letInfo) {
712
+ function findFirstWriteInSubtree
713
+ (ost, letInfo) {
712
714
  if (ost) {
713
715
  if (ost.astNode.type == 'FunctionDeclaration' || ost.astNode.type == 'ArrowFunctionExpression' || ost.astNode.type == 'FunctionExpression')
714
716
  return null
@@ -733,7 +735,8 @@ function findFirstWriteInSubtree(ost, letInfo) {
733
735
  return null
734
736
  }
735
737
 
736
- function ostCheck(ost, context) {
738
+ function ostCheck
739
+ (ost, context) {
737
740
  if (ost) {
738
741
  for (let letInfo of ost.lets)
739
742
  if (letInfo.firstWrite)
@@ -744,7 +747,8 @@ function ostCheck(ost, context) {
744
747
  }
745
748
  }
746
749
 
747
- function walk2Start(node, letInfo, context) {
750
+ function walk2Start
751
+ (node, letInfo, context) {
748
752
  if (node.astNode.type == 'FunctionDeclaration')
749
753
  for (let child of node.children)
750
754
  if (child.astNode.type == 'BlockStatement')
@@ -752,7 +756,8 @@ function walk2Start(node, letInfo, context) {
752
756
  return walk2(node, letInfo, context, new Set())
753
757
  }
754
758
 
755
- function walk2(node, letInfo, context, visited) {
759
+ function walk2
760
+ (node, letInfo, context, visited) {
756
761
  if (node) {
757
762
  if (node.astNode.type == 'FunctionDeclaration' || node.astNode.type == 'ArrowFunctionExpression' || node.astNode.type == 'FunctionExpression')
758
763
  return false
@@ -760,11 +765,9 @@ function walk2(node, letInfo, context, visited) {
760
765
  if (node == letInfo.firstWrite) {
761
766
  for (let readInfo of node.reads)
762
767
  if (readInfo.item.ref.resolved == letInfo.item.variable) {
763
- context.report({
764
- node: readInfo.item.ref.identifier,
765
- messageId: 'initBeforeUse',
766
- data: { name: letInfo.item.name }
767
- });
768
+ context.report({ node: readInfo.item.ref.identifier,
769
+ messageId: 'initBeforeUse',
770
+ data: { name: letInfo.item.name } });
768
771
  }
769
772
  return true
770
773
  }
@@ -790,11 +793,9 @@ function walk2(node, letInfo, context, visited) {
790
793
 
791
794
  for (let readInfo of node.reads)
792
795
  if (readInfo.item.ref.resolved == letInfo.item.variable) {
793
- context.report({
794
- node: readInfo.item.ref.identifier,
795
- messageId: 'initBeforeUse',
796
- data: { name: letInfo.item.name }
797
- });
796
+ context.report({ node: readInfo.item.ref.identifier,
797
+ messageId: 'initBeforeUse',
798
+ data: { name: letInfo.item.name } });
798
799
  }
799
800
 
800
801
  for (let child of node.children)
@@ -805,19 +806,14 @@ function walk2(node, letInfo, context, visited) {
805
806
  return false
806
807
  }
807
808
 
808
- var initBeforeUsePlugin = {
809
- meta: {
810
- type: 'problem',
811
- docs: { description: 'Warn when a variable is used before being explicitly initialized.' },
812
- messages: { initBeforeUse: "'{{name}}' used before initialization.",
813
- mustInit: "'{{name}}' must be initialized." },
814
- schema: []
815
- },
816
- create: createInitBeforeUse
817
- };
809
+ var initBeforeUsePlugin = { meta: { type: 'problem',
810
+ docs: { description: 'Warn when a variable is used before being explicitly initialized.' },
811
+ messages: { initBeforeUse: "'{{name}}' used before initialization.",
812
+ mustInit: "'{{name}}' must be initialized." },
813
+ schema: [] },
814
+ create: createInitBeforeUse };
818
815
 
819
- function
820
- VariableDeclaration
816
+ function VariableDeclaration
821
817
  (context, node) {
822
818
  let parent;
823
819
 
@@ -842,7 +838,8 @@ VariableDeclaration
842
838
  }
843
839
  }
844
840
  }
845
- function create$1
841
+
842
+ function create$3
846
843
  (context) {
847
844
  return { VariableDeclaration: node => VariableDeclaration(context, node) }
848
845
  }
@@ -851,10 +848,9 @@ var varDeclBlockStartPlugin = { meta: { type: 'suggestion',
851
848
  docs: { description: 'Require variable declarations to be at the start of the block.' },
852
849
  messages: { varDeclBlockStart: 'VarDecl must be at start of block.' },
853
850
  schema: [] },
854
- create: create$1 };
851
+ create: create$3 };
855
852
 
856
- function
857
- FunctionDeclaration
853
+ function FunctionDeclaration
858
854
  (context, node) {
859
855
  let parent;
860
856
 
@@ -880,7 +876,7 @@ FunctionDeclaration
880
876
  }
881
877
  }
882
878
 
883
- function create
879
+ function create$2
884
880
  (context) {
885
881
  return { FunctionDeclaration: node => FunctionDeclaration(context, node) }
886
882
  }
@@ -889,7 +885,162 @@ var fnDeclBlockStartPlugin = { meta: { type: 'suggestion',
889
885
  docs: { description: 'Require function declarations to be at the start of the block.' },
890
886
  messages: { fnDeclBlockStart: 'FnDecl must be the start the block (after VarDecls).' },
891
887
  schema: [] },
892
- create };
888
+ create: create$2 };
889
+
890
+ function FnArgsNl
891
+ (node, context) {
892
+ let nameLine, parenLine, nameEnd, i, newlines, parent;
893
+
894
+ parent = node.parent;
895
+
896
+ if (parent?.type == 'Property' && (parent.method || parent.kind == 'get' || parent.kind == 'set')) {
897
+ nameLine = parent.key.loc.start.line;
898
+ nameEnd = parent.key.range[1];
899
+ }
900
+ else if (parent?.type == 'MethodDefinition') {
901
+ nameLine = parent.key.loc.start.line;
902
+ nameEnd = parent.key.range[1];
903
+ }
904
+ else {
905
+ nameLine = node.loc.start.line;
906
+ nameEnd = node.range[0];
907
+ }
908
+
909
+ i = nameEnd;
910
+ newlines = 0;
911
+ while (i < context.sourceCode.text.length) {
912
+ if (context.sourceCode.text[i] == '(')
913
+ break
914
+ if (context.sourceCode.text[i] == '\n')
915
+ newlines++;
916
+ i++;
917
+ }
918
+
919
+ parenLine = nameLine + newlines;
920
+
921
+ if (parenLine - nameLine == 1)
922
+ return
923
+ context.report({ node, messageId: 'fnArgsNl' });
924
+ }
925
+
926
+ function create$1
927
+ (context) {
928
+ return { FunctionDeclaration: node => FnArgsNl(node, context),
929
+ FunctionExpression: node => FnArgsNl(node, context) }
930
+ }
931
+
932
+ var fnArgsNlPlugin = { meta: { type: 'suggestion',
933
+ docs: { description: 'Require function args on the line immediately after the function name.' },
934
+ messages: { fnArgsNl: 'Fn args must be on the line immediately after the function name.' },
935
+ schema: [] },
936
+ create: create$1 };
937
+
938
+ function trace
939
+ (...args) {
940
+ }
941
+
942
+ function unit
943
+ (context) {
944
+ return context.options[0] ?? 2
945
+ }
946
+
947
+ function checkObjectExpressionProperties
948
+ (properties, node, context) {
949
+ let firstProp, sourceCode, lastProp, lastPropEnd, closingBrace, firstPropLine, firstPropCol, afterLastProp, closingLine, lastPropValueEndLine;
950
+
951
+ sourceCode = context.sourceCode.text;
952
+ firstProp = properties[0];
953
+ lastProp = properties[properties.length - 1];
954
+ firstPropLine = firstProp.loc.start.line;
955
+ firstPropCol = firstProp.loc.start.column;
956
+ lastPropEnd = lastProp.range[1];
957
+ closingBrace = sourceCode.indexOf('}', lastPropEnd);
958
+ closingLine = sourceCode.slice(0, closingBrace).split('\n').length;
959
+ afterLastProp = sourceCode.slice(lastPropEnd, closingBrace);
960
+ lastPropValueEndLine = sourceCode.slice(0, lastPropEnd).split('\n').length;
961
+ trace('CHECK POINT 1: is single-line? firstPropLine=%d, braceLine=%d, closingLine=%d', firstPropLine, node.loc.start.line, closingLine);
962
+ if (firstPropLine == node.loc.start.line && closingLine == firstPropLine)
963
+ return
964
+ trace('CHECK POINT 2: is firstPropLine (%d) != braceLine (%d)?', firstPropLine, node.loc.start.line);
965
+ if (firstPropLine == node.loc.start.line) ;
966
+ else if (firstPropCol == node.loc.start.column + unit(context)) ;
967
+ else {
968
+ context.report({ node: firstProp, messageId: 'indentStruct' });
969
+ }
970
+ for (let i = 1; i < properties.length; i++) {
971
+ let prop;
972
+
973
+ prop = properties[i];
974
+ if (prop.loc.start.column == firstPropCol) ;
975
+ else {
976
+ context.report({ node: prop, messageId: 'indentStruct' });
977
+ }
978
+ }
979
+ if (closingLine > lastPropValueEndLine) {
980
+ let braceCol, closingCol;
981
+
982
+ braceCol = node.loc.start.column;
983
+ closingCol = node.loc.end.column - 1;
984
+ if (closingCol == braceCol) ;
985
+ else {
986
+ context.report({ node, messageId: 'indentStruct' });
987
+ }
988
+ }
989
+ if (closingLine == lastPropValueEndLine) {
990
+ if (afterLastProp == ' ') ;
991
+ else {
992
+ context.report({ node, messageId: 'indentStruct' });
993
+ }
994
+ }
995
+ for (let prop of properties)
996
+ if (prop.method) {
997
+ let keyLine, keyEnd, i, newlines, parenLine;
998
+
999
+ keyLine = prop.key.loc.start.line;
1000
+ keyEnd = prop.key.range[1];
1001
+ i = keyEnd;
1002
+ newlines = 0;
1003
+
1004
+ while (i < sourceCode.length) {
1005
+ if (sourceCode[i] == '(')
1006
+ break
1007
+ if (sourceCode[i] == '\n')
1008
+ newlines++;
1009
+ i++;
1010
+ }
1011
+ parenLine = keyLine + newlines;
1012
+ if (parenLine > keyLine) {
1013
+ let parenCol;
1014
+
1015
+ parenCol = i - sourceCode.lastIndexOf('\n', i);
1016
+ if (prop.value.type == 'FunctionExpression' && prop.value.async) ;
1017
+ else if (parenCol - 1 == prop.key.loc.start.column) ;
1018
+ else {
1019
+ context.report({ node: prop, messageId: 'indentStruct' });
1020
+ }
1021
+ }
1022
+ }
1023
+ }
1024
+
1025
+ function checkObjectExpression
1026
+ (node, context) {
1027
+ let properties;
1028
+
1029
+ properties = node.properties;
1030
+ if (properties.length)
1031
+ checkObjectExpressionProperties(properties, node, context);
1032
+ }
1033
+
1034
+ function create
1035
+ (context) {
1036
+ return { ObjectExpression: node => checkObjectExpression(node, context) }
1037
+ }
1038
+
1039
+ var indentStructPlugin = { meta: { type: 'suggestion',
1040
+ docs: { description: 'Struct alignment rules.' },
1041
+ messages: { indentStruct: 'Indent structure' },
1042
+ schema: [] },
1043
+ create };
893
1044
 
894
1045
  let rules, languageOptions, plugins;
895
1046
 
@@ -899,75 +1050,69 @@ plugins = { 'cookshack': { rules: { 'positive-vibes': positiveVibesPlugin,
899
1050
  'always-let': alwaysLetPlugin,
900
1051
  'init-before-use': initBeforeUsePlugin,
901
1052
  'var-decl-block-start': varDeclBlockStartPlugin,
902
- 'fn-decl-block-start': fnDeclBlockStartPlugin } } };
903
-
904
- rules = {
905
- 'array-bracket-newline': [ 'error', 'never' ],
906
- 'array-bracket-spacing': [ 'error', 'always' ],
907
- 'arrow-parens': [ 'error', 'as-needed' ],
908
- 'brace-style': [ 'error', 'stroustrup' ],
909
- 'comma-dangle': 'error',
910
- 'curly': [ 'error', 'multi' ],
911
- 'eol-last': [ 'error', 'always' ],
912
- 'function-paren-newline': [ 'error', 'never' ],
913
- 'indent': [ 'error', 2, { ArrayExpression: 'first',
914
- CallExpression: { arguments: 'first' },
915
- //flatTernaryExpressions: true,
916
- //offsetTernaryExpressions: true,
917
- // ternary, because overhangs strangely (eg multiline in array def)
918
- 'ignoredNodes': [ 'ConditionalExpression' ],
919
- FunctionDeclaration: { parameters: 'first', body: 1 },
920
- FunctionExpression: { parameters: 'first', body: 1 },
921
- ImportDeclaration: 'first',
922
- ObjectExpression: 'first',
923
- offsetTernaryExpressions: true,
924
- VariableDeclarator: 'first' } ],
925
- 'init-declarations': [ 'error', 'never', { 'ignoreForLoopInit': true } ],
926
- 'keyword-spacing': [ 'error', { before: true, after: true } ],
927
- 'linebreak-style': [ 'error', 'unix' ],
928
- 'padding-line-between-statements': [ 'error',
929
- { blankLine: 'always', prev: 'let', next: '*' },
930
- { blankLine: 'never', prev: 'let', next: 'let' } ],
931
- 'no-case-declarations': 'error',
932
- 'no-global-assign': 'error',
933
- 'cookshack/positive-vibes': 'error',
934
- 'cookshack/narrowest-scope': 'error',
935
- 'cookshack/use-risky-equal': 'error',
936
- 'cookshack/always-let': 'error',
937
- // using the implicit inititialization to undefined fits better
938
- //'cookshack/init-before-use': 'error',
939
- 'cookshack/var-decl-block-start': 'error',
940
- 'cookshack/fn-decl-block-start': 'error',
941
- 'no-mixed-operators': 'error',
942
- 'no-multi-spaces': 'error',
943
- 'no-multiple-empty-lines': [ 'error', { max: 1, maxEOF: 0 } ],
944
- 'no-negated-condition': 'error',
945
- 'no-redeclare': 'error',
946
- 'no-sequences': 'error',
947
- 'no-sparse-arrays': 'error',
948
- 'no-tabs': 'error',
949
- 'no-trailing-spaces': 'error',
950
- 'no-undef': 'error',
951
- 'no-unsafe-negation': 'error',
952
- 'no-unused-vars': 'error',
953
- 'no-var': 'error',
954
- 'object-curly-spacing': [ 'error', 'always' ],
955
- 'object-shorthand': [ 'error', 'always' ],
956
- quotes: [ 'error', 'single', { avoidEscape: true } ],
957
- semi: [ 'error', 'never' ]
958
- //'vars-on-top': [ 'error' ], // want version for let
959
- //'newline-before-function-paren': ['error', 'always'],
960
- };
961
-
962
- languageOptions = {
963
- globals: {
964
- ...globals.node
965
- },
966
- parserOptions: {
967
- ecmaVersion: 2025,
968
- sourceType: 'module'
969
- }
970
- };
1053
+ 'fn-decl-block-start': fnDeclBlockStartPlugin,
1054
+ 'fn-args-nl': fnArgsNlPlugin,
1055
+ 'indent-struct': indentStructPlugin } } };
1056
+
1057
+ rules = { 'array-bracket-newline': [ 'error', 'never' ],
1058
+ 'array-bracket-spacing': [ 'error', 'always' ],
1059
+ 'arrow-parens': [ 'error', 'as-needed' ],
1060
+ 'brace-style': [ 'error', 'stroustrup' ],
1061
+ 'comma-dangle': 'error',
1062
+ 'curly': [ 'error', 'multi' ],
1063
+ 'eol-last': [ 'error', 'always' ],
1064
+ 'function-paren-newline': [ 'error', 'never' ],
1065
+ 'indent': [ 'error', 2, { ArrayExpression: 'first',
1066
+ CallExpression: { arguments: 'first' },
1067
+ //flatTernaryExpressions: true,
1068
+ //offsetTernaryExpressions: true,
1069
+ // ternary, because overhangs strangely (eg multiline in array def)
1070
+ 'ignoredNodes': [ 'ConditionalExpression', 'ObjectExpression *' ],
1071
+ FunctionDeclaration: { parameters: 'first', body: 1 },
1072
+ FunctionExpression: { parameters: 'first', body: 1 },
1073
+ ImportDeclaration: 'first',
1074
+ offsetTernaryExpressions: true,
1075
+ VariableDeclarator: 'first' } ],
1076
+ 'init-declarations': [ 'error', 'never', { 'ignoreForLoopInit': true } ],
1077
+ 'keyword-spacing': [ 'error', { before: true, after: true } ],
1078
+ 'linebreak-style': [ 'error', 'unix' ],
1079
+ 'padding-line-between-statements': [ 'error',
1080
+ { blankLine: 'always', prev: 'let', next: '*' },
1081
+ { blankLine: 'never', prev: 'let', next: 'let' } ],
1082
+ 'no-case-declarations': 'error',
1083
+ 'no-global-assign': 'error',
1084
+ 'cookshack/positive-vibes': 'error',
1085
+ 'cookshack/narrowest-scope': 'error',
1086
+ 'cookshack/use-risky-equal': 'error',
1087
+ 'cookshack/always-let': 'error',
1088
+ // using the implicit inititialization to undefined fits better
1089
+ //'cookshack/init-before-use': 'error',
1090
+ 'cookshack/var-decl-block-start': 'error',
1091
+ 'cookshack/fn-decl-block-start': 'error',
1092
+ 'cookshack/fn-args-nl': 'error',
1093
+ 'cookshack/indent-struct': 'error',
1094
+ 'no-mixed-operators': 'error',
1095
+ 'no-multi-spaces': 'error',
1096
+ 'no-multiple-empty-lines': [ 'error', { max: 1, maxEOF: 0 } ],
1097
+ 'no-negated-condition': 'error',
1098
+ 'no-redeclare': 'error',
1099
+ 'no-sequences': 'error',
1100
+ 'no-shadow': [ 'error', { builtinGlobals: true } ],
1101
+ 'no-sparse-arrays': 'error',
1102
+ 'no-tabs': 'error',
1103
+ 'no-trailing-spaces': 'error',
1104
+ 'no-undef': 'error',
1105
+ 'no-unsafe-negation': 'error',
1106
+ 'no-unused-vars': 'error',
1107
+ 'no-var': 'error',
1108
+ 'object-curly-spacing': [ 'error', 'always' ],
1109
+ 'object-shorthand': [ 'error', 'always' ],
1110
+ quotes: [ 'error', 'single', { avoidEscape: true } ],
1111
+ semi: [ 'error', 'never' ] };
1112
+
1113
+ languageOptions = { globals: { ...globals.node },
1114
+ parserOptions: { ecmaVersion: 2025,
1115
+ sourceType: 'module' } };
971
1116
 
972
1117
  var index = [ { ignores: [ 'TAGS.mjs' ] },
973
1118
  { languageOptions,