Skip to content

Commit

Permalink
feat: Export the moduleType from ImportTarget (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
scagood committed Nov 7, 2023
1 parent 79c8afd commit ff01930
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
15 changes: 6 additions & 9 deletions lib/rules/file-extension-in-import.js
Expand Up @@ -8,9 +8,6 @@ const path = require("path")
const fs = require("fs")
const mapTypescriptExtension = require("../util/map-typescript-extension")
const visitImport = require("../util/visit-import")
const packageNamePattern = /^(?:@[^/\\]+[/\\])?[^/\\]+$/u
const corePackageOverridePattern =
/^(?:assert|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|http2|https|inspector|module|net|os|path|perf_hooks|process|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|trace_events|tty|url|util|v8|vm|worker_threads|zlib)[/\\]$/u

/**
* Get all file extensions of the files which have the same basename.
Expand Down Expand Up @@ -67,13 +64,13 @@ module.exports = {
const defaultStyle = context.options[0] || "always"
const overrideStyle = context.options[1] || {}

function verify({ filePath, name, node }) {
/**
* @param {import("../util/import-target.js")} target
* @returns {void}
*/
function verify({ filePath, name, node, moduleType }) {
// Ignore if it's not resolved to a file or it's a bare module.
if (
!filePath ||
packageNamePattern.test(name) ||
corePackageOverridePattern.test(name)
) {
if (moduleType !== "relative" && moduleType !== "absolute") {
return
}

Expand Down
27 changes: 27 additions & 0 deletions lib/util/import-target.js
Expand Up @@ -6,6 +6,7 @@

const path = require("path")
const { pathToFileURL, fileURLToPath } = require("url")
const { isBuiltin } = require("module")
const resolve = require("resolve")
const {
defaultResolve: importResolve,
Expand Down Expand Up @@ -72,6 +73,14 @@ function getFilePath(isModule, id, options, moduleType) {
}
}

function isNodeModule(name, options) {
try {
return require.resolve(name, options).startsWith(path.sep)
} catch {
return false
}
}

/**
* Gets the module name of a given path.
*
Expand Down Expand Up @@ -115,6 +124,24 @@ module.exports = class ImportTarget {
*/
this.name = name

/**
* What type of module is this
* @type {'unknown'|'relative'|'absolute'|'node'|'npm'|'http'|void}
*/
this.moduleType = "unknown"

if (name.startsWith("./") || name.startsWith(".\\")) {
this.moduleType = "relative"
} else if (name.startsWith("/") || name.startsWith("\\")) {
this.moduleType = "absolute"
} else if (isBuiltin(name)) {
this.moduleType = "node"
} else if (isNodeModule(name, options)) {
this.moduleType = "npm"
} else if (name.startsWith("http://") || name.startsWith("https://")) {
this.moduleType = "http"
}

/**
* The full path of this import target.
* If the target is a module and it does not exist then this is `null`.
Expand Down
17 changes: 17 additions & 0 deletions tests/lib/rules/file-extension-in-import.js
Expand Up @@ -155,6 +155,23 @@ new RuleTester({
options: ["never", { ".json": "always" }],
},

// Ignore sub-paths of modules
{
filename: fixture("test.js"),
code: "import '@apollo/client/core'",
options: ["always"],
},
{
filename: fixture("test.js"),
code: "import 'yargs/helpers'",
options: ["always"],
},
{
filename: fixture("test.js"),
code: "import 'firebase-functions/v1/auth'",
options: ["always"],
},

// typescriptExtensionMap
{
filename: fixture("test.tsx"),
Expand Down

0 comments on commit ff01930

Please sign in to comment.