eslint-config-octaviaflow 1.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/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # eslint-config-octaviaflow
2
+
3
+ > ESLint configuration for octaviaflow
4
+
5
+ ## Getting started
6
+
7
+ To install `eslint-config-octaviaflow` in your project, you will need to run the
8
+ following command using [npm](https://www.npmjs.com/):
9
+
10
+ ```bash
11
+ npm install -S eslint-config-octaviaflow
12
+ ```
13
+
14
+ If you prefer [Yarn](https://yarnpkg.com/en/), use the following command
15
+ instead:
16
+
17
+ ```bash
18
+ yarn add eslint-config-octaviaflow
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ You can use `eslint-config-octaviaflow` in your project by extending it in your
24
+ `eslint` configuration. For example, if we had an `.eslintrc` file:
25
+
26
+ ```json
27
+ {
28
+ "extends": ["octaviaflow"]
29
+ }
30
+ ```
31
+
32
+ The default configuration available under `eslint-config-octaviaflow` includes all
33
+ ESLint configuration and plugins, including plugins for React.js development. If
34
+ you'd like to not include these rules in your setup, you can also include a
35
+ `base` or `vanilla` oriented configuration by doing the following:
36
+
37
+ ```json
38
+ {
39
+ "extends": ["eslint-config-octaviaflow/base"]
40
+ }
41
+ ```
42
+
43
+ ## 📝 License
44
+
45
+ Licensed under the [Apache 2.0 License](/LICENSE).
package/base.js ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ parser: '@babel/eslint-parser',
12
+ parserOptions: {
13
+ babelOptions: {
14
+ presets: ['babel-preset-octaviaflow'],
15
+ },
16
+ requireConfigFile: false,
17
+ },
18
+ extends: [
19
+ 'eslint:recommended',
20
+ require.resolve('./rules/best-practices'),
21
+ require.resolve('./plugins/jsdoc'),
22
+ ],
23
+ rules: {
24
+ // Handle cases where we are destructuring but may not be using the initial
25
+ // variables
26
+ 'no-unused-vars': [
27
+ 'error',
28
+ {
29
+ args: 'after-used',
30
+ argsIgnorePattern: '^_',
31
+ varsIgnorePattern: '^_',
32
+ },
33
+ ],
34
+ },
35
+ env: {
36
+ node: true,
37
+ browser: true,
38
+ es6: true,
39
+ jest: true,
40
+ jasmine: true,
41
+ },
42
+ globals: {
43
+ __DEV__: true,
44
+ },
45
+ };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "eslint-config-octaviaflow",
3
+ "description": "ESLint configuration for octaviaflow",
4
+ "version": "1.0.0",
5
+ "license": "Apache-2.0",
6
+ "main": "index.js",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/OctaviaFlow/OctaviaFlow-Design-System.git",
10
+ "directory": "config/eslint-config-octaviaflow"
11
+ },
12
+ "bugs": "https://github.com/OctaviaFlow/OctaviaFlow-Design-System/issues",
13
+ "files": [
14
+ "plugins",
15
+ "rules",
16
+ "base.js",
17
+ "index.js",
18
+ "react.js",
19
+ "vanilla.js"
20
+ ],
21
+ "keywords": [
22
+ "octaviaflow",
23
+ "octaviaflow",
24
+ "octaviaflow-design-system",
25
+ "components",
26
+ "react"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "peerDependencies": {
32
+ "eslint": "^9.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@babel/eslint-parser": "^7.28.5",
36
+ "@typescript-eslint/eslint-plugin": "^8.46.4",
37
+ "@typescript-eslint/parser": "^8.46.4",
38
+ "eslint-config-airbnb": "^19.0.4",
39
+ "eslint-config-airbnb-base": "^15.0.0",
40
+ "eslint-config-prettier": "^10.1.8",
41
+ "eslint-plugin-import": "^2.32.0",
42
+ "eslint-plugin-jest": "^29.1.0",
43
+ "eslint-plugin-jest-dom": "^5.5.0",
44
+ "eslint-plugin-jsdoc": "^61.1.12",
45
+ "eslint-plugin-jsx-a11y": "^6.10.2",
46
+ "eslint-plugin-prettier": "^5.5.4",
47
+ "eslint-plugin-react": "^7.37.5",
48
+ "eslint-plugin-react-hooks": "^7.0.1",
49
+ "eslint-plugin-ssr-friendly": "^1.3.0",
50
+ "eslint-plugin-storybook": "^10.0.6",
51
+ "eslint-plugin-testing-library": "^7.13.3",
52
+ "eslint-restricted-globals": "^0.2.0"
53
+ },
54
+ "devDependencies": {
55
+ "babel-preset-octaviaflow": "^1.0.0",
56
+ "prettier": "^3.3.3"
57
+ }
58
+ }
@@ -0,0 +1,34 @@
1
+ const prefixes = [
2
+ '@avt-default-state',
3
+ '@avt-advanced-states',
4
+ '@avt-keyboard-nav',
5
+ ];
6
+ const prefixesList = prefixes.join(' | \n');
7
+
8
+ module.exports = {
9
+ plugins: ['eslint-plugin-playwright'],
10
+ overrides: [
11
+ {
12
+ extends: ['plugin:playwright/recommended'],
13
+ files: ['*-test.avt.e2e.js'],
14
+ rules: {
15
+ 'playwright/valid-title': [
16
+ 'error',
17
+ {
18
+ mustMatch: {
19
+ describe: [
20
+ /^(\s*@avt(\s+\S+)*\s*)$/.source,
21
+ `Describe titles should start with "@avt" prefix`,
22
+ ],
23
+ test: [
24
+ /^(\s*(@avt-default-state||@avt-advanced-states||@avt-keyboard-nav)(\s+\S+)*\s*)$/
25
+ .source,
26
+ `Test titles should start with one of the following prefixes: ${prefixesList}`,
27
+ ],
28
+ },
29
+ },
30
+ ],
31
+ },
32
+ },
33
+ ],
34
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ plugins: ['ssr-friendly'],
12
+ ignorePatterns: ['*.stories.js', '*-test.js'],
13
+ overrides: [
14
+ {
15
+ extends: ['plugin:ssr-friendly/recommended'],
16
+ files: ['*.js', '*.ts', '*.tsx'],
17
+ },
18
+ ],
19
+ };
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ plugins: ['eslint-plugin-jest', 'jest-dom'],
12
+ overrides: [
13
+ {
14
+ extends: ['plugin:jest-dom/recommended'],
15
+ files: ['*-test.js', '*.test.js', '*-spec.js', '*.spec.js'],
16
+ env: {
17
+ 'jest/globals': true,
18
+ },
19
+ rules: {
20
+ // Have control over test and it usages
21
+ 'jest/consistent-test-it': 'off',
22
+
23
+ // Have control over test and it usages
24
+ 'jest/expect-expect': [
25
+ 'error',
26
+ {
27
+ assertFunctionNames: ['expect', 'assert*'],
28
+ },
29
+ ],
30
+
31
+ // Enforce lowercase test names
32
+ 'jest/prefer-lowercase-title': 'off',
33
+
34
+ // Disallow alias methods
35
+ 'jest/no-alias-methods': 'error',
36
+
37
+ // Disallow commented out tests
38
+ 'jest/no-commented-out-tests': 'error',
39
+
40
+ // Prevent calling expect conditionally
41
+ 'jest/no-conditional-expect': 'error',
42
+
43
+ // Disallow use of deprecated functions
44
+ 'jest/no-deprecated-functions': 'error',
45
+
46
+ // Disallow disabled tests
47
+ 'jest/no-disabled-tests': 'off',
48
+
49
+ // Avoid using a callback in asynchronous tests and hooks
50
+ 'jest/no-done-callback': 'error',
51
+
52
+ // Disallow duplicate setup and teardown hooks
53
+ 'jest/no-duplicate-hooks': 'error',
54
+
55
+ // Disallow using exports in files containing tests
56
+ 'jest/no-export': 'error',
57
+
58
+ // Disallow focused tests
59
+ 'jest/no-focused-tests': 'error',
60
+
61
+ // Disallow setup and teardown hooks
62
+ 'jest/no-hooks': 'off',
63
+
64
+ // Disallow identical titles
65
+ 'jest/no-identical-title': 'error',
66
+
67
+ // Disallow conditional logic
68
+ 'jest/no-if': 'error',
69
+
70
+ // Disallow string interpolation inside snapshots
71
+ 'jest/no-interpolation-in-snapshots': 'error',
72
+
73
+ // Disallow Jasmine globals
74
+ 'jest/no-jasmine-globals': 'error',
75
+
76
+ // Disallow large snapshots
77
+ 'jest/no-large-snapshots': 'off',
78
+
79
+ // Disallow manually importing from __mocks__
80
+ 'jest/no-mocks-import': 'error',
81
+
82
+ // Disallow specific matchers & modifiers
83
+ 'jest/no-restricted-matchers': 'off',
84
+
85
+ // Disallow using expect outside of it or test blocks
86
+ 'jest/no-standalone-expect': 'error',
87
+
88
+ // Use .only and .skip over f and x
89
+ 'jest/no-test-prefixes': 'off',
90
+
91
+ // Disallow explicitly returning from tests
92
+ 'jest/no-test-return-statement': 'error',
93
+
94
+ // Suggest using toBeCalledWith() or toHaveBeenCalledWith()
95
+ 'jest/prefer-called-with': 'off',
96
+
97
+ // Suggest using expect.assertions() OR expect.hasAssertions()
98
+ 'jest/prefer-expect-assertions': 'off',
99
+
100
+ // Suggest having hooks before any test cases
101
+ 'jest/prefer-hooks-on-top': 'error',
102
+
103
+ // Suggest using jest.spyOn()
104
+ 'jest/prefer-spy-on': 'off',
105
+
106
+ // Suggest using toStrictEqual()
107
+ 'jest/prefer-strict-equal': 'off',
108
+
109
+ // Suggest using toBe() for primitive literals
110
+ 'jest/prefer-to-be': 'off',
111
+
112
+ // Suggest using toContain()
113
+ 'jest/prefer-to-contain': 'off',
114
+
115
+ // Suggest using toHaveLength()
116
+ 'jest/prefer-to-have-length': 'off',
117
+
118
+ // Suggest using test.todo
119
+ 'jest/prefer-todo': 'off',
120
+
121
+ // Require a message for toThrow()
122
+ 'jest/require-to-throw-message': 'off',
123
+
124
+ // Require test cases and hooks to be inside a describe block
125
+ 'jest/require-top-level-describe': 'off',
126
+
127
+ // Enforce valid describe() callback
128
+ 'jest/valid-describe-callback': 'error',
129
+
130
+ // Enforce valid expect() usage
131
+ 'jest/valid-expect': 'error',
132
+
133
+ // Enforce having return statement when testing with promises
134
+ 'jest/valid-expect-in-promise': 'error',
135
+
136
+ // Enforce valid titles
137
+ 'jest/valid-title': 'error',
138
+ },
139
+ },
140
+ ],
141
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ plugins: ['jsdoc'],
12
+ settings: {
13
+ jsdoc: {
14
+ tagNamePreference: {
15
+ augments: 'extends',
16
+ },
17
+ },
18
+ },
19
+ rules: {
20
+ 'jsdoc/check-param-names': 2,
21
+ 'jsdoc/check-tag-names': [
22
+ 'error',
23
+ {
24
+ definedTags: ['jest-environment'],
25
+ },
26
+ ],
27
+ 'jsdoc/check-types': 2,
28
+ },
29
+ };
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ extends: [
12
+ 'plugin:react/recommended',
13
+ 'plugin:react-hooks/recommended',
14
+ 'plugin:jsx-a11y/recommended',
15
+ ],
16
+ plugins: ['react', 'react-hooks'],
17
+ settings: {
18
+ react: {
19
+ version: 'detect',
20
+ },
21
+ },
22
+ parserOptions: {
23
+ ecmaFeatures: {
24
+ jsx: true,
25
+ },
26
+ },
27
+ rules: {
28
+ // react
29
+ 'react/button-has-type': 'error',
30
+ 'react/jsx-uses-vars': 1,
31
+ 'react/jsx-uses-react': 1,
32
+ 'react/no-find-dom-node': 1,
33
+ 'react/jsx-no-useless-fragment': 2,
34
+ 'react/no-typos': 2,
35
+ 'react/sort-prop-types': 2,
36
+ 'react/forbid-component-props': [
37
+ 2,
38
+ { forbid: [{ propName: 'style', message: 'Avoid using style prop' }] },
39
+ ],
40
+ 'react/forbid-dom-props': [
41
+ 2,
42
+ { forbid: [{ propName: 'style', message: 'Avoid using style prop' }] },
43
+ ],
44
+
45
+ // react-hooks
46
+ 'react-hooks/rules-of-hooks': 2,
47
+ 'react-hooks/exhaustive-deps': [
48
+ 2,
49
+ {
50
+ additionalHooks: 'useIsomorphicEffect',
51
+ },
52
+ ],
53
+ },
54
+ overrides: [
55
+ {
56
+ files: ['*.ts', '*.tsx'],
57
+ plugins: ['@typescript-eslint'],
58
+ extends: ['plugin:@typescript-eslint/recommended'],
59
+ parser: '@typescript-eslint/parser',
60
+ rules: {
61
+ 'no-unused-vars': 'off', // Disabled in favor of @typescript-eslint/no-unused-vars
62
+ '@typescript-eslint/no-unused-vars': [
63
+ 'error',
64
+ {
65
+ args: 'after-used',
66
+ argsIgnorePattern: '^_',
67
+ varsIgnorePattern: '^_',
68
+ },
69
+ ],
70
+ '@typescript-eslint/no-empty-function': 'off', // Disabled to support default empty functions used in PropTypes
71
+ '@typescript-eslint/no-explicit-any': 'off', // TODO: Enable once stricter typings of internal utilities are supported
72
+ '@typescript-eslint/ban-ts-comment': 'off', // Disabled to allow some instances where we won't be able to fix type errors
73
+ },
74
+ },
75
+ // Sometimes we'll want to define a quick component in a story to use as a
76
+ // wrapper for a component we're documenting. For example:
77
+ //
78
+ // function DemoComponent({ children }) {
79
+ // return <p>{children}</p>;
80
+ // }
81
+ //
82
+ // In these cases, we don't need to handle prop type validation like we
83
+ // would for code we ship to users.
84
+ {
85
+ files: ['*-story.js', '*.stories.js'],
86
+ rules: {
87
+ 'react/display-name': 0,
88
+ 'react/prop-types': 0,
89
+ 'react/forbid-component-props': 0,
90
+ 'react/forbid-dom-props': 0,
91
+ },
92
+ },
93
+ // style prop is fine to be used in internal unit testing
94
+ {
95
+ files: ['*.e2e.js'],
96
+ rules: {
97
+ 'react/forbid-component-props': 0,
98
+ 'react/forbid-dom-props': 0,
99
+ },
100
+ },
101
+
102
+ // When writing fixtures, we tend to focus on the specific component and
103
+ // don't require React in scope as we never end up executing the code. The
104
+ // fixtures are often used for asserting transformations on the file
105
+ {
106
+ files: ['**/fixtures/**/*.js'],
107
+ rules: {
108
+ 'react/react-in-jsx-scope': 0,
109
+ },
110
+ },
111
+
112
+ {
113
+ files: ['*-test.js'],
114
+ rules: {
115
+ // We often write inline functions for certain types of props, typically
116
+ // `render*` props. For example, `renderIcon={() => <div>test</div>}`
117
+ 'react/display-name': 0,
118
+
119
+ // While writing tests, we often write helper components that are meant
120
+ // to emulate a specific situation or behavior. These do not require prop
121
+ // types as they are not shipped to end-users and are not valuable for
122
+ // test authors.
123
+ 'react/prop-types': 0,
124
+ },
125
+ },
126
+ ],
127
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ /**
11
+ * ESLint configuration for eslint-plugin-storybook
12
+ *
13
+ * @see https://github.com/storybookjs/eslint-plugin-storybook
14
+ */
15
+ module.exports = {
16
+ plugins: ['storybook'],
17
+ overrides: [
18
+ {
19
+ files: ['*.stories.js', '*-story.js'],
20
+ extends: ['plugin:storybook/recommended'],
21
+ rules: {
22
+ // Interactions should be awaited
23
+ 'storybook/await-interactions': 'error',
24
+
25
+ // Pass a context when invoking play function of another story
26
+ 'storybook/context-in-play-function': 'error',
27
+
28
+ // The component property should be set
29
+ 'storybook/csf-component': 'error',
30
+
31
+ // Story files should have a default export
32
+ 'storybook/default-exports': 'error',
33
+
34
+ // Deprecated hierachy separator in title property
35
+ 'storybook/hierarchy-separator': 'error',
36
+
37
+ 'storybook/no-redundant-story-name': 'error',
38
+
39
+ // storiesOf is deprecated and should not be used
40
+ 'storybook/no-stories-of': 'error',
41
+
42
+ // Do not define a title in meta
43
+ 'storybook/no-title-property-in-meta': 'off',
44
+
45
+ // Stories should use PascalCase
46
+ 'storybook/prefer-pascal-case': 'error',
47
+
48
+ // A story file must contain at least one story export
49
+ 'storybook/story-exports': 'error',
50
+
51
+ // Use expect from @storybook/jest
52
+ 'storybook/use-storybook-expect': 'error',
53
+
54
+ // Do not use testing-library directly on stories
55
+ 'storybook/use-storybook-testing-library': 'error',
56
+ },
57
+ },
58
+ ],
59
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ plugins: ['testing-library'],
12
+ overrides: [
13
+ {
14
+ extends: ['plugin:testing-library/react'],
15
+ files: ['packages/react/**/*-test.js'],
16
+ rules: {
17
+ 'testing-library/no-node-access': [
18
+ 'error',
19
+ { allowContainerFirstChild: true },
20
+ ],
21
+ },
22
+ },
23
+ ],
24
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ export default {
11
+ rules: {
12
+ // @see https://eslint.org/docs/rules/curly
13
+ curly: 'error',
14
+ },
15
+ };
package/vanilla.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright OctaviaFlow
3
+ * Author: Vishal Kumar
4
+ * Created: 11/November/2025
5
+ *
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ module.exports = {
11
+ parser: '@babel/eslint-parser',
12
+ parserOptions: {
13
+ ecmaVersion: 6,
14
+ sourceType: 'script',
15
+ babelOptions: {
16
+ presets: ['babel-preset-octaviaflow'],
17
+ },
18
+ requireConfigFile: false,
19
+ },
20
+ env: {
21
+ browser: true,
22
+ node: true,
23
+ es6: true,
24
+ },
25
+ extends: ['airbnb-base', 'prettier'],
26
+ plugins: ['prettier'],
27
+ rules: {
28
+ 'prettier/prettier': [
29
+ 'error',
30
+ {
31
+ singleQuote: true,
32
+ trailingComma: 'es5',
33
+ },
34
+ ],
35
+ 'max-len': [2, 130, 4],
36
+ 'no-param-reassign': [
37
+ 2,
38
+ {
39
+ props: false,
40
+ },
41
+ ],
42
+ 'no-plusplus': 0,
43
+ 'no-underscore-dangle': 0,
44
+ 'prefer-rest-params': 0,
45
+ 'comma-dangle': [
46
+ 2,
47
+ {
48
+ arrays: 'always-multiline',
49
+ objects: 'always-multiline',
50
+ imports: 'always-multiline',
51
+ exports: 'always-multiline',
52
+ functions: 'never',
53
+ },
54
+ ],
55
+ 'import/no-extraneous-dependencies': [2, { devDependencies: true }],
56
+ 'import/order': 0,
57
+ },
58
+ };