@akinon/eslint-plugin-projectzero 1.14.0 → 1.14.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/.prettierrc CHANGED
@@ -1,13 +1,13 @@
1
- {
2
- "bracketSameLine": false,
3
- "tabWidth": 2,
4
- "singleQuote": true,
5
- "jsxSingleQuote": false,
6
- "bracketSpacing": true,
7
- "semi": true,
8
- "useTabs": false,
9
- "arrowParens": "always",
10
- "endOfLine": "lf",
11
- "proseWrap": "never",
12
- "trailingComma": "none"
13
- }
1
+ {
2
+ "bracketSameLine": false,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "jsxSingleQuote": false,
6
+ "bracketSpacing": true,
7
+ "semi": true,
8
+ "useTabs": false,
9
+ "arrowParens": "always",
10
+ "endOfLine": "lf",
11
+ "proseWrap": "never",
12
+ "trailingComma": "none"
13
+ }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @akinon/eslint-plugin-projectzero
2
2
 
3
+ ## 1.14.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Change EOL
8
+
3
9
  ## 1.14.0
4
10
 
5
11
  ### Minor Changes
package/configs/core.ts CHANGED
@@ -1,20 +1,20 @@
1
- export default {
2
- rules: {
3
- '@akinon/projectzero/image-import': 'error',
4
- '@akinon/projectzero/client-url': 'error',
5
- '@akinon/projectzero/link-import': 'error',
6
- '@akinon/projectzero/router-import': 'error',
7
- '@akinon/projectzero/skip-trailing-slash-redirect': 'error',
8
- '@akinon/projectzero/check-locale': 'error',
9
- '@akinon/projectzero/meta-data-import': 'error',
10
- '@akinon/projectzero/urls-without-slash': 'error',
11
- 'no-restricted-syntax': [
12
- 'error',
13
- {
14
- selector:
15
- "MemberExpression[property.name='COMMERCE_URL'][object.property.name='env'][object.object.name='process']",
16
- message: "You should use it as 'Settings.commerceUrl'"
17
- }
18
- ]
19
- }
20
- };
1
+ export default {
2
+ rules: {
3
+ '@akinon/projectzero/image-import': 'error',
4
+ '@akinon/projectzero/client-url': 'error',
5
+ '@akinon/projectzero/link-import': 'error',
6
+ '@akinon/projectzero/router-import': 'error',
7
+ '@akinon/projectzero/skip-trailing-slash-redirect': 'error',
8
+ '@akinon/projectzero/check-locale': 'error',
9
+ '@akinon/projectzero/meta-data-import': 'error',
10
+ '@akinon/projectzero/urls-without-slash': 'error',
11
+ 'no-restricted-syntax': [
12
+ 'error',
13
+ {
14
+ selector:
15
+ "MemberExpression[property.name='COMMERCE_URL'][object.property.name='env'][object.object.name='process']",
16
+ message: "You should use it as 'Settings.commerceUrl'"
17
+ }
18
+ ]
19
+ }
20
+ };
package/configs/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import core from './core';
2
- import recommended from './recommended';
3
-
4
- export { core, recommended };
1
+ import core from './core';
2
+ import recommended from './recommended';
3
+
4
+ export { core, recommended };
@@ -1,23 +1,23 @@
1
- export default {
2
- rules: {
3
- '@next/next/no-html-link-for-pages': 'off',
4
- '@next/next/no-server-import-in-page': 'off',
5
- '@typescript-eslint/no-var-requires': 0,
6
- '@typescript-eslint/no-empty-interface': [
7
- 'error',
8
- {
9
- allowSingleExtends: false
10
- }
11
- ],
12
- 'no-console': ['error', { allow: ['error', 'warn'] }],
13
- 'no-empty-function': [
14
- 'error',
15
- { allow: ['arrowFunctions', 'functions', 'methods'] }
16
- ],
17
- 'object-shorthand': [
18
- 'error',
19
- 'always',
20
- { ignoreConstructors: false, avoidQuotes: true }
21
- ]
22
- }
23
- };
1
+ export default {
2
+ rules: {
3
+ '@next/next/no-html-link-for-pages': 'off',
4
+ '@next/next/no-server-import-in-page': 'off',
5
+ '@typescript-eslint/no-var-requires': 0,
6
+ '@typescript-eslint/no-empty-interface': [
7
+ 'error',
8
+ {
9
+ allowSingleExtends: false
10
+ }
11
+ ],
12
+ 'no-console': ['error', { allow: ['error', 'warn'] }],
13
+ 'no-empty-function': [
14
+ 'error',
15
+ { allow: ['arrowFunctions', 'functions', 'methods'] }
16
+ ],
17
+ 'object-shorthand': [
18
+ 'error',
19
+ 'always',
20
+ { ignoreConstructors: false, avoidQuotes: true }
21
+ ]
22
+ }
23
+ };
@@ -1,37 +1,37 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@typescript-eslint/utils");
4
- exports.default = utils_1.ESLintUtils.RuleCreator.withoutDocs({
5
- create(context) {
6
- if (context.getFilename().includes('@akinon/next/hooks/use-router.ts')) {
7
- return {};
8
- }
9
- return {
10
- ImportDeclaration(node) {
11
- if (node.source.value === 'next/router' || node.source.value === 'next/navigation' && node.specifiers.find((s) => s.local.name === 'useRouter')) {
12
- context.report({
13
- messageId: 'routerImport',
14
- node,
15
- fix: (fixer) => {
16
- if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
- return null;
18
- }
19
- return fixer.replaceText(node, node.specifiers
20
- .map((specifier) => `import { ${specifier.local.name} } from '@akinon/next/hooks';`)
21
- .join('\n'));
22
- }
23
- });
24
- }
25
- }
26
- };
27
- },
28
- meta: {
29
- messages: {
30
- routerImport: "Import 'useRouter' hooks from '@akinon/next/hooks'."
31
- },
32
- type: 'problem',
33
- fixable: 'code',
34
- schema: []
35
- },
36
- defaultOptions: []
37
- });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@typescript-eslint/utils");
4
+ exports.default = utils_1.ESLintUtils.RuleCreator.withoutDocs({
5
+ create(context) {
6
+ if (context.getFilename().includes('@akinon/next/hooks/use-router.ts')) {
7
+ return {};
8
+ }
9
+ return {
10
+ ImportDeclaration(node) {
11
+ if (node.source.value === 'next/router' || node.source.value === 'next/navigation' && node.specifiers.find((s) => s.local.name === 'useRouter')) {
12
+ context.report({
13
+ messageId: 'routerImport',
14
+ node,
15
+ fix: (fixer) => {
16
+ if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
+ return null;
18
+ }
19
+ return fixer.replaceText(node, node.specifiers
20
+ .map((specifier) => `import { ${specifier.local.name} } from '@akinon/next/hooks';`)
21
+ .join('\n'));
22
+ }
23
+ });
24
+ }
25
+ }
26
+ };
27
+ },
28
+ meta: {
29
+ messages: {
30
+ routerImport: "Import 'useRouter' hooks from '@akinon/next/hooks'."
31
+ },
32
+ type: 'problem',
33
+ fixable: 'code',
34
+ schema: []
35
+ },
36
+ defaultOptions: []
37
+ });
@@ -1,40 +1,40 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@typescript-eslint/utils");
4
- const URLS = [
5
- '/users/logout/'
6
- ];
7
- exports.default = utils_1.ESLintUtils.RuleCreator.withoutDocs({
8
- create(context) {
9
- if (!context.getFilename().includes('urls.ts')) {
10
- return {};
11
- }
12
- return {
13
- Literal(node) {
14
- var _a;
15
- const value = (_a = node.value) === null || _a === void 0 ? void 0 : _a.toString();
16
- if (!value) {
17
- return;
18
- }
19
- URLS.map((url) => {
20
- if (value.endsWith(url)) {
21
- context.report({
22
- messageId: 'UrlWithoutSlash',
23
- node,
24
- fix: (fixer) => fixer.replaceText(node, `\`${value.slice(0, -1)}\``)
25
- });
26
- }
27
- });
28
- }
29
- };
30
- },
31
- meta: {
32
- messages: {
33
- UrlWithoutSlash: 'It must not end with a forward slash (/).'
34
- },
35
- type: 'problem',
36
- fixable: 'code',
37
- schema: []
38
- },
39
- defaultOptions: []
40
- });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@typescript-eslint/utils");
4
+ const URLS = [
5
+ '/users/logout/'
6
+ ];
7
+ exports.default = utils_1.ESLintUtils.RuleCreator.withoutDocs({
8
+ create(context) {
9
+ if (!context.getFilename().includes('urls.ts')) {
10
+ return {};
11
+ }
12
+ return {
13
+ Literal(node) {
14
+ var _a;
15
+ const value = (_a = node.value) === null || _a === void 0 ? void 0 : _a.toString();
16
+ if (!value) {
17
+ return;
18
+ }
19
+ URLS.map((url) => {
20
+ if (value.endsWith(url)) {
21
+ context.report({
22
+ messageId: 'UrlWithoutSlash',
23
+ node,
24
+ fix: (fixer) => fixer.replaceText(node, `\`${value.slice(0, -1)}\``)
25
+ });
26
+ }
27
+ });
28
+ }
29
+ };
30
+ },
31
+ meta: {
32
+ messages: {
33
+ UrlWithoutSlash: 'It must not end with a forward slash (/).'
34
+ },
35
+ type: 'problem',
36
+ fixable: 'code',
37
+ schema: []
38
+ },
39
+ defaultOptions: []
40
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/eslint-plugin-projectzero",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "private": false,
5
5
  "description": "ESLint plugin for Project Zero Next",
6
6
  "main": "dist/index.js",
@@ -1,78 +1,78 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
- import * as path from 'path';
3
- import * as fs from 'fs';
4
-
5
- const MONOREPO_LOCALES_DIR = path.resolve(
6
- __dirname,
7
- '../../../../apps/projectzeropwa/public/locales/en'
8
- );
9
-
10
- const STANDARD_REPO_LOCALES_DIR = path.join(process.cwd(), 'public/locales/en');
11
-
12
- const LOCALES_DIR = fs.existsSync(MONOREPO_LOCALES_DIR)
13
- ? MONOREPO_LOCALES_DIR
14
- : STANDARD_REPO_LOCALES_DIR;
15
-
16
- const getAllKeysFromObject = (obj: any, prefix = ''): string[] => {
17
- return Object.keys(obj).reduce((result, key) => {
18
- if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
19
- return result.concat(getAllKeysFromObject(obj[key], `${prefix}${key}.`));
20
- }
21
- return result.concat(`${prefix}${key}`);
22
- }, [] as string[]);
23
- };
24
-
25
- export default ESLintUtils.RuleCreator.withoutDocs({
26
- create(context: any) {
27
- return {
28
- CallExpression(node: any) {
29
- if (node.callee.type !== 'Identifier' || node.callee.name !== 't') {
30
- return;
31
- }
32
-
33
- const [firstArg] = node.arguments;
34
-
35
- if (
36
- firstArg &&
37
- firstArg.type === 'Literal' &&
38
- typeof firstArg.value === 'string'
39
- ) {
40
- const key = firstArg.value;
41
-
42
- const filename = `${key.split('.')[0]}.json`;
43
- const filepath = path.join(LOCALES_DIR, filename);
44
-
45
- if (fs.existsSync(filepath)) {
46
- const jsonContent = JSON.parse(fs.readFileSync(filepath, 'utf-8'));
47
- const allKeys = getAllKeysFromObject(
48
- jsonContent,
49
- filename.replace('.json', '.')
50
- );
51
-
52
- if (!allKeys.includes(key)) {
53
- context.report({
54
- node: firstArg,
55
- messageId: 'missingLocalizationKey'
56
- });
57
- }
58
- } else {
59
- context.report({
60
- node: firstArg,
61
- messageId: 'missingLocalizationFile'
62
- });
63
- }
64
- }
65
- }
66
- };
67
- },
68
- meta: {
69
- messages: {
70
- missingLocalizationKey:
71
- 'The localization key does not exist in the JSON files.',
72
- missingLocalizationFile: 'The localization file does not exist.'
73
- },
74
- type: 'problem',
75
- schema: []
76
- },
77
- defaultOptions: []
78
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+
5
+ const MONOREPO_LOCALES_DIR = path.resolve(
6
+ __dirname,
7
+ '../../../../apps/projectzeropwa/public/locales/en'
8
+ );
9
+
10
+ const STANDARD_REPO_LOCALES_DIR = path.join(process.cwd(), 'public/locales/en');
11
+
12
+ const LOCALES_DIR = fs.existsSync(MONOREPO_LOCALES_DIR)
13
+ ? MONOREPO_LOCALES_DIR
14
+ : STANDARD_REPO_LOCALES_DIR;
15
+
16
+ const getAllKeysFromObject = (obj: any, prefix = ''): string[] => {
17
+ return Object.keys(obj).reduce((result, key) => {
18
+ if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
19
+ return result.concat(getAllKeysFromObject(obj[key], `${prefix}${key}.`));
20
+ }
21
+ return result.concat(`${prefix}${key}`);
22
+ }, [] as string[]);
23
+ };
24
+
25
+ export default ESLintUtils.RuleCreator.withoutDocs({
26
+ create(context: any) {
27
+ return {
28
+ CallExpression(node: any) {
29
+ if (node.callee.type !== 'Identifier' || node.callee.name !== 't') {
30
+ return;
31
+ }
32
+
33
+ const [firstArg] = node.arguments;
34
+
35
+ if (
36
+ firstArg &&
37
+ firstArg.type === 'Literal' &&
38
+ typeof firstArg.value === 'string'
39
+ ) {
40
+ const key = firstArg.value;
41
+
42
+ const filename = `${key.split('.')[0]}.json`;
43
+ const filepath = path.join(LOCALES_DIR, filename);
44
+
45
+ if (fs.existsSync(filepath)) {
46
+ const jsonContent = JSON.parse(fs.readFileSync(filepath, 'utf-8'));
47
+ const allKeys = getAllKeysFromObject(
48
+ jsonContent,
49
+ filename.replace('.json', '.')
50
+ );
51
+
52
+ if (!allKeys.includes(key)) {
53
+ context.report({
54
+ node: firstArg,
55
+ messageId: 'missingLocalizationKey'
56
+ });
57
+ }
58
+ } else {
59
+ context.report({
60
+ node: firstArg,
61
+ messageId: 'missingLocalizationFile'
62
+ });
63
+ }
64
+ }
65
+ }
66
+ };
67
+ },
68
+ meta: {
69
+ messages: {
70
+ missingLocalizationKey:
71
+ 'The localization key does not exist in the JSON files.',
72
+ missingLocalizationFile: 'The localization file does not exist.'
73
+ },
74
+ type: 'problem',
75
+ schema: []
76
+ },
77
+ defaultOptions: []
78
+ });
@@ -1,64 +1,64 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
-
3
- const correctOrder = [
4
- 'withOauthLogin',
5
- 'withLocale',
6
- 'withCurrency',
7
- 'withPrettyUrl',
8
- 'withRedirectionPayment',
9
- 'withThreeDRedirection',
10
- 'withUrlRedirection'
11
- ];
12
-
13
- export default ESLintUtils.RuleCreator.withoutDocs({
14
- create(context: any) {
15
- return {
16
- CallExpression(node: any) {
17
- if (
18
- node.callee.type === 'Identifier' &&
19
- correctOrder.includes(node.callee.name)
20
- ) {
21
- let current = node;
22
- const callSequence = [];
23
-
24
- while (
25
- current.type === 'CallExpression' &&
26
- current.callee.type === 'Identifier'
27
- ) {
28
- if (correctOrder.includes(current.callee.name)) {
29
- callSequence.unshift(current.callee.name);
30
- }
31
- current = current.parent;
32
- }
33
-
34
- let isValidOrder = true;
35
- for (let i = 0; i < callSequence.length; i++) {
36
- if (callSequence[i] !== correctOrder[i]) {
37
- isValidOrder = false;
38
- break;
39
- }
40
- }
41
-
42
- // Report an error if the order is incorrect
43
- if (!isValidOrder) {
44
- context.report({
45
- node,
46
- message: `Incorrect order of middleware functions. Expected order: ${correctOrder.join(
47
- ', '
48
- )}. Found order: ${callSequence.join(', ')}.`
49
- });
50
- }
51
- }
52
- }
53
- };
54
- },
55
- meta: {
56
- type: 'problem',
57
- schema: [],
58
- messages: {
59
- incorrectMiddlewareOrder:
60
- 'Incorrect middleware order. Expected {{expected}}, found {{found}}.'
61
- }
62
- },
63
- defaultOptions: []
64
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+
3
+ const correctOrder = [
4
+ 'withOauthLogin',
5
+ 'withLocale',
6
+ 'withCurrency',
7
+ 'withPrettyUrl',
8
+ 'withRedirectionPayment',
9
+ 'withThreeDRedirection',
10
+ 'withUrlRedirection'
11
+ ];
12
+
13
+ export default ESLintUtils.RuleCreator.withoutDocs({
14
+ create(context: any) {
15
+ return {
16
+ CallExpression(node: any) {
17
+ if (
18
+ node.callee.type === 'Identifier' &&
19
+ correctOrder.includes(node.callee.name)
20
+ ) {
21
+ let current = node;
22
+ const callSequence = [];
23
+
24
+ while (
25
+ current.type === 'CallExpression' &&
26
+ current.callee.type === 'Identifier'
27
+ ) {
28
+ if (correctOrder.includes(current.callee.name)) {
29
+ callSequence.unshift(current.callee.name);
30
+ }
31
+ current = current.parent;
32
+ }
33
+
34
+ let isValidOrder = true;
35
+ for (let i = 0; i < callSequence.length; i++) {
36
+ if (callSequence[i] !== correctOrder[i]) {
37
+ isValidOrder = false;
38
+ break;
39
+ }
40
+ }
41
+
42
+ // Report an error if the order is incorrect
43
+ if (!isValidOrder) {
44
+ context.report({
45
+ node,
46
+ message: `Incorrect order of middleware functions. Expected order: ${correctOrder.join(
47
+ ', '
48
+ )}. Found order: ${callSequence.join(', ')}.`
49
+ });
50
+ }
51
+ }
52
+ }
53
+ };
54
+ },
55
+ meta: {
56
+ type: 'problem',
57
+ schema: [],
58
+ messages: {
59
+ incorrectMiddlewareOrder:
60
+ 'Incorrect middleware order. Expected {{expected}}, found {{found}}.'
61
+ }
62
+ },
63
+ defaultOptions: []
64
+ });
@@ -1,44 +1,44 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
-
3
- export default ESLintUtils.RuleCreator.withoutDocs({
4
- create(context) {
5
- if (!context.getFilename().includes('urls.ts')) {
6
- return {};
7
- }
8
-
9
- return {
10
- Literal(node) {
11
- const value = node.value?.toString();
12
- const isStrLiteral = value?.includes('${');
13
-
14
- if (!value) {
15
- return;
16
- }
17
-
18
- if (value.endsWith('/')) {
19
- context.report({
20
- messageId: 'clientUrl',
21
- node,
22
- fix: (fixer) =>
23
- fixer.replaceText(
24
- node,
25
- `${isStrLiteral ? '`' : `'`}${value.substring(
26
- 0,
27
- value.length - 1
28
- )}${isStrLiteral ? '`' : `'`}`
29
- )
30
- });
31
- }
32
- }
33
- };
34
- },
35
- meta: {
36
- messages: {
37
- clientUrl: 'Client URLs must not end with slash(/).'
38
- },
39
- type: 'problem',
40
- fixable: 'code',
41
- schema: []
42
- },
43
- defaultOptions: []
44
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+
3
+ export default ESLintUtils.RuleCreator.withoutDocs({
4
+ create(context) {
5
+ if (!context.getFilename().includes('urls.ts')) {
6
+ return {};
7
+ }
8
+
9
+ return {
10
+ Literal(node) {
11
+ const value = node.value?.toString();
12
+ const isStrLiteral = value?.includes('${');
13
+
14
+ if (!value) {
15
+ return;
16
+ }
17
+
18
+ if (value.endsWith('/')) {
19
+ context.report({
20
+ messageId: 'clientUrl',
21
+ node,
22
+ fix: (fixer) =>
23
+ fixer.replaceText(
24
+ node,
25
+ `${isStrLiteral ? '`' : `'`}${value.substring(
26
+ 0,
27
+ value.length - 1
28
+ )}${isStrLiteral ? '`' : `'`}`
29
+ )
30
+ });
31
+ }
32
+ }
33
+ };
34
+ },
35
+ meta: {
36
+ messages: {
37
+ clientUrl: 'Client URLs must not end with slash(/).'
38
+ },
39
+ type: 'problem',
40
+ fixable: 'code',
41
+ schema: []
42
+ },
43
+ defaultOptions: []
44
+ });
@@ -1,44 +1,44 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
-
3
- export default ESLintUtils.RuleCreator.withoutDocs({
4
- create(context) {
5
- if (context.getFilename().includes('components/image.tsx')) {
6
- return {};
7
- }
8
-
9
- return {
10
- ImportDeclaration(node) {
11
- if (node.source.value === 'next/image') {
12
- context.report({
13
- messageId: 'imageImport',
14
- node,
15
- fix: (fixer) => {
16
- if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
- return null;
18
- }
19
-
20
- return fixer.replaceText(
21
- node,
22
- node.specifiers
23
- .map(
24
- (specifier) =>
25
- `import { ${specifier.local.name} } from 'components';`
26
- )
27
- .join('\n')
28
- );
29
- }
30
- });
31
- }
32
- }
33
- };
34
- },
35
- meta: {
36
- messages: {
37
- imageImport: "Import 'Image' component from 'components'."
38
- },
39
- type: 'problem',
40
- fixable: 'code',
41
- schema: []
42
- },
43
- defaultOptions: []
44
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+
3
+ export default ESLintUtils.RuleCreator.withoutDocs({
4
+ create(context) {
5
+ if (context.getFilename().includes('components/image.tsx')) {
6
+ return {};
7
+ }
8
+
9
+ return {
10
+ ImportDeclaration(node) {
11
+ if (node.source.value === 'next/image') {
12
+ context.report({
13
+ messageId: 'imageImport',
14
+ node,
15
+ fix: (fixer) => {
16
+ if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
+ return null;
18
+ }
19
+
20
+ return fixer.replaceText(
21
+ node,
22
+ node.specifiers
23
+ .map(
24
+ (specifier) =>
25
+ `import { ${specifier.local.name} } from 'components';`
26
+ )
27
+ .join('\n')
28
+ );
29
+ }
30
+ });
31
+ }
32
+ }
33
+ };
34
+ },
35
+ meta: {
36
+ messages: {
37
+ imageImport: "Import 'Image' component from 'components'."
38
+ },
39
+ type: 'problem',
40
+ fixable: 'code',
41
+ schema: []
42
+ },
43
+ defaultOptions: []
44
+ });
package/rules/index.ts CHANGED
@@ -1,23 +1,23 @@
1
- import clientUrl from './client-url';
2
- import imageImport from './image-import';
3
- import linkImport from './link-import';
4
- import routerImport from './router-import';
5
- import skipTrailingSlashRedirect from './skip-trailing-slash-redirect';
6
- import checkLocale from './check-locale';
7
- import metaDataImport from './meta-data-import';
8
- import checkMiddlewareOrder from './check-middleware-order';
9
- import urlsWithoutSlash from './urls-without-slash';
10
-
11
- const rules = {
12
- 'client-url': clientUrl,
13
- 'image-import': imageImport,
14
- 'link-import': linkImport,
15
- 'router-import': routerImport,
16
- 'skip-trailing-slash-redirect': skipTrailingSlashRedirect,
17
- 'check-locale': checkLocale,
18
- 'meta-data-import': metaDataImport,
19
- 'check-middleware-order': checkMiddlewareOrder,
20
- 'urls-without-slash': urlsWithoutSlash
21
- };
22
-
23
- export { rules };
1
+ import clientUrl from './client-url';
2
+ import imageImport from './image-import';
3
+ import linkImport from './link-import';
4
+ import routerImport from './router-import';
5
+ import skipTrailingSlashRedirect from './skip-trailing-slash-redirect';
6
+ import checkLocale from './check-locale';
7
+ import metaDataImport from './meta-data-import';
8
+ import checkMiddlewareOrder from './check-middleware-order';
9
+ import urlsWithoutSlash from './urls-without-slash';
10
+
11
+ const rules = {
12
+ 'client-url': clientUrl,
13
+ 'image-import': imageImport,
14
+ 'link-import': linkImport,
15
+ 'router-import': routerImport,
16
+ 'skip-trailing-slash-redirect': skipTrailingSlashRedirect,
17
+ 'check-locale': checkLocale,
18
+ 'meta-data-import': metaDataImport,
19
+ 'check-middleware-order': checkMiddlewareOrder,
20
+ 'urls-without-slash': urlsWithoutSlash
21
+ };
22
+
23
+ export { rules };
@@ -1,44 +1,44 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
-
3
- export default ESLintUtils.RuleCreator.withoutDocs({
4
- create(context) {
5
- if (context.getFilename().includes('components/link.tsx')) {
6
- return {};
7
- }
8
-
9
- return {
10
- ImportDeclaration(node) {
11
- if (node.source.value === 'next/link') {
12
- context.report({
13
- messageId: 'linkImport',
14
- node,
15
- fix: (fixer) => {
16
- if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
- return null;
18
- }
19
-
20
- return fixer.replaceText(
21
- node,
22
- node.specifiers
23
- .map(
24
- (specifier) =>
25
- `import { ${specifier.local.name} } from 'components';`
26
- )
27
- .join('\n')
28
- );
29
- }
30
- });
31
- }
32
- }
33
- };
34
- },
35
- meta: {
36
- messages: {
37
- linkImport: "Import 'Link' component from 'components'."
38
- },
39
- type: 'problem',
40
- fixable: 'code',
41
- schema: []
42
- },
43
- defaultOptions: []
44
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+
3
+ export default ESLintUtils.RuleCreator.withoutDocs({
4
+ create(context) {
5
+ if (context.getFilename().includes('components/link.tsx')) {
6
+ return {};
7
+ }
8
+
9
+ return {
10
+ ImportDeclaration(node) {
11
+ if (node.source.value === 'next/link') {
12
+ context.report({
13
+ messageId: 'linkImport',
14
+ node,
15
+ fix: (fixer) => {
16
+ if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
17
+ return null;
18
+ }
19
+
20
+ return fixer.replaceText(
21
+ node,
22
+ node.specifiers
23
+ .map(
24
+ (specifier) =>
25
+ `import { ${specifier.local.name} } from 'components';`
26
+ )
27
+ .join('\n')
28
+ );
29
+ }
30
+ });
31
+ }
32
+ }
33
+ };
34
+ },
35
+ meta: {
36
+ messages: {
37
+ linkImport: "Import 'Link' component from 'components'."
38
+ },
39
+ type: 'problem',
40
+ fixable: 'code',
41
+ schema: []
42
+ },
43
+ defaultOptions: []
44
+ });
@@ -1,50 +1,50 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
-
3
- export default ESLintUtils.RuleCreator.withoutDocs({
4
- create(context) {
5
- return {
6
- ImportDeclaration(node) {
7
- const targetImportName = 'Metadata';
8
-
9
- const importSpecifiers = node.specifiers
10
- .filter((specifier) => specifier.type === 'ImportSpecifier')
11
- .map((specifier) => specifier.local.name);
12
-
13
- if (
14
- importSpecifiers.includes(targetImportName) &&
15
- node.source.value === 'next'
16
- ) {
17
- context.report({
18
- messageId: 'metaDataImport',
19
- node,
20
- fix: (fixer) => {
21
- if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
22
- return null;
23
- }
24
-
25
- return fixer.replaceText(
26
- node,
27
- node.specifiers
28
- .map(
29
- (specifier) =>
30
- `import { ${specifier.local.name} } from '@akinon/next/types';`
31
- )
32
- .join('\n')
33
- );
34
- }
35
- });
36
- }
37
- }
38
- };
39
- },
40
- meta: {
41
- messages: {
42
- metaDataImport:
43
- "Import '{ Metadata }' component from '@akinon/next/types'."
44
- },
45
- type: 'problem',
46
- fixable: 'code',
47
- schema: []
48
- },
49
- defaultOptions: []
50
- });
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+
3
+ export default ESLintUtils.RuleCreator.withoutDocs({
4
+ create(context) {
5
+ return {
6
+ ImportDeclaration(node) {
7
+ const targetImportName = 'Metadata';
8
+
9
+ const importSpecifiers = node.specifiers
10
+ .filter((specifier) => specifier.type === 'ImportSpecifier')
11
+ .map((specifier) => specifier.local.name);
12
+
13
+ if (
14
+ importSpecifiers.includes(targetImportName) &&
15
+ node.source.value === 'next'
16
+ ) {
17
+ context.report({
18
+ messageId: 'metaDataImport',
19
+ node,
20
+ fix: (fixer) => {
21
+ if (node.specifiers.find((s) => s.type === 'ImportSpecifier')) {
22
+ return null;
23
+ }
24
+
25
+ return fixer.replaceText(
26
+ node,
27
+ node.specifiers
28
+ .map(
29
+ (specifier) =>
30
+ `import { ${specifier.local.name} } from '@akinon/next/types';`
31
+ )
32
+ .join('\n')
33
+ );
34
+ }
35
+ });
36
+ }
37
+ }
38
+ };
39
+ },
40
+ meta: {
41
+ messages: {
42
+ metaDataImport:
43
+ "Import '{ Metadata }' component from '@akinon/next/types'."
44
+ },
45
+ type: 'problem',
46
+ fixable: 'code',
47
+ schema: []
48
+ },
49
+ defaultOptions: []
50
+ });
@@ -1,60 +1,60 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/types';
2
- import { ESLintUtils } from '@typescript-eslint/utils';
3
-
4
- export default ESLintUtils.RuleCreator.withoutDocs({
5
- create(context) {
6
- return {
7
- VariableDeclarator(node) {
8
- if (node.id.type !== AST_NODE_TYPES.Identifier) {
9
- return;
10
- }
11
-
12
- if (node.id.name !== 'nextConfig') {
13
- return;
14
- }
15
-
16
- if (node.init?.type !== AST_NODE_TYPES.ObjectExpression) {
17
- return;
18
- }
19
-
20
- const skipTrailingSlashRedirectNode = node.init.properties.find(
21
- (property) =>
22
- 'key' in property &&
23
- property.key.type === AST_NODE_TYPES.Identifier &&
24
- property.key.name === 'skipTrailingSlashRedirect'
25
- );
26
-
27
- if (
28
- !skipTrailingSlashRedirectNode ||
29
- skipTrailingSlashRedirectNode.type !== AST_NODE_TYPES.Property
30
- ) {
31
- return;
32
- }
33
-
34
- if (
35
- skipTrailingSlashRedirectNode.value.type === AST_NODE_TYPES.Literal &&
36
- skipTrailingSlashRedirectNode.value.value === true
37
- ) {
38
- return;
39
- }
40
-
41
- context.report({
42
- node: skipTrailingSlashRedirectNode,
43
- messageId: 'skipTrailingSlashRedirect',
44
- fix: (fixer) =>
45
- fixer.replaceText(skipTrailingSlashRedirectNode.value, 'true')
46
- });
47
- }
48
- };
49
- },
50
- meta: {
51
- messages: {
52
- skipTrailingSlashRedirect:
53
- 'The `skipTrailingSlashRedirect` value must be true.'
54
- },
55
- type: 'problem',
56
- fixable: 'code',
57
- schema: []
58
- },
59
- defaultOptions: []
60
- });
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/types';
2
+ import { ESLintUtils } from '@typescript-eslint/utils';
3
+
4
+ export default ESLintUtils.RuleCreator.withoutDocs({
5
+ create(context) {
6
+ return {
7
+ VariableDeclarator(node) {
8
+ if (node.id.type !== AST_NODE_TYPES.Identifier) {
9
+ return;
10
+ }
11
+
12
+ if (node.id.name !== 'nextConfig') {
13
+ return;
14
+ }
15
+
16
+ if (node.init?.type !== AST_NODE_TYPES.ObjectExpression) {
17
+ return;
18
+ }
19
+
20
+ const skipTrailingSlashRedirectNode = node.init.properties.find(
21
+ (property) =>
22
+ 'key' in property &&
23
+ property.key.type === AST_NODE_TYPES.Identifier &&
24
+ property.key.name === 'skipTrailingSlashRedirect'
25
+ );
26
+
27
+ if (
28
+ !skipTrailingSlashRedirectNode ||
29
+ skipTrailingSlashRedirectNode.type !== AST_NODE_TYPES.Property
30
+ ) {
31
+ return;
32
+ }
33
+
34
+ if (
35
+ skipTrailingSlashRedirectNode.value.type === AST_NODE_TYPES.Literal &&
36
+ skipTrailingSlashRedirectNode.value.value === true
37
+ ) {
38
+ return;
39
+ }
40
+
41
+ context.report({
42
+ node: skipTrailingSlashRedirectNode,
43
+ messageId: 'skipTrailingSlashRedirect',
44
+ fix: (fixer) =>
45
+ fixer.replaceText(skipTrailingSlashRedirectNode.value, 'true')
46
+ });
47
+ }
48
+ };
49
+ },
50
+ meta: {
51
+ messages: {
52
+ skipTrailingSlashRedirect:
53
+ 'The `skipTrailingSlashRedirect` value must be true.'
54
+ },
55
+ type: 'problem',
56
+ fixable: 'code',
57
+ schema: []
58
+ },
59
+ defaultOptions: []
60
+ });