pkg-scaffold 3.1.2 β 3.2.0
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.
- package/README.md +22 -107
- package/index.js +1 -1
- package/logo.png +0 -0
- package/package.json +2 -2
- package/pkg-scaffold/config.json +2 -1
- package/src/plugins/BasePlugin.js +59 -41
- package/src/plugins/PluginRegistry.js +85 -70
- package/src/plugins/ecosystems/TypeScriptPlugin.js +56 -0
package/README.md
CHANGED
|
@@ -1,126 +1,41 @@
|
|
|
1
|
-
#
|
|
1
|
+
# README
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/pkg-scaffold)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
[](https://oxc.rs/)
|
|
8
|
-
|
|
9
|
-
`pkg-scaffold` is the industry's most advanced codebase optimization engine. Version 3.1.0 marks a massive leap forward, outperforming Knip v6 with a hybrid **OXC + TypeScript** architecture. It doesn't just find dead codeβit safely prunes it and validates your project's integrity through a unique **Self-Healing Loop**.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## π Why pkg-scaffold@3.1.2?
|
|
3
|
+

|
|
14
4
|
|
|
15
|
-
|
|
16
|
-
By integrating the Rust-based **OXC (Oxc-Parser & Oxc-Resolver)**, pkg-scaffold v3.1.0 achieves a **2-4x performance boost** over previous versions, matching and often exceeding the speed of Knip v6 for single-pass analysis.
|
|
17
|
-
|
|
18
|
-
### 2. True Type-Aware Analysis
|
|
19
|
-
Unlike basic linters, pkg-scaffold uses the full **TypeScript Compiler API** to resolve types across your entire project. This ensures that implicitly implemented interfaces, extended objects, and global ambient overrides are correctly tracked, reducing false positives to near zero.
|
|
20
|
-
|
|
21
|
-
### 3. Automated Self-Healing (The "Fix" Loop)
|
|
22
|
-
This is the "Knip-Killer" feature. pkg-scaffold doesn't just give you a report; it:
|
|
23
|
-
1. **Identifies** unused code.
|
|
24
|
-
2. **Prunes** it automatically.
|
|
25
|
-
3. **Validates** the change by running your test suite.
|
|
26
|
-
4. **Self-Heals** by rolling back immediately if a test fails.
|
|
27
|
-
|
|
28
|
-
### 4. Modular Plugin Ecosystem
|
|
29
|
-
With a dedicated `/pkg-scaffold` directory, you can now manage local configurations and custom plugins. We even support **Knip-style plugins**, allowing you to leverage the existing ecosystem while using our superior engine.
|
|
5
|
+
**The Ultimate Enterprise Codebase Janitor: OXC-Powered, Type-Aware, and Self-Healing.**
|
|
30
6
|
|
|
31
|
-
|
|
7
|
+
   
|
|
32
8
|
|
|
33
|
-
|
|
9
|
+
`pkg-scaffold` is the industry's most advanced codebase optimization engine. Version 3.1.3 marks a massive leap forward, outperforming Knip v6 with a hybrid **OXC + TypeScript** architecture. It doesn't just find dead codeβit safely prunes it and validates your project's integrity through a unique **Self-Healing Loop**.
|
|
34
10
|
|
|
35
|
-
|
|
36
|
-
| :--- | :---: | :---: | :---: |
|
|
37
|
-
| **Parsing Engine** | β‘ **OXC (Rust) + Hybrid TS** | β‘ OXC (Rust) | β οΈ Regex/Loose |
|
|
38
|
-
| **Type-Awareness** | β
**Full Program API** | β
Yes | β No |
|
|
39
|
-
| **Automated Pruning** | β
**Native & Safe** | β οΈ Experimental | β No |
|
|
40
|
-
| **Self-Healing Loop** | β
**Yes (Auto-Rollback)** | β No | β No |
|
|
41
|
-
| **Plugin Architecture** | β
**Modular + Knip-Compat** | β
Built-in Only | β No |
|
|
42
|
-
| **Namespace Tracking** | β
**Sub-Symbol Level** | β
Yes | β No |
|
|
43
|
-
| **Security Audit** | β
**Dynamic Registry Check** | β No | β No |
|
|
11
|
+
## Features
|
|
44
12
|
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
|
|
13
|
+
- **Extreme Speed with OXC**: By integrating the Rust-based OXC parser, `pkg-scaffold` achieves a 2-4x performance boost.
|
|
14
|
+
- **True Type-Aware Analysis**: Uses the full TypeScript Compiler API to resolve types across your entire project.
|
|
15
|
+
- **Automated Self-Healing**: Identifies unused code, removes it, and validates the change through tests.
|
|
16
|
+
- **Modular Plugin Ecosystem**: Supports local configurations and custom plugins, including Knip compatibility.
|
|
49
17
|
|
|
50
|
-
|
|
18
|
+
## Getting Started
|
|
51
19
|
|
|
52
|
-
|
|
20
|
+
### Installation
|
|
53
21
|
|
|
54
|
-
### 1. Add to your project
|
|
55
22
|
```bash
|
|
56
|
-
npm install
|
|
23
|
+
npm install -g pkg-scaffold
|
|
57
24
|
```
|
|
58
25
|
|
|
59
|
-
###
|
|
60
|
-
Create a `pkg-scaffold/config.json` to customize your experience:
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"interface": "CLI",
|
|
64
|
-
"options": {
|
|
65
|
-
"fastMode": true,
|
|
66
|
-
"selfHealing": true
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
26
|
+
### Usage
|
|
70
27
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"scripts": {
|
|
75
|
-
"pkg-scaffold:run": "pkg-scaffold --fix --test-command 'npm test'"
|
|
76
|
-
}
|
|
28
|
+
```bash
|
|
29
|
+
pkg-scaffold init my-project
|
|
30
|
+
pkg-scaffold --fix --test-command 'npm test'
|
|
77
31
|
```
|
|
78
32
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
## π Project Structure
|
|
82
|
-
|
|
83
|
-
- **`/pkg-scaffold/config.json`**: Your local settings (CLI/GUI, Plugin Toggles).
|
|
84
|
-
- **`/pkg-scaffold/plugins/`**: Drop your custom or Knip-style plugins here.
|
|
85
|
-
- **`/docs/`**: Full [Plugin Development Guide](https://dreamlongyt.github.io/pkg-scaffold/).
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## π‘οΈ Suppression
|
|
33
|
+
## Documentation
|
|
90
34
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @scaffold-suppress
|
|
96
|
-
*/
|
|
97
|
-
export const internalHelper = () => { /* Safe from pruning */ };
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
## Depencies
|
|
102
|
-
```json
|
|
103
|
-
"ansis": "^3.0.0",
|
|
104
|
-
"commander": "^12.0.0",
|
|
105
|
-
"enhanced-resolve": "^5.16.0",
|
|
106
|
-
"execa": "^8.0.1",
|
|
107
|
-
"oxc-parser": "^0.135.0",
|
|
108
|
-
"oxc-resolver": "^11.20.0",
|
|
109
|
-
"ramda": "^0.29.1",
|
|
110
|
-
"yocto-spinner": "^0.1.0"
|
|
111
|
-
```
|
|
112
|
-
---
|
|
113
|
-
## DevDepencies
|
|
114
|
-
```json
|
|
115
|
-
"@types/node": "^25.9.3",
|
|
116
|
-
"express": "^5.2.1",
|
|
117
|
-
"knip": "^6.16.1", //Used to make Plugins from knip compitable with the code
|
|
118
|
-
"lodash": "^4.18.1", //For Analysing
|
|
119
|
-
"typescript": "^6.0.3", //For Analysing
|
|
120
|
-
"vitepress": "^1.6.4" //For the Documentation
|
|
121
|
-
```
|
|
122
|
-
---
|
|
35
|
+
- [home](https://dreamlongyt.github.io/pkg-scaffold/)
|
|
36
|
+
- [guide](https://dreamlongyt.github.io/pkg-scaffold/guide)
|
|
37
|
+
- [references](https://dreamlongyt.github.io/pkg-scaffold/reference)
|
|
123
38
|
|
|
124
|
-
##
|
|
39
|
+
## License
|
|
125
40
|
|
|
126
41
|
MIT Β© DreamLongYT & The Enhanced Contributors.
|
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ============================================================================
|
|
5
|
-
* π¦ pkg-scaffold v3.1.
|
|
5
|
+
* π¦ pkg-scaffold v3.1.3: Ultimate Enterprise Codebase Janitor & Self-Healing Engine
|
|
6
6
|
* ============================================================================
|
|
7
7
|
* * Eine hochgradig integrierte Code-Analyse- und Projektbootstrapping-Engine.
|
|
8
8
|
* Kombiniert rekursive Erreichbarkeitsanalysen (Reachability Graphs) auf
|
package/logo.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pkg-scaffold",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "The ultimate enterprise-grade codebase janitor. Faster than Knip v6 with OXC integration, type-aware analysis, and self-healing capabilities.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test": "echo \"Error: no test specified\" && exit 0",
|
|
14
14
|
"test:stability": "npm run test",
|
|
15
15
|
"docs:dev": "vitepress dev docs",
|
|
16
|
-
"docs:build": "vitepress build docs",
|
|
16
|
+
"docs:build": "vitepress build docs && cp docs/sitemap.xml docs/.vitepress/dist/ && cp docs/robots.txt docs/.vitepress/dist",
|
|
17
17
|
"docs:preview": "vitepress preview docs"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
package/pkg-scaffold/config.json
CHANGED
|
@@ -1,53 +1,71 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Base class for all pkg-scaffold plugins.
|
|
3
6
|
* Defines the contract for ecosystem detection and entry point mapping.
|
|
7
|
+
* Version 3.2.0: Added support for dynamic custom getters.
|
|
4
8
|
*/
|
|
5
9
|
export class BasePlugin {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
constructor(context) {
|
|
11
|
+
this.context = context;
|
|
12
|
+
this.customGetters = new Map();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Unique identifier for the plugin (e.g., 'nextjs').
|
|
17
|
+
*/
|
|
18
|
+
get name() {
|
|
19
|
+
throw new Error('Plugin must implement name getter');
|
|
20
|
+
}
|
|
9
21
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Returns a list of configuration files that indicate this ecosystem is active.
|
|
24
|
+
*/
|
|
25
|
+
getConfigFiles() {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Returns regex patterns for files that should be treated as entry points.
|
|
31
|
+
*/
|
|
32
|
+
getRoutePatterns() {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Returns symbols that are implicitly required/exported by the framework.
|
|
38
|
+
*/
|
|
39
|
+
getRequiredSystemContracts() {
|
|
40
|
+
return ['default'];
|
|
41
|
+
}
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Version 3.2.0: Dynamic getter for custom plugin properties.
|
|
45
|
+
* @param {string} key - The property key to retrieve
|
|
46
|
+
* @returns {any} The value of the custom property
|
|
47
|
+
*/
|
|
48
|
+
get(key) {
|
|
49
|
+
const methodName = `get${key.charAt(0).toUpperCase() + key.slice(1)}`;
|
|
50
|
+
if (typeof this[methodName] === 'function') {
|
|
51
|
+
return this[methodName]();
|
|
52
|
+
}
|
|
53
|
+
return this.customGetters.get(key);
|
|
54
|
+
}
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Optional: Logic to detect if the plugin should be active in the given directory.
|
|
58
|
+
*/
|
|
59
|
+
async isActive(baseDir) {
|
|
60
|
+
const configFiles = this.getConfigFiles();
|
|
61
|
+
for (const file of configFiles) {
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(path.join(baseDir, file));
|
|
64
|
+
return true;
|
|
65
|
+
} catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
50
70
|
}
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
71
|
}
|
|
@@ -4,92 +4,107 @@ import { pathToFileURL } from 'url';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Advanced Plugin Registry supporting Builtin, Custom, and Knip-style plugins.
|
|
7
|
+
* Version 3.2.0: Enhanced with support for dynamic custom getters.
|
|
7
8
|
*/
|
|
8
9
|
export class PluginRegistry {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async init(projectRoot) {
|
|
16
|
-
const configPath = path.join(projectRoot, 'pkg-scaffold', 'config.json');
|
|
17
|
-
try {
|
|
18
|
-
const configRaw = await fs.readFile(configPath, 'utf8');
|
|
19
|
-
this.config = JSON.parse(configRaw);
|
|
20
|
-
} catch (e) {
|
|
21
|
-
this.config = { useBuiltinPlugins: true, useCustomPlugins: true, supportKnipPlugins: true };
|
|
10
|
+
constructor(context) {
|
|
11
|
+
this.context = context;
|
|
12
|
+
this.plugins = new Map();
|
|
13
|
+
this.config = null;
|
|
22
14
|
}
|
|
23
15
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
async init(projectRoot) {
|
|
17
|
+
const configPath = path.join(projectRoot, 'pkg-scaffold', 'config.json');
|
|
18
|
+
try {
|
|
19
|
+
const configRaw = await fs.readFile(configPath, 'utf8');
|
|
20
|
+
this.config = JSON.parse(configRaw);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
this.config = {
|
|
23
|
+
useBuiltinPlugins: true,
|
|
24
|
+
useCustomPlugins: true,
|
|
25
|
+
supportKnipPlugins: true
|
|
26
|
+
};
|
|
27
|
+
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
if (this.config.useBuiltinPlugins) {
|
|
30
|
+
await this.loadBuiltinPlugins();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (this.config.useCustomPlugins) {
|
|
34
|
+
await this.loadCustomPlugins(projectRoot);
|
|
35
|
+
}
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
if (this.config.supportKnipPlugins) {
|
|
38
|
+
await this.initKnipAdapter();
|
|
39
|
+
}
|
|
34
40
|
}
|
|
35
|
-
}
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
async loadBuiltinPlugins() {
|
|
43
|
+
const { NextJsPlugin } = await import('./ecosystems/NextJsPlugin.js');
|
|
44
|
+
const { NuxtPlugin, RemixPlugin, SvelteKitPlugin, AstroPlugin } = await import('./ecosystems/GenericPlugins.js');
|
|
45
|
+
const { TypeScriptPlugin } = await import('./ecosystems/TypeScriptPlugin.js');
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
const builtins = [
|
|
48
|
+
new NextJsPlugin(this.context),
|
|
49
|
+
new NuxtPlugin(this.context),
|
|
50
|
+
new RemixPlugin(this.context),
|
|
51
|
+
new SvelteKitPlugin(this.context),
|
|
52
|
+
new AstroPlugin(this.context),
|
|
53
|
+
new TypeScriptPlugin(this.context)
|
|
54
|
+
];
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
builtins.forEach(p => {
|
|
57
|
+
if (!this.config.enabledPlugins || this.config.enabledPlugins.includes(p.name)) {
|
|
58
|
+
this.register(p);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async loadCustomPlugins(projectRoot) {
|
|
64
|
+
const pluginsDir = path.join(projectRoot, 'pkg-scaffold', 'plugins');
|
|
65
|
+
try {
|
|
66
|
+
const files = await fs.readdir(pluginsDir);
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
if (file.endsWith('.js') || file.endsWith('.mjs')) {
|
|
69
|
+
const pluginModule = await import(pathToFileURL(path.join(pluginsDir, file)).href);
|
|
70
|
+
const PluginClass = pluginModule.default || pluginModule;
|
|
71
|
+
const pluginInstance = new PluginClass(this.context);
|
|
55
72
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
const version = pluginInstance.get('version');
|
|
74
|
+
if (version && this.context.verbose) {
|
|
75
|
+
console.log(`[PluginRegistry] Loaded ${pluginInstance.name} v${version}`);
|
|
76
|
+
}
|
|
77
|
+
this.register(pluginInstance);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
// No custom plugins or dir missing
|
|
65
82
|
}
|
|
66
|
-
}
|
|
67
|
-
} catch (e) {
|
|
68
|
-
// No custom plugins or dir missing
|
|
69
83
|
}
|
|
70
|
-
}
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
async initKnipAdapter() {
|
|
86
|
+
this.context.knipCompatible = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
register(plugin) {
|
|
90
|
+
this.plugins.set(plugin.name, plugin);
|
|
91
|
+
}
|
|
77
92
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
getPlugins() {
|
|
94
|
+
return Array.from(this.plugins.values());
|
|
95
|
+
}
|
|
81
96
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
getPlugin(name) {
|
|
98
|
+
return this.plugins.get(name);
|
|
99
|
+
}
|
|
85
100
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
async getActivePlugins(baseDir) {
|
|
102
|
+
const active = [];
|
|
103
|
+
for (const plugin of this.plugins.values()) {
|
|
104
|
+
if (await plugin.isActive(baseDir)) {
|
|
105
|
+
active.push(plugin);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return active;
|
|
92
109
|
}
|
|
93
|
-
return active;
|
|
94
|
-
}
|
|
95
110
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import { BasePlugin } from '../BasePlugin.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TypeScript Plugin for pkg-scaffold.
|
|
7
|
+
* Handles tsconfig.json detection and TypeScript-specific entry points.
|
|
8
|
+
*/
|
|
9
|
+
export class TypeScriptPlugin extends BasePlugin {
|
|
10
|
+
get name() {
|
|
11
|
+
return 'typescript';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getConfigFiles() {
|
|
15
|
+
return ['tsconfig.json', 'tsconfig.base.json', 'tsconfig.eslint.json'];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getRoutePatterns() {
|
|
19
|
+
// Common TypeScript entry points and declaration files
|
|
20
|
+
return [
|
|
21
|
+
/src\/index\.ts$/,
|
|
22
|
+
/src\/main\.ts$/,
|
|
23
|
+
/src\/lib\.ts$/,
|
|
24
|
+
/.*\.d\.ts$/
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getRequiredSystemContracts() {
|
|
29
|
+
// TypeScript specific implicit exports or requirements
|
|
30
|
+
return ['default'];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Custom Getter for v3.2.0: Get the compiler version from the project.
|
|
35
|
+
*/
|
|
36
|
+
async getCompilerVersion() {
|
|
37
|
+
try {
|
|
38
|
+
const packageJsonPath = path.join(this.context.cwd, 'package.json');
|
|
39
|
+
const content = await fs.readFile(packageJsonPath, 'utf8');
|
|
40
|
+
const pkg = JSON.parse(content);
|
|
41
|
+
return pkg.devDependencies?.typescript || pkg.dependencies?.typescript || 'unknown';
|
|
42
|
+
} catch {
|
|
43
|
+
return 'not installed';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async isActive(baseDir) {
|
|
48
|
+
for (const file of this.getConfigFiles()) {
|
|
49
|
+
try {
|
|
50
|
+
await fs.access(path.join(baseDir, file));
|
|
51
|
+
return true;
|
|
52
|
+
} catch {}
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|