@anolilab/eslint-config 2.1.7 → 3.0.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ ### @anolilab/eslint-config [3.0.1](https://github.com/anolilab/javascript-style-guide/compare/@anolilab/eslint-config@3.0.0...@anolilab/eslint-config@3.0.1) (2022-02-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** updated all dependencies (non-major) ([6a4e889](https://github.com/anolilab/javascript-style-guide/commit/6a4e889bcdab9d11755b61850e7d24f9f4a0733f))
7
+
8
+ ## @anolilab/eslint-config [3.0.0](https://github.com/anolilab/javascript-style-guide/compare/@anolilab/eslint-config@2.2.0...@anolilab/eslint-config@3.0.0) (2022-02-15)
9
+
10
+
11
+ ### ⚠ BREAKING CHANGES
12
+
13
+ * remove old node version from our supported versions
14
+
15
+ Signed-off-by: prisis <d.bannert@anolilab.de>
16
+
17
+ ### Bug Fixes
18
+
19
+ * fixed wrong version on peer dependencies ([fc28d8b](https://github.com/anolilab/javascript-style-guide/commit/fc28d8b990bea3004283dfb37a249d0ffe3e476f))
20
+ * markdown lint ([24059d4](https://github.com/anolilab/javascript-style-guide/commit/24059d41ca682ca21b39ad7f6dff594be734329d))
21
+
22
+
23
+ ### Performance Improvements
24
+
25
+ * support for v12, v14 was removed from our supported versions of node ([83d6a80](https://github.com/anolilab/javascript-style-guide/commit/83d6a8058ed7791135aff03d4cd734327bb1b694))
26
+
27
+ ## @anolilab/eslint-config [2.2.0](https://github.com/anolilab/javascript-style-guide/compare/@anolilab/eslint-config@2.1.8...@anolilab/eslint-config@2.2.0) (2021-10-26)
28
+
29
+
30
+ ### Features
31
+
32
+ * updated ([642c2d5](https://github.com/anolilab/javascript-style-guide/commit/642c2d57a0f667bb9dbfd792210b97b8122a6595))
33
+
34
+ ### @anolilab/eslint-config [2.1.8](https://github.com/anolilab/javascript-style-guide/compare/@anolilab/eslint-config@2.1.7...@anolilab/eslint-config@2.1.8) (2021-09-13)
35
+
36
+
37
+ ### Bug Fixes
38
+
39
+ * **deps:** update dependency eslint-plugin-unicorn to v36 ([caa30c3](https://github.com/anolilab/javascript-style-guide/commit/caa30c336ab9e2e7f78cf2fc5b74321fe0399e33))
40
+
1
41
  ### @anolilab/eslint-config [2.1.7](https://github.com/anolilab/javascript-style-guide/compare/@anolilab/eslint-config@2.1.6...@anolilab/eslint-config@2.1.7) (2021-09-03)
2
42
 
3
43
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ESLint config
2
2
 
3
- This package provides Anolilab’s .eslintrc.cjs as an extensible shared config, with a range of useful plugins that are often too time-consuming to setup and provides an easy way to install just the plugins you need, based on your project’s dependencies.
3
+ This package provides Anolilab’s .eslintrc.cjs as an extensible shared config, with a range of useful plugins that are often too time-consuming to setup and provides an install the plugins you need, based on your project’s dependencies.
4
4
 
5
5
  ---
6
6
 
@@ -297,7 +297,7 @@ Therefore, `@anolilab/eslint-config` also inherits the philosophy of ESLint. It
297
297
  ## Supported Node.js Versions
298
298
 
299
299
  Libraries in this ecosystem make the best effort to track
300
- [Node.js' release schedule](https://nodejs.org/en/about/releases/). Here's [a
300
+ [Node.js release schedule](https://nodejs.org/en/about/releases/). Heres [a
301
301
  post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a).
302
302
 
303
303
  Contributing
package/config.cjs CHANGED
@@ -1,59 +1,59 @@
1
- const { hasAnyDep, hasTypescript } = require('./lib/utils.cjs');
2
- const isModuleAvailable = require('./lib/is-module-available.cjs');
1
+ const { hasAnyDep, hasTypescript } = require("./lib/utils.cjs");
2
+ const isModuleAvailable = require("./lib/is-module-available.cjs");
3
3
 
4
4
  // Base rules
5
- const rules = ['best-practices', 'errors', 'style', 'es6', 'variables'];
5
+ const rules = ["best-practices", "errors", "style", "es6", "variables"];
6
6
 
7
7
  // Base plugin rules
8
8
  const pRules = [
9
- 'compat',
10
- 'eslint-comments',
11
- 'import',
12
- 'json',
13
- 'markdown',
14
- 'optimize-regex',
15
- 'promise',
16
- 'simple-import-sort',
17
- 'unicorn',
18
- 'you-dont-need-lodash-underscore',
19
- 'you-dont-need-momentjs',
9
+ "compat",
10
+ "eslint-comments",
11
+ "import",
12
+ "json",
13
+ "markdown",
14
+ "optimize-regex",
15
+ "promise",
16
+ "simple-import-sort",
17
+ "unicorn",
18
+ "you-dont-need-lodash-underscore",
19
+ "you-dont-need-momentjs",
20
20
 
21
21
  // Security Rules
22
- 'no-secrets',
23
- 'radar',
22
+ "no-secrets",
23
+ "radar",
24
24
  ];
25
25
 
26
26
  // Optionals rules based on project dependencies
27
27
  const depRules = [
28
- 'array-func',
29
- 'html',
30
- 'mdx',
31
- 'react-redux',
32
- 'no-unsanitized',
33
- 'lodash',
34
- ['lodash', 'lodash-fp'],
35
- 'jsdoc',
36
- 'react',
37
- ['mdx', 'eslint-plugin-react'],
38
- ['react-a11y', 'react'],
39
- ['react-hooks', 'react'],
28
+ "array-func",
29
+ "html",
30
+ "mdx",
31
+ "react-redux",
32
+ "no-unsanitized",
33
+ "lodash",
34
+ ["lodash", "lodash-fp"],
35
+ "jsdoc",
36
+ "react",
37
+ ["mdx", "eslint-plugin-react"],
38
+ ["react-a11y", "react"],
39
+ ["react-hooks", "react"],
40
40
  ];
41
41
 
42
42
  const testRules = [
43
- 'cypress',
44
- 'jest',
45
- ['jest', 'jest-async', 'jest-dom'],
46
- 'jest-dom',
47
- ['jest-formatting', 'jest'],
48
- ['@testing-library/jest-dom', 'jest-dom'],
49
- ['@testing-library/dom', 'testing-library'],
43
+ "cypress",
44
+ "jest",
45
+ ["jest", "jest-async", "jest-dom"],
46
+ "jest-dom",
47
+ ["jest-formatting", "jest"],
48
+ ["@testing-library/jest-dom", "jest-dom"],
49
+ ["@testing-library/dom", "testing-library"],
50
50
  ];
51
51
 
52
52
  // Extra required optional packages
53
53
  const extraInstalled = [];
54
54
 
55
55
  depRules.forEach((depRule) => {
56
- const rule = typeof depRule === 'string' ? [depRule, depRule] : depRule;
56
+ const rule = typeof depRule === "string" ? [depRule, depRule] : depRule;
57
57
 
58
58
  if (hasAnyDep(rule[0])) {
59
59
  pRules.push(rule[1]);
@@ -61,7 +61,7 @@ depRules.forEach((depRule) => {
61
61
  });
62
62
 
63
63
  testRules.forEach((depRule) => {
64
- const rule = typeof depRule === 'string' ? [depRule, depRule] : depRule;
64
+ const rule = typeof depRule === "string" ? [depRule, depRule] : depRule;
65
65
 
66
66
  if (isModuleAvailable(rule[0])) {
67
67
  pRules.push(rule[1]);
@@ -69,16 +69,16 @@ testRules.forEach((depRule) => {
69
69
  });
70
70
 
71
71
  if (hasTypescript) {
72
- pRules.push('typescript');
73
- extraInstalled.push(['@typescript-eslint/parser', '@typescript-eslint/eslint-plugin']);
72
+ pRules.push("typescript");
73
+ extraInstalled.push(["@typescript-eslint/parser", "@typescript-eslint/eslint-plugin"]);
74
74
 
75
- if (hasAnyDep('eslint-plugin-typescript-sort-keys')) {
76
- pRules.push('typescript-sort-keys');
75
+ if (hasAnyDep("eslint-plugin-typescript-sort-keys")) {
76
+ pRules.push("typescript-sort-keys");
77
77
  }
78
78
  }
79
79
 
80
80
  module.exports = {
81
81
  rules,
82
82
  pluginRules: pRules,
83
- extraInstallPackage: extraInstalled
84
- }
83
+ extraInstallPackage: extraInstalled,
84
+ };
package/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
- const path = require('path');
2
- const checkMissing = require('./lib/check-missing.cjs');
3
- const showLoaded = require('./lib/show-loaded.cjs');
4
- const { rules, pluginRules, extraInstallPackage } = require('./config.cjs');
1
+ const path = require("path");
2
+ const checkMissing = require("./lib/check-missing.cjs");
3
+ const showLoaded = require("./lib/show-loaded.cjs");
4
+ const { rules, pluginRules, extraInstallPackage } = require("./config.cjs");
5
5
 
6
6
  // Workaround VS Code trying to run this file twice!
7
7
  if (!global.hasAnolilabEsLintConfigLoaded) {
package/lib/utils.cjs CHANGED
@@ -2,9 +2,28 @@
2
2
  const { existsSync, realpathSync } = require('fs');
3
3
  const { dirname, join } = require('path');
4
4
  const has = require('lodash.has');
5
- const arrify = require('arrify');
6
5
  const readPkgUp = require('read-pkg-up');
7
6
 
7
+ function arrify(value) {
8
+ if (value === null || value === undefined) {
9
+ return [];
10
+ }
11
+
12
+ if (Array.isArray(value)) {
13
+ return value;
14
+ }
15
+
16
+ if (typeof value === 'string') {
17
+ return [value];
18
+ }
19
+
20
+ if (typeof value[Symbol.iterator] === 'function') {
21
+ return [...value];
22
+ }
23
+
24
+ return [value];
25
+ }
26
+
8
27
  const { packageJson: package_, path: packagePath } = readPkgUp.sync({
9
28
  cwd: realpathSync(process.cwd()),
10
29
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anolilab/eslint-config",
3
- "version": "2.1.7",
3
+ "version": "3.0.1",
4
4
  "description": "ESLint shareable config for the Anolilab JavaScript style guide.",
5
5
  "keywords": [
6
6
  "css",
@@ -24,11 +24,6 @@
24
24
  "url": "https://github.com/anolilab/javascript-style-guide.git",
25
25
  "directory": "packages/eslint-config"
26
26
  },
27
- "license": "MIT",
28
- "author": {
29
- "name": "Daniel Bannert",
30
- "email": "d.bannert@anolilab.de"
31
- },
32
27
  "funding": [
33
28
  {
34
29
  "type": "github",
@@ -39,6 +34,11 @@
39
34
  "url": "https://anolilab.com/support"
40
35
  }
41
36
  ],
37
+ "license": "MIT",
38
+ "author": {
39
+ "name": "Daniel Bannert",
40
+ "email": "d.bannert@anolilab.de"
41
+ },
42
42
  "type": "module",
43
43
  "main": "index.cjs",
44
44
  "files": [
@@ -54,22 +54,21 @@
54
54
  "postinstall": "node lib/postinstall.cjs"
55
55
  },
56
56
  "dependencies": {
57
- "@rushstack/eslint-plugin-security": "^0.2.0",
58
- "arrify": "2.0.1",
59
- "confusing-browser-globals": "^1.0.10",
57
+ "@rushstack/eslint-plugin-security": "^0.2.4",
58
+ "confusing-browser-globals": "^1.0.11",
60
59
  "eslint-import-resolver-node": "^0.3.6",
61
- "eslint-plugin-compat": "^3.12.0",
60
+ "eslint-plugin-compat": "^3.13.0",
62
61
  "eslint-plugin-eslint-comments": "^3.2.0",
63
- "eslint-plugin-import": "^2.24.0",
64
- "eslint-plugin-markdown": "^2.2.0",
62
+ "eslint-plugin-import": "^2.25.4",
63
+ "eslint-plugin-markdown": "^2.2.1",
65
64
  "eslint-plugin-no-loops": "^0.3.0",
66
65
  "eslint-plugin-no-secrets": "^0.8.9",
67
66
  "eslint-plugin-optimize-regex": "^1.2.1",
68
- "eslint-plugin-promise": "^5.1.0",
67
+ "eslint-plugin-promise": "^5.1.1",
69
68
  "eslint-plugin-radar": "^0.2.1",
70
69
  "eslint-plugin-simple-import-sort": "^7.0.0",
71
70
  "eslint-plugin-sort-keys-fix": "^1.1.2",
72
- "eslint-plugin-unicorn": "^35.0.0",
71
+ "eslint-plugin-unicorn": "^37.0.1",
73
72
  "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0",
74
73
  "eslint-plugin-you-dont-need-momentjs": "^1.6.0",
75
74
  "lodash.has": "^4.5.2",
@@ -78,58 +77,58 @@
78
77
  "semver": "^7.3.5"
79
78
  },
80
79
  "devDependencies": {
81
- "@testing-library/dom": "8.2.0",
82
- "@typescript-eslint/eslint-plugin": "^4.29.2",
83
- "@typescript-eslint/parser": "4.30.0",
80
+ "@testing-library/dom": "8.11.3",
81
+ "@typescript-eslint/eslint-plugin": "^5.0.0",
82
+ "@typescript-eslint/parser": "5.10.0",
84
83
  "eslint": "7.32.0",
85
- "eslint-find-rules": "3.6.1",
84
+ "eslint-find-rules": "4.1.0",
86
85
  "eslint-plugin-babel": "5.3.1",
87
- "eslint-plugin-cypress": "2.11.3",
88
- "eslint-plugin-jest": "24.4.0",
86
+ "eslint-plugin-cypress": "2.12.1",
87
+ "eslint-plugin-jest": "25.7.0",
89
88
  "eslint-plugin-jest-async": "1.0.3",
90
- "eslint-plugin-jest-dom": "3.9.0",
91
- "eslint-plugin-jest-formatting": "3.0.0",
92
- "eslint-plugin-jsdoc": "36.0.8",
89
+ "eslint-plugin-jest-dom": "4.0.1",
90
+ "eslint-plugin-jest-formatting": "3.1.0",
91
+ "eslint-plugin-jsdoc": "37.6.3",
93
92
  "eslint-plugin-json": "3.1.0",
94
- "eslint-plugin-jsx-a11y": "6.4.1",
95
- "eslint-plugin-mdx": "1.15.0",
93
+ "eslint-plugin-jsx-a11y": "6.5.1",
94
+ "eslint-plugin-mdx": "1.16.0",
96
95
  "eslint-plugin-node": "11.1.0",
97
96
  "eslint-plugin-prefer-object-spread": "1.2.1",
98
- "eslint-plugin-react": "7.25.1",
99
- "eslint-plugin-react-hooks": "4.2.0",
100
- "eslint-plugin-react-redux": "3.3.2",
101
- "eslint-plugin-testing-library": "4.12.0",
102
- "eslint-plugin-typescript-sort-keys": "1.8.0",
103
- "jest": "27.1.0",
97
+ "eslint-plugin-react": "7.28.0",
98
+ "eslint-plugin-react-hooks": "4.3.0",
99
+ "eslint-plugin-react-redux": "3.3.4",
100
+ "eslint-plugin-testing-library": "5.0.4",
101
+ "eslint-plugin-typescript-sort-keys": "2.1.0",
102
+ "jest": "27.5.1",
104
103
  "react": "17.0.2",
105
- "typescript": "^4.3.5"
104
+ "typescript": "^4.5.5"
106
105
  },
107
106
  "peerDependencies": {
108
107
  "eslint": "^7.32.0"
109
108
  },
110
109
  "optionalDependencies": {
111
- "@typescript-eslint/eslint-plugin": "^4.29.2",
112
- "@typescript-eslint/parser": "^4.29.2",
110
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
111
+ "@typescript-eslint/parser": "^5.2.0",
113
112
  "eslint-plugin-babel": "^5.3.1",
114
- "eslint-plugin-cypress": "^2.11.3",
115
- "eslint-plugin-jest": "^24.4.0",
113
+ "eslint-plugin-cypress": "^2.12.1",
114
+ "eslint-plugin-jest": "^26.1.0",
116
115
  "eslint-plugin-jest-async": "^1.0.3",
117
- "eslint-plugin-jest-dom": "^3.9.0",
118
- "eslint-plugin-jest-formatting": "^3.0.0",
119
- "eslint-plugin-jsdoc": "^36.0.7",
116
+ "eslint-plugin-jest-dom": "^4.0.1",
117
+ "eslint-plugin-jest-formatting": "^3.1.0",
118
+ "eslint-plugin-jsdoc": "^37.9.1",
120
119
  "eslint-plugin-json": "^3.1.0",
121
- "eslint-plugin-jsx-a11y": "^6.4.1",
122
- "eslint-plugin-mdx": "^1.14.1",
120
+ "eslint-plugin-jsx-a11y": "^6.5.1",
121
+ "eslint-plugin-mdx": "^1.16.0",
123
122
  "eslint-plugin-node": "^11.1.0",
124
123
  "eslint-plugin-prefer-object-spread": "^1.2.1",
125
- "eslint-plugin-react": "^7.24.0",
126
- "eslint-plugin-react-hooks": "^4.2.0",
127
- "eslint-plugin-react-redux": "^3.3.2",
128
- "eslint-plugin-testing-library": "^4.11.0",
129
- "eslint-plugin-typescript-sort-keys": "^1.8.0"
124
+ "eslint-plugin-react": "^7.28.0",
125
+ "eslint-plugin-react-hooks": "^4.3.0",
126
+ "eslint-plugin-react-redux": "^4.0.0",
127
+ "eslint-plugin-testing-library": "^5.0.5",
128
+ "eslint-plugin-typescript-sort-keys": "^2.1.0"
130
129
  },
131
130
  "engines": {
132
- "node": ">=12"
131
+ "node": ">=16"
133
132
  },
134
133
  "publishConfig": {
135
134
  "access": "public"
@@ -1,36 +1,36 @@
1
- const { rules: baseBestPracticesRules } = require('../best-practices.cjs');
2
- const { rules: errorsRules } = require('../errorsRules.cjs');
3
- const { rules: styleRules } = require('../styleRules.cjs');
1
+ const { rules: baseBestPracticesRules } = require("../best-practices.cjs");
2
+ const { rules: errorsRules } = require("../errorsRules.cjs");
3
+ const { rules: styleRules } = require("../styleRules.cjs");
4
4
 
5
5
  module.exports = {
6
- plugins: ['babel'],
6
+ plugins: ["babel"],
7
7
  rules: {
8
- camelcase: 'off',
9
- 'babel/camelcase': [
8
+ camelcase: "off",
9
+ "babel/camelcase": [
10
10
  // Deep clone to avoid object mutation wierdness
11
11
  styleRules.camelcase[0],
12
12
  { ...styleRules.camelcase[1] },
13
13
  ],
14
14
 
15
- 'new-cap': 'off',
16
- 'babel/new-cap': styleRules['new-cap'],
15
+ "new-cap": "off",
16
+ "babel/new-cap": styleRules["new-cap"],
17
17
 
18
- 'no-invalid-this': 'off',
19
- 'babel/no-invalid-this': baseBestPracticesRules['no-invalid-this'],
18
+ "no-invalid-this": "off",
19
+ "babel/no-invalid-this": baseBestPracticesRules["no-invalid-this"],
20
20
 
21
- 'object-curly-spacing': 'off',
22
- 'babel/object-curly-spacing': styleRules['object-curly-spacing'],
21
+ "object-curly-spacing": "off",
22
+ "babel/object-curly-spacing": styleRules["object-curly-spacing"],
23
23
 
24
- quotes: 'off',
25
- 'babel/quotes': styleRules.quotes,
24
+ quotes: "off",
25
+ "babel/quotes": styleRules.quotes,
26
26
 
27
- semi: 'off',
28
- 'babel/semi': styleRules.semi,
27
+ semi: "off",
28
+ "babel/semi": styleRules.semi,
29
29
 
30
- 'no-unused-expressions': 'off',
31
- 'babel/no-unused-expressions': baseBestPracticesRules['no-unused-expressions'],
30
+ "no-unused-expressions": "off",
31
+ "babel/no-unused-expressions": baseBestPracticesRules["no-unused-expressions"],
32
32
 
33
- 'valid-typeof': 'off',
34
- 'babel/valid-typeof': errorsRules['valid-typeof'],
35
- }
36
- }
33
+ "valid-typeof": "off",
34
+ "babel/valid-typeof": errorsRules["valid-typeof"],
35
+ },
36
+ };
@@ -1,7 +1,7 @@
1
1
  // @see https://github.com/yannickcr/eslint-plugin-react
2
- const assign = require('object.assign');
3
- const { hasAnyDep } = require('../../lib/utils.cjs');
4
- const { rules: baseStyleRules } = require('../style.cjs');
2
+ const assign = require("object.assign");
3
+ const { hasAnyDep } = require("../../lib/utils.cjs");
4
+ const { rules: baseStyleRules } = require("../style.cjs");
5
5
 
6
6
  const dangleRules = baseStyleRules["no-underscore-dangle"];
7
7
 
@@ -387,7 +387,10 @@ module.exports = {
387
387
 
388
388
  // only .jsx files may have JSX
389
389
  // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
390
- "react/jsx-filename-extension": ["error", { extensions: [".jsx"].concat(hasAnyDep("typescript") ? [".tsx"] : []) }],
390
+ "react/jsx-filename-extension": [
391
+ "error",
392
+ { extensions: [".jsx"].concat(hasAnyDep("typescript") ? [".tsx"] : []) },
393
+ ],
391
394
 
392
395
  // prevent accidental JS comments from being injected into JSX as text
393
396
  // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
@@ -5,6 +5,6 @@ module.exports = {
5
5
  "simple-import-sort/exports": "off",
6
6
  "import/first": "error",
7
7
  "import/newline-after-import": "error",
8
- "import/no-duplicates": "error"
8
+ "import/no-duplicates": "error",
9
9
  },
10
10
  };
@@ -1,5 +1,5 @@
1
- const isModuleAvailable = require('../../lib/is-module-available.cjs');
2
- const { consoleLog } = require('../../lib/loggers.cjs');
1
+ const isModuleAvailable = require("../../lib/is-module-available.cjs");
2
+ const { consoleLog } = require("../../lib/loggers.cjs");
3
3
 
4
4
  let ruleset;
5
5
 
@@ -1,11 +1,18 @@
1
- const semver = require('semver');
1
+ const semver = require("semver");
2
2
 
3
3
  module.exports = {
4
- plugins: [
5
- "unicorn"
6
- ],
4
+ plugins: ["unicorn"],
7
5
  extends: ["plugin:unicorn/recommended"],
8
6
  rules: {
9
- "unicorn/prefer-node-protocol": semver.gte(process.version, 'v16.0.0') ? "error" : "off",
7
+ "unicorn/prefer-node-protocol": semver.gte(process.version, "v16.0.0") ? "error" : "off",
8
+ "unicorn/template-indent": [
9
+ "warn",
10
+ {
11
+ tags: ["outdent", "dedent", "gql", "sql", "html", "styled"],
12
+ functions: ["dedent", "stripIndent"],
13
+ selectors: [],
14
+ comments: ["HTML", "indent"],
15
+ },
16
+ ],
10
17
  },
11
18
  };
@@ -1,4 +1,4 @@
1
- const confusingBrowserGlobals = require('confusing-browser-globals');
1
+ const confusingBrowserGlobals = require("confusing-browser-globals");
2
2
 
3
3
  module.exports = {
4
4
  rules: {