@progressive-victory/eslint-plugin-index-file 0.0.3

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.
@@ -0,0 +1,18 @@
1
+ name: Build
2
+ on: [push]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ environment: Preview
7
+ steps:
8
+ - name: Checkout repository
9
+ uses: actions/checkout@v4
10
+
11
+ - name: Install pnpm
12
+ uses: pnpm/action-setup@v3
13
+
14
+ - name: Install dependencies
15
+ run: pnpm install --frozen-lockfile
16
+
17
+ - name: Build project
18
+ run: pnpm build
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # eslint-index-file-plugin
2
+ Custom plugin to eslint for enforcing the use of index files.
@@ -0,0 +1,20 @@
1
+ import esbuild from 'esbuild';
2
+ import path, { dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+
8
+ await esbuild.build({
9
+ platform: 'node',
10
+ target: 'esnext',
11
+ format: 'esm',
12
+ entryPoints: ['./src/index.ts'],
13
+ outfile: './dist/index.js',
14
+ sourcemap: true,
15
+ minify: false,
16
+ bundle: true,
17
+ legalComments: 'external',
18
+ packages: 'external',
19
+ alias: { '~': path.resolve(__dirname, 'src') },
20
+ });
@@ -0,0 +1,37 @@
1
+ import js from '@eslint/js'
2
+ import { defineConfig } from 'eslint/config'
3
+ import globals from 'globals'
4
+ import tseslint from 'typescript-eslint'
5
+
6
+ export default defineConfig([
7
+ {
8
+ ignores: ['dist/**'],
9
+ },
10
+ {
11
+ files: ['**/*.ts,mts,cts,jsx,tsx'],
12
+ plugins: { js, index },
13
+ extends: ['js/recommended'],
14
+ languageOptions: { globals: { ...globals.browser, ...globals.node } },
15
+ },
16
+ tseslint.configs.recommendedTypeChecked,
17
+ tseslint.configs.stylisticTypeChecked,
18
+ {
19
+ languageOptions: {
20
+ parserOptions: {
21
+ projectService: {
22
+ allowDefaultProject: ['*.js']
23
+ },
24
+ tsconfigRootDir: import.meta.dirname,
25
+ },
26
+ },
27
+ rules: {
28
+ 'object-shorthand': 'warn',
29
+ '@typescript-eslint/no-unsafe-assignment': 'warn',
30
+ '@typescript-eslint/no-unsafe-member-access': 'warn',
31
+ '@typescript-eslint/no-unsafe-argument': 'warn',
32
+ '@typescript-eslint/no-unsafe-enum-comparison': 'off',
33
+ '@typescript-eslint/no-unsafe-call': 'warn',
34
+ '@typescript-eslint/no-unsafe-return': 'warn',
35
+ },
36
+ },
37
+ ])
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@progressive-victory/eslint-plugin-index-file",
3
+ "version": "0.0.3",
4
+ "description": "Plugin that enforces the use of index files with eslint.",
5
+ "homepage": "https://github.com/Progressive-Victory/eslint-index-file-plugin#readme",
6
+ "private": false,
7
+ "bugs": {
8
+ "url": "https://github.com/Progressive-Victory/eslint-index-file-plugin/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/Progressive-Victory/eslint-index-file-plugin.git"
13
+ },
14
+ "license": "ISC",
15
+ "author": "sH3llH0und",
16
+ "type": "module",
17
+ "main": "dist/index.js",
18
+ "exports": {
19
+ "./*.js": {
20
+ "types": "./*.d.ts",
21
+ "require": "./*.js",
22
+ "import": "./*.js"
23
+ }
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^25.9.1",
27
+ "@typescript-eslint/rule-tester": "^8.60.1",
28
+ "esbuild": "^0.28.0",
29
+ "globals": "^17.6.0",
30
+ "prettier": "^3.8.3",
31
+ "typescript": "^6.0.3",
32
+ "typescript-eslint": "^8.60.1",
33
+ "vitest": "^4.1.8"
34
+ },
35
+ "dependencies": {
36
+ "@typescript-eslint/eslint-plugin": "^8.60.1",
37
+ "@typescript-eslint/parser": "^8.60.1",
38
+ "@typescript-eslint/utils": "^8.60.1",
39
+ "eslint": "^10.4.1"
40
+ },
41
+ "scripts": {
42
+ "build": "node esbuild.config.js",
43
+ "test": "pnpm build && pnpm vitest --silent=false"
44
+ }
45
+ }
package/src/index.ts ADDED
@@ -0,0 +1,24 @@
1
+ import {enforceIndexUsageRule} from "./rules"
2
+
3
+ const {name, version} =
4
+ // eslint-diable-next-line @typescript-eslint/no-require-imports
5
+ require("../package.json") as typeof import("../package.json")
6
+
7
+ const plugin = {
8
+ configs: {
9
+ get recommended() {
10
+ return recommended
11
+ }
12
+ },
13
+ meta: { name, version },
14
+ enforceIndexUsageRule
15
+ }
16
+
17
+ const recommended = {
18
+ plugins: {
19
+ "eslint-index-file-plugin": plugin
20
+ },
21
+ enforceIndexUsageRule
22
+ }
23
+
24
+ export default plugin;
@@ -0,0 +1,44 @@
1
+ import path from "path"
2
+ import tseslint from "typescript-eslint";
3
+ import { RuleTester } from "@typescript-eslint/rule-tester"
4
+ import * as vitest from "vitest"
5
+
6
+ import { enforceIndexUsageRule } from "./enforce-index-usage"
7
+
8
+ RuleTester.afterAll = vitest.afterAll
9
+ RuleTester.it = vitest.it
10
+ RuleTester.itOnly = vitest.it.only
11
+ RuleTester.describe = vitest.describe
12
+
13
+ const ruleTester = new RuleTester({
14
+ languageOptions: {
15
+ parser: tseslint.parser,
16
+ parserOptions: {
17
+ projectService: {
18
+ allowDefaultProject: ["*.js"],
19
+ defaultProject: "tsconfig.json"
20
+ },
21
+ tsconfigRootDir: path.join(import.meta.dirname, "../..")
22
+ }
23
+ }
24
+ })
25
+
26
+ ruleTester.run("enforce-index-usage", enforceIndexUsageRule, {
27
+ valid: [
28
+ {
29
+ code: `export const foo = bar`
30
+ }
31
+ ],
32
+ invalid: [
33
+ {
34
+ code: `export const bar = foo`,
35
+ errors: [
36
+ {
37
+ messageId: "notExportedInIndex",
38
+ suggestions: [
39
+ ]
40
+ }
41
+ ]
42
+ }
43
+ ]
44
+ })
@@ -0,0 +1,47 @@
1
+ //import {ESLintUtils} from "@typescript-eslint/utils"
2
+
3
+ import { createRule } from "../utils.js"
4
+ import path from "node:path"
5
+ import fs from "fs"
6
+
7
+ export const enforceIndexUsageRule = createRule({
8
+ create(context) {
9
+ //const services = ESLintUtils.getParserServices(context);
10
+
11
+ return {
12
+ ExportNamedDeclaration(node) {
13
+ console.log("doing shit")
14
+ const cwd = context.cwd
15
+ const cwdFiles = fs.readdirSync(cwd)
16
+ const index = cwdFiles.find(x => x === "index.ts")
17
+ if(!index) context.report({
18
+ messageId: 'noIndexPresent',
19
+ node
20
+ })
21
+
22
+ const fileNameArr = context.filename.split('.')
23
+ const fileName = fileNameArr[fileNameArr.length - 1]
24
+ const indexContent = fs.readFileSync(path.join(cwd, "index.ts")).toString()
25
+ if(!indexContent.includes(`export * from './${fileName}.js`)) context.report({
26
+ messageId: "notExportedInIndex",
27
+ node
28
+ })
29
+ }
30
+ }
31
+ },
32
+ meta: {
33
+ docs: {
34
+ description: "Enforces the usage of index files within code.",
35
+ recommended: true,
36
+ requiresTypeChecking: false
37
+ },
38
+ messages: {
39
+ notExportedInIndex: "Export statement not accompanied by index file entry.",
40
+ noIndexPresent: "Could not find index file in working directory."
41
+ },
42
+ type: "problem",
43
+ schema: []
44
+ },
45
+ name: "enforce-index-usage",
46
+ defaultOptions: []
47
+ })
@@ -0,0 +1,2 @@
1
+ export * from './enforce-index-usage.js'
2
+ export * from './enforce-index-usage.test.js'
package/src/utils.ts ADDED
@@ -0,0 +1,11 @@
1
+ import {ESLintUtils} from "@typescript-eslint/utils"
2
+
3
+ export interface IndexFileDocs {
4
+ description: string;
5
+ recommended?: boolean;
6
+ requiresTypeChecking?: boolean;
7
+ }
8
+
9
+ export const createRule = ESLintUtils.RuleCreator<IndexFileDocs>(
10
+ (name) => `https://github.com/import-js/eslint-plugin-import/wiki/${name}`
11
+ )
package/tsconfig.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": ".",
6
+ "outDir": "./dist",
7
+ "paths": {
8
+ "~/*": ["./src/*"]
9
+ },
10
+
11
+ // Environment Settings
12
+ // See also https://aka.ms/tsconfig/module
13
+ "moduleResolution": "bundler",
14
+ "module": "esnext",
15
+ "target": "esnext",
16
+ // For nodejs:
17
+ "lib": ["esnext"],
18
+ "types": ["node"],
19
+ // and npm install -D @types/node
20
+
21
+ // Other Outputs
22
+ "sourceMap": true,
23
+ "declaration": true,
24
+ "declarationMap": true,
25
+
26
+ // Stricter Typechecking Options
27
+ "noUncheckedIndexedAccess": true,
28
+ "exactOptionalPropertyTypes": true,
29
+
30
+ // Style Options
31
+ "noImplicitReturns": true,
32
+ "noImplicitOverride": true,
33
+ "noUnusedLocals": true,
34
+ "noUnusedParameters": true,
35
+ "noFallthroughCasesInSwitch": true,
36
+ // "noPropertyAccessFromIndexSignature": true,
37
+
38
+ // Recommended Options
39
+ "strict": true,
40
+ "verbatimModuleSyntax": false,
41
+ "isolatedModules": true,
42
+ "noUncheckedSideEffectImports": true,
43
+ "moduleDetection": "force",
44
+ "skipLibCheck": true,
45
+ },
46
+ "exclude": ["node_modules", "dist"]
47
+ }