@kurateh/eslint-plugin 0.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.cjs ADDED
@@ -0,0 +1,193 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var utils = require('@typescript-eslint/utils');
6
+
7
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var path__default = /*#__PURE__*/_interopDefault(path);
11
+
12
+ // src/index.ts
13
+ var createRule = utils.ESLintUtils.RuleCreator.withoutDocs;
14
+
15
+ // src/rules/import-path.ts
16
+ var posix = path__default.default.posix;
17
+ var TS_CONFIG_FILE_NAMES = ["tsconfig.path.json", "tsconfig.json"];
18
+ var has = (map, path2) => {
19
+ let inner = map;
20
+ for (const step of path2.split(".")) {
21
+ inner = inner[step];
22
+ if (inner === void 0) {
23
+ return false;
24
+ }
25
+ }
26
+ return true;
27
+ };
28
+ var normalizePath = (p) => p.replace(/\\/g, "/");
29
+ var findFilePath = (filename, initialPath) => {
30
+ let dir = initialPath;
31
+ let lastDir;
32
+ do {
33
+ lastDir = dir;
34
+ dir = posix.dirname(dir);
35
+ } while (!fs.existsSync(path.join(dir, filename)) && dir !== lastDir);
36
+ const filePath = path.join(dir, filename);
37
+ if (!fs.existsSync(filePath)) {
38
+ return;
39
+ }
40
+ return normalizePath(filePath);
41
+ };
42
+ var getAbsolutePathInfo = (fileName) => {
43
+ const normalizedFileName = normalizePath(fileName);
44
+ for (const configPath of TS_CONFIG_FILE_NAMES) {
45
+ const filePath = findFilePath(configPath, normalizedFileName);
46
+ if (filePath === void 0) {
47
+ continue;
48
+ }
49
+ const baseDir = normalizePath(posix.dirname(filePath));
50
+ const tsPathConfig = JSON.parse(
51
+ fs.readFileSync(filePath, {
52
+ encoding: "utf-8"
53
+ }).replace(
54
+ /("(?:[^"\\]|\\.)*")|\/\/.*/g,
55
+ (_, string) => string || ""
56
+ ).replace(
57
+ /("(?:[^"\\]|\\.)*")|\/\*[\s\S]*?\*\//g,
58
+ (_, string) => string || ""
59
+ ).replace(/,(?=\s*[\]}])/g, "")
60
+ );
61
+ const result = {
62
+ baseUrl: "",
63
+ paths: {}
64
+ };
65
+ if (has(tsPathConfig, "compilerOptions.baseUrl")) {
66
+ result.baseUrl = normalizePath(
67
+ posix.join(baseDir, tsPathConfig.compilerOptions.baseUrl)
68
+ );
69
+ }
70
+ if (has(tsPathConfig, "compilerOptions.paths")) {
71
+ result.paths = Object.fromEntries(
72
+ Object.entries(tsPathConfig.compilerOptions.paths).map(
73
+ ([key, value]) => [
74
+ key.replace(/\/\*$/, "/"),
75
+ value.map(
76
+ (path2) => normalizePath(posix.join(baseDir, path2)).replace(/\/\*$/, "/")
77
+ )
78
+ ]
79
+ )
80
+ );
81
+ }
82
+ return result;
83
+ }
84
+ return;
85
+ };
86
+ var import_path_default = createRule({
87
+ meta: {
88
+ type: "suggestion",
89
+ fixable: "code",
90
+ messages: {
91
+ shouldBeRelativePath: 'When importing a child module, you must use the relative path. Use "{{expectedPath}}" instead of "{{source}}".',
92
+ shouldBeAbsolutePath: 'When importing a parent module, you must use the absolute path. Use "{{expectedPath}}" instead of "{{source}}".'
93
+ },
94
+ schema: [],
95
+ docs: {
96
+ description: "Enforce import path according to the location of the imported file."
97
+ }
98
+ },
99
+ defaultOptions: [],
100
+ create: (context) => {
101
+ const fileName = normalizePath(context.filename);
102
+ const absolutePathInfo = getAbsolutePathInfo(fileName);
103
+ return {
104
+ ImportDeclaration: (node) => {
105
+ if (absolutePathInfo === void 0) {
106
+ return;
107
+ }
108
+ const source = node.source.value;
109
+ if (source.startsWith("..")) {
110
+ const sourceAbsolutePath2 = normalizePath(
111
+ posix.join(posix.dirname(fileName), source)
112
+ );
113
+ for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
114
+ for (const path2 of paths) {
115
+ if (sourceAbsolutePath2.startsWith(path2)) {
116
+ const expectedPath2 = sourceAbsolutePath2.replace(path2, alias);
117
+ context.report({
118
+ node,
119
+ messageId: "shouldBeAbsolutePath",
120
+ data: {
121
+ expectedPath: expectedPath2,
122
+ source
123
+ },
124
+ fix(fixer) {
125
+ return fixer.replaceText(node.source, `"${expectedPath2}"`);
126
+ }
127
+ });
128
+ return;
129
+ }
130
+ }
131
+ }
132
+ return;
133
+ }
134
+ let sourceAbsolutePath;
135
+ for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
136
+ for (const path2 of paths) {
137
+ if (source.startsWith(alias)) {
138
+ sourceAbsolutePath = normalizePath(
139
+ posix.join(path2, source.replace(alias, ""))
140
+ );
141
+ break;
142
+ }
143
+ }
144
+ if (sourceAbsolutePath !== void 0) {
145
+ break;
146
+ }
147
+ }
148
+ if (sourceAbsolutePath === void 0) {
149
+ return;
150
+ }
151
+ const sourceRelativePath = normalizePath(
152
+ posix.relative(posix.dirname(fileName), sourceAbsolutePath)
153
+ );
154
+ if (sourceRelativePath.startsWith("..")) {
155
+ return;
156
+ }
157
+ const expectedPath = "./" + sourceRelativePath;
158
+ context.report({
159
+ node,
160
+ messageId: "shouldBeRelativePath",
161
+ data: {
162
+ expectedPath,
163
+ source
164
+ },
165
+ fix(fixer) {
166
+ return fixer.replaceText(node.source, `"${expectedPath}"`);
167
+ }
168
+ });
169
+ return;
170
+ }
171
+ };
172
+ }
173
+ });
174
+
175
+ // src/rules/index.ts
176
+ var rules_default = {
177
+ "import-path": import_path_default
178
+ };
179
+
180
+ // src/index.ts
181
+ var pkg = JSON.parse(
182
+ fs.readFileSync(new URL("../package.json", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))), "utf-8")
183
+ );
184
+ var plugin = {
185
+ meta: {
186
+ name: "@kurateh/eslint-plugin",
187
+ version: pkg.version
188
+ },
189
+ rules: rules_default
190
+ };
191
+ var index_default = plugin;
192
+
193
+ module.exports = index_default;
@@ -0,0 +1,5 @@
1
+ import { ESLint } from 'eslint';
2
+
3
+ declare const plugin: ESLint.Plugin;
4
+
5
+ export { plugin as default };
@@ -0,0 +1,5 @@
1
+ import { ESLint } from 'eslint';
2
+
3
+ declare const plugin: ESLint.Plugin;
4
+
5
+ export { plugin as default };
package/dist/index.js ADDED
@@ -0,0 +1,187 @@
1
+ import { createRequire } from 'module';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import path, { join } from 'path';
4
+ import { ESLintUtils } from '@typescript-eslint/utils';
5
+
6
+ createRequire(import.meta.url);
7
+ var createRule = ESLintUtils.RuleCreator.withoutDocs;
8
+
9
+ // src/rules/import-path.ts
10
+ var posix = path.posix;
11
+ var TS_CONFIG_FILE_NAMES = ["tsconfig.path.json", "tsconfig.json"];
12
+ var has = (map, path2) => {
13
+ let inner = map;
14
+ for (const step of path2.split(".")) {
15
+ inner = inner[step];
16
+ if (inner === void 0) {
17
+ return false;
18
+ }
19
+ }
20
+ return true;
21
+ };
22
+ var normalizePath = (p) => p.replace(/\\/g, "/");
23
+ var findFilePath = (filename, initialPath) => {
24
+ let dir = initialPath;
25
+ let lastDir;
26
+ do {
27
+ lastDir = dir;
28
+ dir = posix.dirname(dir);
29
+ } while (!existsSync(join(dir, filename)) && dir !== lastDir);
30
+ const filePath = join(dir, filename);
31
+ if (!existsSync(filePath)) {
32
+ return;
33
+ }
34
+ return normalizePath(filePath);
35
+ };
36
+ var getAbsolutePathInfo = (fileName) => {
37
+ const normalizedFileName = normalizePath(fileName);
38
+ for (const configPath of TS_CONFIG_FILE_NAMES) {
39
+ const filePath = findFilePath(configPath, normalizedFileName);
40
+ if (filePath === void 0) {
41
+ continue;
42
+ }
43
+ const baseDir = normalizePath(posix.dirname(filePath));
44
+ const tsPathConfig = JSON.parse(
45
+ readFileSync(filePath, {
46
+ encoding: "utf-8"
47
+ }).replace(
48
+ /("(?:[^"\\]|\\.)*")|\/\/.*/g,
49
+ (_, string) => string || ""
50
+ ).replace(
51
+ /("(?:[^"\\]|\\.)*")|\/\*[\s\S]*?\*\//g,
52
+ (_, string) => string || ""
53
+ ).replace(/,(?=\s*[\]}])/g, "")
54
+ );
55
+ const result = {
56
+ baseUrl: "",
57
+ paths: {}
58
+ };
59
+ if (has(tsPathConfig, "compilerOptions.baseUrl")) {
60
+ result.baseUrl = normalizePath(
61
+ posix.join(baseDir, tsPathConfig.compilerOptions.baseUrl)
62
+ );
63
+ }
64
+ if (has(tsPathConfig, "compilerOptions.paths")) {
65
+ result.paths = Object.fromEntries(
66
+ Object.entries(tsPathConfig.compilerOptions.paths).map(
67
+ ([key, value]) => [
68
+ key.replace(/\/\*$/, "/"),
69
+ value.map(
70
+ (path2) => normalizePath(posix.join(baseDir, path2)).replace(/\/\*$/, "/")
71
+ )
72
+ ]
73
+ )
74
+ );
75
+ }
76
+ return result;
77
+ }
78
+ return;
79
+ };
80
+ var import_path_default = createRule({
81
+ meta: {
82
+ type: "suggestion",
83
+ fixable: "code",
84
+ messages: {
85
+ shouldBeRelativePath: 'When importing a child module, you must use the relative path. Use "{{expectedPath}}" instead of "{{source}}".',
86
+ shouldBeAbsolutePath: 'When importing a parent module, you must use the absolute path. Use "{{expectedPath}}" instead of "{{source}}".'
87
+ },
88
+ schema: [],
89
+ docs: {
90
+ description: "Enforce import path according to the location of the imported file."
91
+ }
92
+ },
93
+ defaultOptions: [],
94
+ create: (context) => {
95
+ const fileName = normalizePath(context.filename);
96
+ const absolutePathInfo = getAbsolutePathInfo(fileName);
97
+ return {
98
+ ImportDeclaration: (node) => {
99
+ if (absolutePathInfo === void 0) {
100
+ return;
101
+ }
102
+ const source = node.source.value;
103
+ if (source.startsWith("..")) {
104
+ const sourceAbsolutePath2 = normalizePath(
105
+ posix.join(posix.dirname(fileName), source)
106
+ );
107
+ for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
108
+ for (const path2 of paths) {
109
+ if (sourceAbsolutePath2.startsWith(path2)) {
110
+ const expectedPath2 = sourceAbsolutePath2.replace(path2, alias);
111
+ context.report({
112
+ node,
113
+ messageId: "shouldBeAbsolutePath",
114
+ data: {
115
+ expectedPath: expectedPath2,
116
+ source
117
+ },
118
+ fix(fixer) {
119
+ return fixer.replaceText(node.source, `"${expectedPath2}"`);
120
+ }
121
+ });
122
+ return;
123
+ }
124
+ }
125
+ }
126
+ return;
127
+ }
128
+ let sourceAbsolutePath;
129
+ for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
130
+ for (const path2 of paths) {
131
+ if (source.startsWith(alias)) {
132
+ sourceAbsolutePath = normalizePath(
133
+ posix.join(path2, source.replace(alias, ""))
134
+ );
135
+ break;
136
+ }
137
+ }
138
+ if (sourceAbsolutePath !== void 0) {
139
+ break;
140
+ }
141
+ }
142
+ if (sourceAbsolutePath === void 0) {
143
+ return;
144
+ }
145
+ const sourceRelativePath = normalizePath(
146
+ posix.relative(posix.dirname(fileName), sourceAbsolutePath)
147
+ );
148
+ if (sourceRelativePath.startsWith("..")) {
149
+ return;
150
+ }
151
+ const expectedPath = "./" + sourceRelativePath;
152
+ context.report({
153
+ node,
154
+ messageId: "shouldBeRelativePath",
155
+ data: {
156
+ expectedPath,
157
+ source
158
+ },
159
+ fix(fixer) {
160
+ return fixer.replaceText(node.source, `"${expectedPath}"`);
161
+ }
162
+ });
163
+ return;
164
+ }
165
+ };
166
+ }
167
+ });
168
+
169
+ // src/rules/index.ts
170
+ var rules_default = {
171
+ "import-path": import_path_default
172
+ };
173
+
174
+ // src/index.ts
175
+ var pkg = JSON.parse(
176
+ readFileSync(new URL("../package.json", import.meta.url), "utf-8")
177
+ );
178
+ var plugin = {
179
+ meta: {
180
+ name: "@kurateh/eslint-plugin",
181
+ version: pkg.version
182
+ },
183
+ rules: rules_default
184
+ };
185
+ var index_default = plugin;
186
+
187
+ export { index_default as default };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@kurateh/eslint-plugin",
3
+ "version": "0.0.0",
4
+ "description": "",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "keywords": [],
16
+ "author": {
17
+ "name": "kurateh",
18
+ "email": "me@kurateh.com"
19
+ },
20
+ "repository": {
21
+ "url": "https://github.com/kurateh/ts-configs"
22
+ },
23
+ "license": "ISC",
24
+ "dependencies": {
25
+ "@typescript-eslint/utils": "^8.59.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^24.13.3",
29
+ "@typescript-eslint/parser": "8.59.0",
30
+ "@typescript-eslint/rule-tester": "8.59.0",
31
+ "vitest": "^4.1.10"
32
+ },
33
+ "peerDependencies": {
34
+ "eslint": ">=9"
35
+ },
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "format": "prettier --write .",
39
+ "format:check": "prettier --check .",
40
+ "test": "vitest run"
41
+ }
42
+ }