Skip to content

Commit

Permalink
refactor: migrate core utils (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed Mar 13, 2024
1 parent bbf46c3 commit dc3d48b
Show file tree
Hide file tree
Showing 61 changed files with 943 additions and 892 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-tools-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-import-x": patch
---

refactor: migrate core utils
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@
"export"
],
"scripts": {
"build": "rimraf lib && tsc -p src",
"lint": "yarn lint:es && yarn update:eslint-docs --check",
"build": "tsc -p src",
"clean": "rimraf lib",
"lint": "run-p lint:*",
"lint:docs": "yarn update:eslint-docs --check",
"lint:es": "eslint . --cache",
"lint:tsc": "tsc -p tsconfig.base.json --noEmit",
"prepare": "patch-package",
"release": "changeset publish",
"test": "jest",
"test-compiled": "yarn build && cross-env TEST_COMPILED=1 jest",
"update:eslint-docs": "yarn build && eslint-doc-generator --rule-doc-title-format prefix-name --rule-doc-section-options false --rule-list-split meta.docs.category --ignore-config stage-0 --config-emoji recommended,☑️",
"update:eslint-docs": "eslint-doc-generator --rule-doc-title-format prefix-name --rule-doc-section-options false --rule-list-split meta.docs.category --ignore-config stage-0 --config-emoji recommended,☑️",
"watch": "yarn test --watch"
},
"peerDependencies": {
Expand Down Expand Up @@ -75,6 +78,7 @@
"@types/eslint": "^8.56.5",
"@types/jest": "^29.5.12",
"@types/json-schema": "^7.0.15",
"@types/node": "^20.11.26",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript-eslint/typescript-estree": "^5.62.0",
Expand All @@ -94,6 +98,7 @@
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"npm-run-all2": "^6.1.2",
"prettier": "^3.2.5",
"redux": "^5.0.1",
"rimraf": "^5.0.5",
Expand Down
73 changes: 46 additions & 27 deletions src/core/importType.js → src/core/import-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {

import { isCoreModule } from '../utils/is-core-module'
import { resolve } from '../utils/resolve'
import { getContextPackagePath } from './packagePath'
import { getContextPackagePath } from './package-path'
import { PluginSettings, RuleContext } from '../types'

function baseModule(name) {
function baseModule(name: string) {
if (isScoped(name)) {
const [scope, pkg] = name.split('/')
return `${scope}/${pkg}`
Expand All @@ -17,17 +18,21 @@ function baseModule(name) {
return pkg
}

function isInternalRegexMatch(name, settings) {
const internalScope = settings && settings['import-x/internal-regex']
function isInternalRegexMatch(name: string, settings: PluginSettings) {
const internalScope = settings?.['import-x/internal-regex']
return internalScope && new RegExp(internalScope).test(name)
}

export function isAbsolute(name) {
export function isAbsolute(name?: string | boolean | number | null) {
return typeof name === 'string' && nodeIsAbsolute(name)
}

// path is defined only when a resolver resolves to a non-standard path
export function isBuiltIn(name, settings, path) {
export function isBuiltIn(
name: string,
settings: PluginSettings,
path?: string | null,
) {
if (path || !name) {
return false
}
Expand All @@ -36,7 +41,11 @@ export function isBuiltIn(name, settings, path) {
return isCoreModule(base) || extras.indexOf(base) > -1
}

export function isExternalModule(name, path, context) {
export function isExternalModule(
name: string,
path: string,
context: RuleContext,
) {
if (arguments.length < 3) {
throw new TypeError(
'isExternalModule: name, path, and context are all required',
Expand All @@ -48,7 +57,11 @@ export function isExternalModule(name, path, context) {
)
}

export function isExternalModuleMain(name, path, context) {
export function isExternalModuleMain(
name: string,
path: string,
context: RuleContext,
) {
if (arguments.length < 3) {
throw new TypeError(
'isExternalModule: name, path, and context are all required',
Expand All @@ -58,39 +71,44 @@ export function isExternalModuleMain(name, path, context) {
}

const moduleRegExp = /^\w/
function isModule(name) {

function isModule(name: string) {
return name && moduleRegExp.test(name)
}

const moduleMainRegExp = /^[\w]((?!\/).)*$/
function isModuleMain(name) {

function isModuleMain(name: string) {
return name && moduleMainRegExp.test(name)
}

const scopedRegExp = /^@[^/]+\/?[^/]+/
export function isScoped(name) {

export function isScoped(name: string) {
return name && scopedRegExp.test(name)
}

const scopedMainRegExp = /^@[^/]+\/?[^/]+$/
export function isScopedMain(name) {

export function isScopedMain(name: string) {
return name && scopedMainRegExp.test(name)
}

function isRelativeToParent(name) {
function isRelativeToParent(name: string) {
return /^\.\.$|^\.\.[\\/]/.test(name)
}

const indexFiles = ['.', './', './index', './index.js']
function isIndex(name) {
return indexFiles.indexOf(name) !== -1

function isIndex(name: string) {
return indexFiles.includes(name)
}

function isRelativeToSibling(name) {
function isRelativeToSibling(name: string) {
return /^\.[\\/]/.test(name)
}

function isExternalPath(path, context) {
function isExternalPath(path: string | null | undefined, context: RuleContext) {
if (!path) {
return false
}
Expand All @@ -102,45 +120,46 @@ function isExternalPath(path, context) {
return true
}

const folders = (settings &&
settings['import-x/external-module-folders']) || ['node_modules']
const folders = settings?.['import-x/external-module-folders'] || [
'node_modules',
]
return folders.some(folder => {
const folderPath = nodeResolve(packagePath, folder)
const relativePath = relative(folderPath, path)
return !relativePath.startsWith('..')
})
}

function isInternalPath(path, context) {
function isInternalPath(path: string | null | undefined, context: RuleContext) {
if (!path) {
return false
}
const packagePath = getContextPackagePath(context)
return !relative(packagePath, path).startsWith('../')
}

function isExternalLookingName(name) {
function isExternalLookingName(name: string) {
return isModule(name) || isScoped(name)
}

function typeTest(name, context, path) {
function typeTest(name: string, context: RuleContext, path?: string | null) {
const { settings } = context
if (isInternalRegexMatch(name, settings)) {
return 'internal'
}
if (isAbsolute(name, settings, path)) {
if (isAbsolute(name)) {
return 'absolute'
}
if (isBuiltIn(name, settings, path)) {
return 'builtin'
}
if (isRelativeToParent(name, settings, path)) {
if (isRelativeToParent(name)) {
return 'parent'
}
if (isIndex(name, settings, path)) {
if (isIndex(name)) {
return 'index'
}
if (isRelativeToSibling(name, settings, path)) {
if (isRelativeToSibling(name)) {
return 'sibling'
}
if (isExternalPath(path, context)) {
Expand All @@ -155,6 +174,6 @@ function typeTest(name, context, path) {
return 'unknown'
}

export default function resolveImportType(name, context) {
export function importType(name: string, context: RuleContext) {
return typeTest(name, context, resolve(name, context))
}
27 changes: 27 additions & 0 deletions src/core/package-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { dirname } from 'path'

import { pkgUp } from '../utils/pkg-up'
import { readPkgUp } from '../utils/read-pkg-ip'
import { RuleContext } from '../types'

export function getContextPackagePath(context: RuleContext) {
return getFilePackagePath(
context.getPhysicalFilename
? context.getPhysicalFilename()
: context.getFilename(),
)
}

export function getFilePackagePath(filePath: string) {
const fp = pkgUp({ cwd: filePath })!
return dirname(fp)
}

export function getFilePackageName(filePath: string): string | null {
const { pkg, path } = readPkgUp({ cwd: filePath })
if (pkg) {
// recursion in case of intermediate esm package.json without name found
return pkg.name || getFilePackageName(dirname(dirname(path)))
}
return null
}
25 changes: 0 additions & 25 deletions src/core/packagePath.js

This file was deleted.

4 changes: 3 additions & 1 deletion src/core/staticRequire.js → src/core/static-require.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { TSESTree } from '@typescript-eslint/utils'

// todo: merge with module visitor
export default function isStaticRequire(node) {
export function isStaticRequire(node: TSESTree.CallExpression) {
return (
node &&
node.callee &&
Expand Down
6 changes: 2 additions & 4 deletions src/ExportMap.ts → src/export-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ export class ExportMap {

private declare mtime: Date

private declare doc: Annotation
declare doc: Annotation

constructor(public path: string) {}

Expand Down Expand Up @@ -812,8 +812,6 @@ export class ExportMap {
}
}
}

return undefined
}

forEach(
Expand Down Expand Up @@ -1072,7 +1070,7 @@ function childContext(
: 'getFilename' in context &&
typeof context.getFilename === 'function'
? context.getFilename()
: (('filename' in context && context.filename) as string),
: ('filename' in context && context.filename) || undefined,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/rules/default.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExportMap } from '../ExportMap'
import { ExportMap } from '../export-map'
import { docsUrl } from '../docs-url'

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/export.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExportMap, recursivePatternCapture } from '../ExportMap'
import { ExportMap, recursivePatternCapture } from '../export-map'
import { docsUrl } from '../docs-url'

/*
Expand Down
4 changes: 2 additions & 2 deletions src/rules/extensions.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import path from 'path'

import { resolve } from '../utils/resolve'
import { isBuiltIn, isExternalModule, isScoped } from '../core/importType'
import { moduleVisitor } from '../utils/moduleVisitor'
import { isBuiltIn, isExternalModule, isScoped } from '../core/import-type'
import { moduleVisitor } from '../utils/module-visitor'
import { docsUrl } from '../docs-url'

const enumValues = { enum: ['always', 'ignorePackages', 'never'] }
Expand Down
2 changes: 1 addition & 1 deletion src/rules/max-dependencies.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { moduleVisitor } from '../utils/moduleVisitor'
import { moduleVisitor } from '../utils/module-visitor'
import { docsUrl } from '../docs-url'

const DEFAULT_MAX = 10
Expand Down
4 changes: 2 additions & 2 deletions src/rules/named.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import path from 'path'

import type { TSESTree } from '@typescript-eslint/utils'

import { ExportMap } from '../ExportMap'
import { ExportMap } from '../export-map'
import { createRule } from '../utils'
import { ModuleOptions } from '../utils/moduleVisitor'
import { ModuleOptions } from '../utils/module-visitor'

type MessageId = 'notFound' | 'notFoundDeep'

Expand Down
4 changes: 2 additions & 2 deletions src/rules/namespace.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import declaredScope from '../utils/declaredScope'
import { ExportMap } from '../ExportMap'
import { declaredScope } from '../utils/declared-scope'
import { ExportMap } from '../export-map'
import { importDeclaration } from '../import-declaration'
import { docsUrl } from '../docs-url'

Expand Down
2 changes: 1 addition & 1 deletion src/rules/newline-after-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @author Radek Benkel
*/

import isStaticRequire from '../core/staticRequire'
import { isStaticRequire } from '../core/static-require'
import { docsUrl } from '../docs-url'

import debug from 'debug'
Expand Down
4 changes: 2 additions & 2 deletions src/rules/no-absolute-path.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path'
import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor'
import { isAbsolute } from '../core/importType'
import { moduleVisitor, makeOptionsSchema } from '../utils/module-visitor'
import { isAbsolute } from '../core/import-type'
import { docsUrl } from '../docs-url'

module.exports = {
Expand Down
6 changes: 3 additions & 3 deletions src/rules/no-cycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*/

import { resolve } from '../utils/resolve'
import { ExportMap } from '../ExportMap'
import { isExternalModule } from '../core/importType'
import { moduleVisitor, makeOptionsSchema } from '../utils/moduleVisitor'
import { ExportMap } from '../export-map'
import { isExternalModule } from '../core/import-type'
import { moduleVisitor, makeOptionsSchema } from '../utils/module-visitor'
import { docsUrl } from '../docs-url'

const traversed = new Set()
Expand Down
Loading

0 comments on commit dc3d48b

Please sign in to comment.