Skip to content

Commit f883516

Browse files
fix: do not apply typescript preset without tsconfig (#89)
1 parent 9ceacfe commit f883516

File tree

6 files changed

+1132
-1551
lines changed

6 files changed

+1132
-1551
lines changed

configs.js

Lines changed: 7 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,11 @@
1-
import fs from "node:fs";
2-
import path from "node:path";
31
import { globalIgnores } from "eslint/config";
42
import semver from "semver";
53
import configs from "./configs/index.js";
64
import { typescriptExtensions } from "./configs/utils/extensions.js";
5+
import getJsonFile from "./configs/utils/get-json-file.js";
6+
import isTypescriptInstalled from "./configs/utils/is-typescript-installed.js";
77
import ignorePaths from "./ignore-paths.js";
88

9-
const SKIP_TIME = 5000;
10-
11-
class Cache {
12-
/**
13-
* Initialize this cache instance.
14-
*/
15-
constructor() {
16-
this.map = new Map();
17-
}
18-
19-
/**
20-
* Get the cached value of the given key.
21-
* @param {string} key The key to get.
22-
* @returns {import('type-fest').JsonObject} The cached value or null.
23-
*/
24-
get(key) {
25-
const entry = this.map.get(key);
26-
const now = Date.now();
27-
28-
if (entry) {
29-
if (entry.expire > now) {
30-
entry.expire = now + SKIP_TIME;
31-
return entry.value;
32-
}
33-
this.map.delete(key);
34-
}
35-
return null;
36-
}
37-
38-
/**
39-
* Set the value of the given key.
40-
* @param {string} key The key to set.
41-
* @param {import('type-fest').JsonObject} value The value to set.
42-
* @returns {void}
43-
*/
44-
set(key, value) {
45-
const entry = this.map.get(key);
46-
const expire = Date.now() + SKIP_TIME;
47-
48-
if (entry) {
49-
entry.value = value;
50-
entry.expire = expire;
51-
} else {
52-
this.map.set(key, { value, expire });
53-
}
54-
}
55-
}
56-
57-
const cache = new Cache();
58-
59-
/**
60-
* Reads the `package.json` data in a given path.
61-
*
62-
* Don't cache the data.
63-
* @param {string} dir The path to a directory to read.
64-
* @param {string} filename The filename.
65-
* @returns {import('type-fest').JsonObject|null} The read `package.json` data, or null.
66-
*/
67-
function readJsonFile(dir, filename) {
68-
const filePath = path.join(dir, filename);
69-
try {
70-
const text = fs.readFileSync(filePath, "utf8");
71-
const data = JSON.parse(text);
72-
73-
if (
74-
data !== null &&
75-
typeof data === "object" &&
76-
Array.isArray(data) === false
77-
) {
78-
data.filePath = filePath;
79-
return data;
80-
}
81-
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
82-
} catch (_err) {
83-
// do nothing.
84-
}
85-
86-
return null;
87-
}
88-
89-
/**
90-
* Gets a `package.json` data.
91-
* The data is cached if found, then it's used after.
92-
* @param {string} filename The filename.
93-
* @param {string=} startPath A file path to lookup.
94-
* @returns {import('type-fest').JsonObject | null} A found `package.json` data or `null`.
95-
* This object have additional property `filePath`.
96-
*/
97-
function getJsonFile(filename, startPath = "a.js") {
98-
const startDir = path.dirname(path.resolve(startPath));
99-
let dir = startDir;
100-
let prevDir = "";
101-
let data = null;
102-
103-
do {
104-
data = cache.get(dir + filename);
105-
if (data) {
106-
if (dir !== startDir) {
107-
cache.set(startDir + filename, data);
108-
}
109-
return data;
110-
}
111-
112-
data = readJsonFile(dir, filename);
113-
if (data) {
114-
cache.set(dir + filename, data);
115-
cache.set(startDir + filename, data);
116-
return data;
117-
}
118-
119-
// Go to next.
120-
prevDir = dir;
121-
dir = path.resolve(dir, "..");
122-
} while (dir !== prevDir);
123-
124-
cache.set(startDir + filename, null);
125-
return null;
126-
}
127-
1289
const packageJson = getJsonFile("package.json");
12910
const isModule =
13011
packageJson !== null &&
@@ -199,23 +80,17 @@ function getJavascriptConfig() {
19980
* @returns {Promise<Record<string, string>>} config
20081
*/
20182
function getTypescriptJSdocConfig() {
202-
if (packageJson === null) {
203-
return [];
204-
}
205-
206-
const dependencies = packageJson.dependencies || [];
207-
const devDependencies = packageJson.devDependencies || [];
208-
209-
return typeof dependencies.typescript !== "undefined" ||
210-
typeof devDependencies.typescript !== "undefined"
211-
? configs["typescript/jsdoc"]
212-
: [];
83+
return isTypescriptInstalled() ? configs["typescript/jsdoc"] : [];
21384
}
21485

21586
/**
21687
* @returns {Promise<Record<string, string>>} config
21788
*/
21889
function getTypescriptConfig() {
90+
if (!isTypescriptInstalled()) {
91+
return {};
92+
}
93+
21994
const tsconfigJson = getJsonFile("tsconfig.json");
22095

22196
const isNoEmitEnabled =

configs/markdown.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import isTypescriptInstalled from "./utils/is-typescript-installed.js";
2+
13
/**
24
* @returns {Promise<Record<string, string>>} config
35
*/
@@ -22,7 +24,9 @@ async function getMarkdownRecommendedConfig() {
2224
},
2325
{
2426
name: "markdown/code-blocks/js",
25-
files: ["**/*.md/*.js", "**/*.md/*.ts"],
27+
files: isTypescriptInstalled
28+
? ["**/*.md/*.js", "**/*.md/*.ts"]
29+
: ["**/*.md/*.js"],
2630
languageOptions: {
2731
sourceType: "module",
2832
ecmaVersion: "latest",

configs/utils/get-json-file.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import fs from "node:fs";
2+
import path from "node:path";
3+
4+
const SKIP_TIME = 5000;
5+
6+
class Cache {
7+
/**
8+
* Initialize this cache instance.
9+
*/
10+
constructor() {
11+
this.map = new Map();
12+
}
13+
14+
/**
15+
* Get the cached value of the given key.
16+
* @param {string} key The key to get.
17+
* @returns {import('type-fest').JsonObject} The cached value or null.
18+
*/
19+
get(key) {
20+
const entry = this.map.get(key);
21+
const now = Date.now();
22+
23+
if (entry) {
24+
if (entry.expire > now) {
25+
entry.expire = now + SKIP_TIME;
26+
return entry.value;
27+
}
28+
this.map.delete(key);
29+
}
30+
return null;
31+
}
32+
33+
/**
34+
* Set the value of the given key.
35+
* @param {string} key The key to set.
36+
* @param {import('type-fest').JsonObject} value The value to set.
37+
* @returns {void}
38+
*/
39+
set(key, value) {
40+
const entry = this.map.get(key);
41+
const expire = Date.now() + SKIP_TIME;
42+
43+
if (entry) {
44+
entry.value = value;
45+
entry.expire = expire;
46+
} else {
47+
this.map.set(key, { value, expire });
48+
}
49+
}
50+
}
51+
52+
const cache = new Cache();
53+
54+
/**
55+
* Reads the `package.json` data in a given path.
56+
*
57+
* Don't cache the data.
58+
* @param {string} dir The path to a directory to read.
59+
* @param {string} filename The filename.
60+
* @returns {import('type-fest').JsonObject|null} The read `package.json` data, or null.
61+
*/
62+
function readJsonFile(dir, filename) {
63+
const filePath = path.join(dir, filename);
64+
try {
65+
const text = fs.readFileSync(filePath, "utf8");
66+
const data = JSON.parse(text);
67+
68+
if (
69+
data !== null &&
70+
typeof data === "object" &&
71+
Array.isArray(data) === false
72+
) {
73+
data.filePath = filePath;
74+
return data;
75+
}
76+
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
77+
} catch (_err) {
78+
// do nothing.
79+
}
80+
81+
return null;
82+
}
83+
84+
/**
85+
* Gets a `package.json` data.
86+
* The data is cached if found, then it's used after.
87+
* @param {string} filename The filename.
88+
* @param {string=} startPath A file path to lookup.
89+
* @returns {import('type-fest').JsonObject | null} A found `package.json` data or `null`.
90+
* This object have additional property `filePath`.
91+
*/
92+
function getJsonFile(filename, startPath = "a.js") {
93+
const startDir = path.dirname(path.resolve(startPath));
94+
let dir = startDir;
95+
let prevDir = "";
96+
let data = null;
97+
98+
do {
99+
data = cache.get(dir + filename);
100+
if (data) {
101+
if (dir !== startDir) {
102+
cache.set(startDir + filename, data);
103+
}
104+
return data;
105+
}
106+
107+
data = readJsonFile(dir, filename);
108+
if (data) {
109+
cache.set(dir + filename, data);
110+
cache.set(startDir + filename, data);
111+
return data;
112+
}
113+
114+
// Go to next.
115+
prevDir = dir;
116+
dir = path.resolve(dir, "..");
117+
} while (dir !== prevDir);
118+
119+
cache.set(startDir + filename, null);
120+
return null;
121+
}
122+
123+
export default getJsonFile;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import getJsonFile from "./get-json-file.js";
2+
3+
/**
4+
* @returns {boolean} true when typescript is supported by project, otherwise false
5+
*/
6+
function isTypescriptInstalled() {
7+
const packageJson = getJsonFile("package.json");
8+
9+
if (packageJson === null) {
10+
return [];
11+
}
12+
13+
const dependencies = packageJson.dependencies || [];
14+
const devDependencies = packageJson.devDependencies || [];
15+
16+
return Boolean(
17+
typeof dependencies.typescript !== "undefined" ||
18+
typeof devDependencies.typescript !== "undefined",
19+
);
20+
}
21+
22+
export default isTypescriptInstalled;

0 commit comments

Comments
 (0)