@bigbinary/eslint-plugin-neeto 1.1.21 → 1.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +270 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -46,6 +46,7 @@ module.exports = {
46
46
 
47
47
  ## Exported rules
48
48
 
49
+ - [use-use-mutation-with-invalidation-hook](./docs/src/rules/use-use-mutation-with-invalidation-hook.md)
49
50
  - [no-withT-for-smart-components](./docs/src/rules/no-withT-for-smart-components.md)
50
51
  - [no-large-functions-inside-jsx](./docs/src/rules/no-large-functions-inside-jsx.md)
51
52
  - [use-standard-date-time-formats](./docs/src/rules/use-standard-date-time-formats.md)
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@
42
42
  var commonResolve$2 = loadJS$2("node_modules/@bigbinary/neeto-commons-frontend/configs/webpack/resolve.js");
43
43
  var resolve$2 = ramda.mergeDeepLeft(projectResolve$2, commonResolve$2);
44
44
  var rules = {
45
+ "@bigbinary/neeto/use-use-mutation-with-invalidation-hook": "error",
45
46
  "@bigbinary/neeto/no-withT-for-smart-components": "error",
46
47
  "@bigbinary/neeto/no-large-functions-inside-jsx": "error",
47
48
  "@bigbinary/neeto/use-standard-date-time-formats": "error",
@@ -549,6 +550,7 @@
549
550
  var NO_WITH_T_IN_SMART_COMPONENTS = '"withT" HOC should only be used in dumb components. "useTranslation" hook should be used here.';
550
551
  var USE_STANDARD_DATE_TIME_FORMATS = 'Use "dateFormat/timeFormat" from "@bigbinary/neeto-commons-frontend/utils" instead. Refer: https://github.com/bigbinary/neeto-commons-frontend/blob/main/docs/utils/README.md#dateformattimeformat';
551
552
  var MOVE_SPREAD_ATTRIBUTES_TO_TOP = "Move spread attribute to top";
553
+ var USE_USE_MUTATION_WITH_INVALIDATION = "Use useMutationWithInvalidation from 'neetocommons/react-utils'";
552
554
 
553
555
  var PACKAGES_TO_CHECK = ["@bigbinary/neeto-molecules", "@bigbinary/neetoui", "@bigbinary/neeto-commons-frontend"];
554
556
 
@@ -5368,7 +5370,7 @@
5368
5370
  };
5369
5371
 
5370
5372
  //import { } from "neetocommons/react-utils";
5371
- var REACT_UTILS_IMPORT_PATTERN$1 = {
5373
+ var REACT_UTILS_IMPORT_PATTERN$2 = {
5372
5374
  type: TYPES.IMPORT_DECLARATION,
5373
5375
  source: {
5374
5376
  type: TYPES.LITERAL,
@@ -5478,7 +5480,7 @@
5478
5480
  context: context,
5479
5481
  fixer: fixer,
5480
5482
  functions: ["handleMetaClick"],
5481
- importPattern: REACT_UTILS_IMPORT_PATTERN$1
5483
+ importPattern: REACT_UTILS_IMPORT_PATTERN$2
5482
5484
  });
5483
5485
  if (importStatement) fixerArray.push(importStatement);
5484
5486
  return fixerArray;
@@ -6648,7 +6650,7 @@
6648
6650
  var restOfString = inputString.slice(position + 1);
6649
6651
  return firstCharacter + textToInsert + restOfString;
6650
6652
  };
6651
- var reportError = function reportError(_ref) {
6653
+ var reportError$1 = function reportError(_ref) {
6652
6654
  var context = _ref.context,
6653
6655
  node = _ref.node,
6654
6656
  arrowFunctionExpression = _ref.arrowFunctionExpression,
@@ -6689,7 +6691,7 @@
6689
6691
  componentDeclaration = node;
6690
6692
  if (!pure.matches(WITH_T_HOC_PATTERN, node)) return;
6691
6693
  var arrowFunctionExpression = node.declarations[0].init.arguments[0];
6692
- reportError({
6694
+ reportError$1({
6693
6695
  context: context,
6694
6696
  node: node,
6695
6697
  arrowFunctionExpression: arrowFunctionExpression
@@ -6698,7 +6700,7 @@
6698
6700
  ExportDefaultDeclaration: function ExportDefaultDeclaration(node) {
6699
6701
  if (!pure.matches(EXPORTED_WITH_T_PATTERN, node)) return;
6700
6702
  if (!pure.matches(SMART_COMPONENT_PATTERN, componentDeclaration)) return;
6701
- reportError({
6703
+ reportError$1({
6702
6704
  context: context,
6703
6705
  node: node,
6704
6706
  arrowFunctionExpression: componentDeclaration.declarations[0].init,
@@ -26298,6 +26300,268 @@
26298
26300
  }
26299
26301
  };
26300
26302
 
26303
+ var ONSUCCESS_OPTION = {
26304
+ type: TYPES.PROPERTY,
26305
+ key: {
26306
+ name: "onSuccess"
26307
+ }
26308
+ };
26309
+
26310
+ // keysToInvalidate: [...]
26311
+ var KEYS_TO_INVALIDATE_OPTION = {
26312
+ type: TYPES.PROPERTY,
26313
+ key: {
26314
+ name: "keysToInvalidate"
26315
+ }
26316
+ };
26317
+
26318
+ // {
26319
+ // onSuccess: (...) => {....},
26320
+ // ...,
26321
+ // });
26322
+ var OPTIONS = {
26323
+ type: TYPES.OBJECT_EXPRESSION,
26324
+ properties: pure.existsBy(ONSUCCESS_OPTION)
26325
+ };
26326
+
26327
+ // useMutation(api.update, {
26328
+ // onSuccess: (...) => {....},
26329
+ // ...,
26330
+ // });
26331
+ var USE_MUTATION_HOOK_WITH_ONSUCCESS = {
26332
+ callee: {
26333
+ type: TYPES.IDENTIFIER,
26334
+ name: ramda.includes(ramda.__, ["useMutation", "useMutationWithInvalidation"])
26335
+ },
26336
+ arguments: pure.existsBy(OPTIONS)
26337
+ };
26338
+
26339
+ // useMutation(api.update, {
26340
+ // onSuccess: (...) => {....queryClient....},
26341
+ // ...,
26342
+ // });
26343
+ var INVALIDATION_PATTERN = {
26344
+ type: TYPES.EXPRESSION_STATEMENT,
26345
+ expression: {
26346
+ type: TYPES.CALL_EXPRESSION,
26347
+ callee: {
26348
+ type: TYPES.MEMBER_EXPRESSION,
26349
+ object: {
26350
+ type: TYPES.IDENTIFIER,
26351
+ name: "queryClient"
26352
+ }
26353
+ }
26354
+ }
26355
+ };
26356
+
26357
+ // () => queryClient.invalidateQueries(CUSTOMERS)
26358
+ var SINGLE_INVALIDATION_PATTERN = {
26359
+ type: TYPES.CALL_EXPRESSION,
26360
+ callee: {
26361
+ type: TYPES.MEMBER_EXPRESSION,
26362
+ object: {
26363
+ type: TYPES.IDENTIFIER,
26364
+ name: "queryClient"
26365
+ },
26366
+ property: {
26367
+ type: TYPES.IDENTIFIER,
26368
+ name: "invalidateQueries"
26369
+ }
26370
+ }
26371
+ };
26372
+
26373
+ // import { useMutationWithInvalidation } from "neetocommons/react-utils";
26374
+ var USE_MUTATION_WITH_INVALIDATION_IMPORT_PATTERN = {
26375
+ type: TYPES.IMPORT_DECLARATION,
26376
+ specifiers: pure.existsBy({
26377
+ type: TYPES.IMPORT_SPECIFIER,
26378
+ imported: {
26379
+ type: TYPES.IDENTIFIER,
26380
+ name: "useMutationWithInvalidation"
26381
+ }
26382
+ }),
26383
+ source: {
26384
+ type: TYPES.LITERAL,
26385
+ value: "neetocommons/react-utils"
26386
+ }
26387
+ };
26388
+
26389
+ //import { } from "neetocommons/react-utils";
26390
+ var REACT_UTILS_IMPORT_PATTERN$1 = {
26391
+ type: TYPES.IMPORT_DECLARATION,
26392
+ source: {
26393
+ type: TYPES.LITERAL,
26394
+ value: "neetocommons/react-utils"
26395
+ },
26396
+ specifiers: [{
26397
+ type: TYPES.IMPORT_SPECIFIER
26398
+ }]
26399
+ };
26400
+
26401
+ // queryClient.setQueryData(...);
26402
+ var OTHER_QUERY_CLIENT_USAGE_PATTERN = {
26403
+ callee: {
26404
+ property: {
26405
+ type: TYPES.IDENTIFIER,
26406
+ name: pure.isNot("invalidateQueries")
26407
+ }
26408
+ }
26409
+ };
26410
+
26411
+ var reportError = function reportError(context, node) {
26412
+ context.report({
26413
+ node: node,
26414
+ message: USE_USE_MUTATION_WITH_INVALIDATION
26415
+ });
26416
+ };
26417
+ var getInitialFixerArray = function getInitialFixerArray(_ref) {
26418
+ var node = _ref.node,
26419
+ context = _ref.context,
26420
+ fixer = _ref.fixer,
26421
+ mutationOptions = _ref.mutationOptions,
26422
+ existingKeysToInvalidate = _ref.existingKeysToInvalidate,
26423
+ keys = _ref.keys,
26424
+ importExists = _ref.importExists;
26425
+ var replaceCallee = fixer.replaceText(node.callee, "useMutationWithInvalidation");
26426
+ var indentLevel = context.getSourceCode().getFirstToken(mutationOptions.properties[0]).loc.start.column;
26427
+ var addKeysToInvalidate;
26428
+ if (existingKeysToInvalidate) {
26429
+ addKeysToInvalidate = fixer.insertTextAfter(ramda.last(existingKeysToInvalidate.value.elements), ",".concat(keys));
26430
+ } else {
26431
+ addKeysToInvalidate = fixer.insertTextBefore(mutationOptions.properties[0], "keysToInvalidate: [".concat(keys, "],\n").concat(" ".repeat(indentLevel)));
26432
+ }
26433
+ var fixerArray = [replaceCallee, addKeysToInvalidate];
26434
+ if (!importExists) {
26435
+ var addImport = addFunctionImport({
26436
+ context: context,
26437
+ fixer: fixer,
26438
+ functions: ["useMutationWithInvalidation"],
26439
+ importPattern: REACT_UTILS_IMPORT_PATTERN$1
26440
+ });
26441
+ fixerArray.push(addImport);
26442
+ }
26443
+ return fixerArray;
26444
+ };
26445
+ var getRemoveCommaFix = function getRemoveCommaFix(context, fixer, onSuccess) {
26446
+ var tokenAfter = context.getTokenAfter(onSuccess);
26447
+ return tokenAfter.value === "," ? fixer.remove(tokenAfter) : null;
26448
+ };
26449
+ var getVariables = function getVariables(context, params) {
26450
+ var _params$arguments$0$e;
26451
+ var variables = (_params$arguments$0$e = params.arguments[0].elements) === null || _params$arguments$0$e === void 0 ? void 0 : _params$arguments$0$e.filter(function (element) {
26452
+ return element.type !== TYPES.LITERAL && /[a-z]/.test(context.getSourceCode().getText(element));
26453
+ });
26454
+ if (!params.arguments[0].elements && /[a-z]/.test(context.getSourceCode().getText(params.arguments[0]))) {
26455
+ variables = params.arguments[0];
26456
+ }
26457
+ return variables;
26458
+ };
26459
+
26460
+ var useUseMutationWithInvalidationHook = {
26461
+ meta: {
26462
+ type: "problem",
26463
+ docs: {
26464
+ url: "https://github.com/bigbinary/eslint-plugin-neeto/blob/main/docs/src/rules/use-use-mutation-with-invalidation-hook.md",
26465
+ description: "Enforce use of useMutationWithInvalidation"
26466
+ },
26467
+ fixable: "code"
26468
+ },
26469
+ create: function create(context) {
26470
+ return {
26471
+ CallExpression: function CallExpression(node) {
26472
+ if (!pure.matches(USE_MUTATION_HOOK_WITH_ONSUCCESS, node)) return;
26473
+ var mutationOptions = pure.findBy({
26474
+ type: TYPES.OBJECT_EXPRESSION
26475
+ }, node.arguments);
26476
+ var onSuccess = pure.findBy(ONSUCCESS_OPTION, mutationOptions.properties);
26477
+ var existingKeysToInvalidate = pure.findBy(KEYS_TO_INVALIDATE_OPTION, mutationOptions.properties);
26478
+ if (!onSuccess.value.body) return;
26479
+ var importExists = pure.existsBy(USE_MUTATION_WITH_INVALIDATION_IMPORT_PATTERN, getAllImports(node));
26480
+ if (onSuccess.value.body.type === TYPES.CALL_EXPRESSION) {
26481
+ var params = onSuccess.value.body;
26482
+ if (!pure.matches(SINGLE_INVALIDATION_PATTERN, params)) return;
26483
+ var variables = getVariables(context, params);
26484
+ if (pure.isPresent(variables)) {
26485
+ reportError(context, node);
26486
+ } else {
26487
+ context.report({
26488
+ node: node,
26489
+ message: USE_USE_MUTATION_WITH_INVALIDATION,
26490
+ fix: function fix(fixer) {
26491
+ var fixerArray = getInitialFixerArray({
26492
+ node: node,
26493
+ context: context,
26494
+ fixer: fixer,
26495
+ mutationOptions: mutationOptions,
26496
+ existingKeysToInvalidate: existingKeysToInvalidate,
26497
+ keys: context.getSourceCode().getText(params.arguments[0]),
26498
+ importExists: importExists
26499
+ });
26500
+ var removeInvalidations = fixer.remove(onSuccess);
26501
+ fixerArray.push(removeInvalidations);
26502
+ var removeComma = getRemoveCommaFix(context, fixer, onSuccess);
26503
+ if (removeComma) fixerArray.push(removeComma);
26504
+ return fixerArray;
26505
+ }
26506
+ });
26507
+ }
26508
+ } else if (onSuccess.value.body.type === TYPES.BLOCK_STATEMENT) {
26509
+ var _params = onSuccess.value.body.body;
26510
+ var invalidations = pure._filterBy(INVALIDATION_PATTERN, _params);
26511
+ if (pure.isNotPresent(invalidations)) return;
26512
+ var otherOptions = pure._removeBy(INVALIDATION_PATTERN, _params);
26513
+ var queryClientInOtherOptions = otherOptions === null || otherOptions === void 0 ? void 0 : otherOptions.find(function (item) {
26514
+ return context.getSourceCode().getText(item).includes("queryClient");
26515
+ });
26516
+ if (queryClientInOtherOptions || pure.findBy(OTHER_QUERY_CLIENT_USAGE_PATTERN, ramda.pluck("expression", invalidations))) {
26517
+ return;
26518
+ }
26519
+ var invalidationsWithoutVariables = invalidations.filter(function (item) {
26520
+ var variables = getVariables(context, item.expression);
26521
+ return pure.isNotPresent(variables);
26522
+ });
26523
+ if (pure.isNotPresent(invalidationsWithoutVariables)) {
26524
+ reportError(context, node);
26525
+ } else {
26526
+ var keys = ramda.pluck("expression", invalidationsWithoutVariables).flatMap(function (item) {
26527
+ return item.arguments.map(function (arg) {
26528
+ return context.getSourceCode().getText(arg);
26529
+ });
26530
+ });
26531
+ context.report({
26532
+ node: node,
26533
+ message: USE_USE_MUTATION_WITH_INVALIDATION,
26534
+ fix: function fix(fixer) {
26535
+ var fixerArray = getInitialFixerArray({
26536
+ node: node,
26537
+ context: context,
26538
+ fixer: fixer,
26539
+ mutationOptions: mutationOptions,
26540
+ existingKeysToInvalidate: existingKeysToInvalidate,
26541
+ keys: keys.join(", "),
26542
+ importExists: importExists
26543
+ });
26544
+ if (_params.length === invalidationsWithoutVariables.length) {
26545
+ var _removeInvalidations = fixer.remove(onSuccess);
26546
+ fixerArray.push(_removeInvalidations);
26547
+ var removeComma = getRemoveCommaFix(context, fixer, onSuccess);
26548
+ if (removeComma) fixerArray.push(removeComma);
26549
+ return fixerArray;
26550
+ }
26551
+ var removeInvalidations = invalidationsWithoutVariables.map(function (item) {
26552
+ return fixer.remove(item);
26553
+ });
26554
+ fixerArray.push.apply(fixerArray, _toConsumableArray(removeInvalidations));
26555
+ return fixerArray;
26556
+ }
26557
+ });
26558
+ }
26559
+ }
26560
+ }
26561
+ };
26562
+ }
26563
+ };
26564
+
26301
26565
  var useWebpackAlias = {
26302
26566
  meta: {
26303
26567
  type: "suggestion",
@@ -26881,6 +27145,7 @@
26881
27145
 
26882
27146
  var index = {
26883
27147
  rules: {
27148
+ "use-use-mutation-with-invalidation-hook": useUseMutationWithInvalidationHook,
26884
27149
  "no-withT-for-smart-components": noWithTForSmartComponents,
26885
27150
  "no-large-functions-inside-jsx": noLargeFunctionsInsideJsx,
26886
27151
  "use-standard-date-time-formats": useStandardDateTimeFormats,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigbinary/eslint-plugin-neeto",
3
- "version": "1.1.21",
3
+ "version": "1.1.22",
4
4
  "main": "dist/index.js",
5
5
  "license": "UNLICENSED",
6
6
  "scripts": {