Skip to content

Commit d68a1cf

Browse files
committed
chore: utilize
1 parent 5353b32 commit d68a1cf

File tree

5 files changed

+209
-86
lines changed

5 files changed

+209
-86
lines changed

src/rules/kit-helpers/kit-helpers.ts

-84
This file was deleted.

src/rules/no-export-load-in-svelte-module-in-kit-pages.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type * as ESTree from "estree"
22
import { createRule } from "../utils"
3-
import { isKitPageComponent, hasSvelteKit } from "./kit-helpers/kit-helpers"
3+
import { isKitPageComponent, hasSvelteKit } from "../utils/svelte-kit"
44

55
export default createRule("no-export-load-in-svelte-module-in-kit-pages", {
66
meta: {
@@ -19,7 +19,9 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", {
1919
type: "problem",
2020
},
2121
create(context) {
22-
if (!hasSvelteKit || !isKitPageComponent(context)) return {}
22+
if (!hasSvelteKit(context.getFilename()) || !isKitPageComponent(context)) {
23+
return {}
24+
}
2325
let isModule = false
2426
return {
2527
// <script context="module">

src/utils/cache.ts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Simple cache manager.
3+
*
4+
* refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/cache.js
5+
*/
6+
7+
const SKIP_TIME = 5000
8+
9+
type CacheValue<T> = {
10+
expire: number
11+
value: T
12+
}
13+
14+
/**
15+
* The cache will dispose of each value if the value has not been accessed
16+
* during 5 seconds.
17+
* @returns getter and setter ofr the cache.
18+
*/
19+
export function createCache<T>(): {
20+
get: (key: string) => T | null
21+
set: (key: string, value: T) => void
22+
} {
23+
const map: Map<string, CacheValue<T>> = new Map()
24+
25+
/**
26+
* Get the cached value of the given key.
27+
* @param key The key to get.
28+
* @returns The cached value or null.
29+
*/
30+
function get(key: string): T | null {
31+
const entry = map.get(key)
32+
const now = Date.now()
33+
34+
if (entry) {
35+
if (entry.expire > now) {
36+
entry.expire = now + SKIP_TIME
37+
return entry.value
38+
}
39+
map.delete(key)
40+
}
41+
return null
42+
}
43+
44+
/**
45+
* Set the value of the given key.
46+
* @param key The key to set.
47+
* @param value The value to set.
48+
* @returns
49+
*/
50+
function set(key: string, value: T): void {
51+
const entry = map.get(key)
52+
const expire = Date.now() + SKIP_TIME
53+
54+
if (entry) {
55+
entry.value = value
56+
entry.expire = expire
57+
} else {
58+
map.set(key, { value, expire })
59+
}
60+
}
61+
62+
return { get, set }
63+
}

src/utils/get-package-json.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/get-package-json.js
3+
*/
4+
5+
import fs from "fs"
6+
import path from "path"
7+
import { createCache } from "./cache"
8+
9+
type PackageJson = Record<string, any> & { filePath: string }
10+
11+
const isRunOnBrowser = !fs.readFileSync
12+
const cache = createCache<PackageJson | null>()
13+
14+
/**
15+
* Reads the `package.json` data in a given path.
16+
*
17+
* Don't cache the data.
18+
*
19+
* @param dir The path to a directory to read.
20+
* @returns The read `package.json` data, or null.
21+
*/
22+
function readPackageJson(dir: string): PackageJson | null {
23+
if (isRunOnBrowser) return null
24+
const filePath = path.join(dir, "package.json")
25+
try {
26+
const text = fs.readFileSync(filePath, "utf8")
27+
const data = JSON.parse(text)
28+
29+
if (typeof data === "object" && data !== null) {
30+
data.filePath = filePath
31+
return data
32+
}
33+
} catch (_err) {
34+
// do nothing.
35+
}
36+
37+
return null
38+
}
39+
40+
/**
41+
* Gets a `package.json` data.
42+
* The data is cached if found, then it's used after.
43+
* @param startPath A file path to lookup.
44+
* @returns A found `package.json` data or `null`.
45+
* This object have additional property `filePath`.
46+
*/
47+
export function getPackageJson(startPath = "a.js"): PackageJson | null {
48+
if (isRunOnBrowser) return null
49+
const startDir = path.dirname(path.resolve(startPath))
50+
let dir = startDir
51+
let prevDir = ""
52+
let data = null
53+
54+
do {
55+
data = cache.get(dir)
56+
if (data) {
57+
if (dir !== startDir) {
58+
cache.set(startDir, data)
59+
}
60+
return data
61+
}
62+
63+
data = readPackageJson(dir)
64+
if (data) {
65+
cache.set(dir, data)
66+
cache.set(startDir, data)
67+
return data
68+
}
69+
70+
// Go to next.
71+
prevDir = dir
72+
dir = path.resolve(dir, "..")
73+
} while (dir !== prevDir)
74+
75+
cache.set(startDir, null)
76+
return null
77+
}

src/utils/svelte-kit.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/get-package-json.js
3+
*/
4+
5+
import type { RuleContext } from "../types"
6+
import fs from "fs"
7+
import path from "path"
8+
import { getPackageJson } from "./get-package-json"
9+
10+
const isRunOnBrowser = !fs.readFileSync
11+
12+
/**
13+
* return true if it's a Svelte Kit page component.
14+
* @param context
15+
* @returns
16+
*/
17+
export function isKitPageComponent(context: RuleContext): boolean {
18+
// Hack: if it runs on browser, it regards as Svelte Kit project.
19+
if (isRunOnBrowser) return true
20+
21+
const routes =
22+
context.settings?.kit?.files?.routes?.replace(/^\//, "") ?? "src/routes"
23+
const filePath = context.getFilename()
24+
const projectRootDir = getProjectRootDir(context.getFilename()) ?? ""
25+
return filePath.startsWith(path.join(projectRootDir, routes))
26+
}
27+
28+
/**
29+
* Check givin file is under SvelteKit project.
30+
*
31+
* If it runs on browser, it always returns true.
32+
*
33+
* @param filePath A file path.
34+
* @returns
35+
*/
36+
export function hasSvelteKit(filePath: string): boolean {
37+
// Hack: if it runs on browser, it regards as Svelte Kit project.
38+
if (isRunOnBrowser) return true
39+
try {
40+
const packageJson = getPackageJson(filePath)
41+
if (!packageJson) return false
42+
if (packageJson.name === "eslint-plugin-svelte")
43+
// Hack: CI removes `@sveltejs/kit` and it returns false and test failed.
44+
// So always it returns true if it runs on the package.
45+
return true
46+
return Boolean(
47+
packageJson.dependencies["@sveltejs/kit"] ??
48+
packageJson.devDependencies["@sveltejs/kit"],
49+
)
50+
} catch (_e) {
51+
return false
52+
}
53+
}
54+
55+
/**
56+
* Gets a project root folder path.
57+
* @param filePath A file path to lookup.
58+
* @returns A found project root folder path or null.
59+
*/
60+
function getProjectRootDir(filePath: string): string | null {
61+
if (isRunOnBrowser) return null
62+
const packageJsonFilePath = getPackageJson(filePath)?.filePath
63+
if (!packageJsonFilePath) return null
64+
return path.dirname(path.resolve(packageJsonFilePath))
65+
}

0 commit comments

Comments
 (0)