@git.zone/tsdoc 1.4.5 → 1.5.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/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/aidocs_classes/commit.js +16 -10
- package/dist_ts/aidocs_classes/description.js +14 -6
- package/dist_ts/aidocs_classes/projectcontext.d.ts +22 -0
- package/dist_ts/aidocs_classes/projectcontext.js +41 -1
- package/dist_ts/aidocs_classes/readme.js +10 -4
- package/dist_ts/classes.aidoc.d.ts +22 -0
- package/dist_ts/classes.aidoc.js +31 -1
- package/dist_ts/cli.js +110 -1
- package/dist_ts/context/config-manager.d.ts +58 -0
- package/dist_ts/context/config-manager.js +183 -0
- package/dist_ts/context/context-trimmer.d.ts +52 -0
- package/dist_ts/context/context-trimmer.js +199 -0
- package/dist_ts/context/enhanced-context.d.ts +75 -0
- package/dist_ts/context/enhanced-context.js +272 -0
- package/dist_ts/context/index.d.ts +7 -0
- package/dist_ts/context/index.js +8 -0
- package/dist_ts/context/task-context-factory.d.ts +46 -0
- package/dist_ts/context/task-context-factory.js +109 -0
- package/dist_ts/context/types.d.ts +89 -0
- package/dist_ts/context/types.js +2 -0
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/npmextra.json +10 -9
- package/package.json +12 -10
- package/readme.md +588 -174
- package/readme.plan.md +314 -0
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/aidocs_classes/commit.ts +21 -9
- package/ts/aidocs_classes/description.ts +16 -5
- package/ts/aidocs_classes/projectcontext.ts +43 -0
- package/ts/aidocs_classes/readme.ts +11 -3
- package/ts/classes.aidoc.ts +33 -0
- package/ts/cli.ts +128 -0
- package/ts/context/config-manager.ts +209 -0
- package/ts/context/context-trimmer.ts +246 -0
- package/ts/context/enhanced-context.ts +343 -0
- package/ts/context/index.ts +32 -0
- package/ts/context/task-context-factory.ts +138 -0
- package/ts/context/types.ts +95 -0
- package/ts/plugins.ts +2 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import type { IContextConfig, ITrimConfig, ITaskConfig, TaskType, ContextMode } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Manages configuration for context building
|
|
6
|
+
*/
|
|
7
|
+
export class ConfigManager {
|
|
8
|
+
private static instance: ConfigManager;
|
|
9
|
+
private config: IContextConfig;
|
|
10
|
+
private projectDir: string = '';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get the singleton instance of ConfigManager
|
|
14
|
+
*/
|
|
15
|
+
public static getInstance(): ConfigManager {
|
|
16
|
+
if (!ConfigManager.instance) {
|
|
17
|
+
ConfigManager.instance = new ConfigManager();
|
|
18
|
+
}
|
|
19
|
+
return ConfigManager.instance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Private constructor for singleton pattern
|
|
24
|
+
*/
|
|
25
|
+
private constructor() {
|
|
26
|
+
this.config = this.getDefaultConfig();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the config manager with a project directory
|
|
31
|
+
* @param projectDir The project directory
|
|
32
|
+
*/
|
|
33
|
+
public async initialize(projectDir: string): Promise<void> {
|
|
34
|
+
this.projectDir = projectDir;
|
|
35
|
+
await this.loadConfig();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get the default configuration
|
|
40
|
+
*/
|
|
41
|
+
private getDefaultConfig(): IContextConfig {
|
|
42
|
+
return {
|
|
43
|
+
maxTokens: 190000, // Default for o4-mini with some buffer
|
|
44
|
+
defaultMode: 'trimmed',
|
|
45
|
+
taskSpecificSettings: {
|
|
46
|
+
readme: {
|
|
47
|
+
mode: 'trimmed',
|
|
48
|
+
includePaths: ['ts/', 'src/'],
|
|
49
|
+
excludePaths: ['test/', 'node_modules/']
|
|
50
|
+
},
|
|
51
|
+
commit: {
|
|
52
|
+
mode: 'trimmed',
|
|
53
|
+
focusOnChangedFiles: true
|
|
54
|
+
},
|
|
55
|
+
description: {
|
|
56
|
+
mode: 'trimmed',
|
|
57
|
+
includePackageInfo: true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
trimming: {
|
|
61
|
+
removeImplementations: true,
|
|
62
|
+
preserveInterfaces: true,
|
|
63
|
+
preserveTypeDefs: true,
|
|
64
|
+
preserveJSDoc: true,
|
|
65
|
+
maxFunctionLines: 5,
|
|
66
|
+
removeComments: true,
|
|
67
|
+
removeBlankLines: true
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Load configuration from npmextra.json
|
|
74
|
+
*/
|
|
75
|
+
private async loadConfig(): Promise<void> {
|
|
76
|
+
try {
|
|
77
|
+
if (!this.projectDir) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Create KeyValueStore for this project
|
|
82
|
+
// We'll just use smartfile directly instead of KeyValueStore
|
|
83
|
+
|
|
84
|
+
// Read the npmextra.json file
|
|
85
|
+
const npmextraJsonFile = await plugins.smartfile.SmartFile.fromFilePath(
|
|
86
|
+
plugins.path.join(this.projectDir, 'npmextra.json')
|
|
87
|
+
);
|
|
88
|
+
const npmextraContent = JSON.parse(npmextraJsonFile.contents.toString());
|
|
89
|
+
|
|
90
|
+
// Check for tsdoc context configuration
|
|
91
|
+
if (npmextraContent?.tsdoc?.context) {
|
|
92
|
+
// Merge with default config
|
|
93
|
+
this.config = this.mergeConfigs(this.config, npmextraContent.tsdoc.context);
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('Error loading context configuration:', error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Merge configurations, with userConfig taking precedence
|
|
102
|
+
* @param defaultConfig The default configuration
|
|
103
|
+
* @param userConfig The user configuration
|
|
104
|
+
*/
|
|
105
|
+
private mergeConfigs(defaultConfig: IContextConfig, userConfig: Partial<IContextConfig>): IContextConfig {
|
|
106
|
+
const result: IContextConfig = { ...defaultConfig };
|
|
107
|
+
|
|
108
|
+
// Merge top-level properties
|
|
109
|
+
if (userConfig.maxTokens !== undefined) result.maxTokens = userConfig.maxTokens;
|
|
110
|
+
if (userConfig.defaultMode !== undefined) result.defaultMode = userConfig.defaultMode;
|
|
111
|
+
|
|
112
|
+
// Merge task-specific settings
|
|
113
|
+
if (userConfig.taskSpecificSettings) {
|
|
114
|
+
result.taskSpecificSettings = result.taskSpecificSettings || {};
|
|
115
|
+
|
|
116
|
+
// For each task type, merge settings
|
|
117
|
+
(['readme', 'commit', 'description'] as TaskType[]).forEach(taskType => {
|
|
118
|
+
if (userConfig.taskSpecificSettings?.[taskType]) {
|
|
119
|
+
result.taskSpecificSettings![taskType] = {
|
|
120
|
+
...result.taskSpecificSettings![taskType],
|
|
121
|
+
...userConfig.taskSpecificSettings[taskType]
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Merge trimming configuration
|
|
128
|
+
if (userConfig.trimming) {
|
|
129
|
+
result.trimming = {
|
|
130
|
+
...result.trimming,
|
|
131
|
+
...userConfig.trimming
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get the complete configuration
|
|
140
|
+
*/
|
|
141
|
+
public getConfig(): IContextConfig {
|
|
142
|
+
return this.config;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get the trimming configuration
|
|
147
|
+
*/
|
|
148
|
+
public getTrimConfig(): ITrimConfig {
|
|
149
|
+
return this.config.trimming || {};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Get configuration for a specific task
|
|
154
|
+
* @param taskType The type of task
|
|
155
|
+
*/
|
|
156
|
+
public getTaskConfig(taskType: TaskType): ITaskConfig {
|
|
157
|
+
// Get task-specific config or empty object
|
|
158
|
+
const taskConfig = this.config.taskSpecificSettings?.[taskType] || {};
|
|
159
|
+
|
|
160
|
+
// If mode is not specified, use default mode
|
|
161
|
+
if (!taskConfig.mode) {
|
|
162
|
+
taskConfig.mode = this.config.defaultMode;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return taskConfig;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get the maximum tokens allowed for context
|
|
170
|
+
*/
|
|
171
|
+
public getMaxTokens(): number {
|
|
172
|
+
return this.config.maxTokens || 190000;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Update the configuration
|
|
177
|
+
* @param config The new configuration
|
|
178
|
+
*/
|
|
179
|
+
public async updateConfig(config: Partial<IContextConfig>): Promise<void> {
|
|
180
|
+
// Merge with existing config
|
|
181
|
+
this.config = this.mergeConfigs(this.config, config);
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
if (!this.projectDir) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Read the existing npmextra.json file
|
|
189
|
+
const npmextraJsonPath = plugins.path.join(this.projectDir, 'npmextra.json');
|
|
190
|
+
let npmextraContent = {};
|
|
191
|
+
|
|
192
|
+
if (await plugins.smartfile.fs.fileExists(npmextraJsonPath)) {
|
|
193
|
+
const npmextraJsonFile = await plugins.smartfile.SmartFile.fromFilePath(npmextraJsonPath);
|
|
194
|
+
npmextraContent = JSON.parse(npmextraJsonFile.contents.toString()) || {};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Update the tsdoc context configuration
|
|
198
|
+
const typedContent = npmextraContent as any;
|
|
199
|
+
if (!typedContent.tsdoc) typedContent.tsdoc = {};
|
|
200
|
+
typedContent.tsdoc.context = this.config;
|
|
201
|
+
|
|
202
|
+
// Write back to npmextra.json
|
|
203
|
+
const updatedContent = JSON.stringify(npmextraContent, null, 2);
|
|
204
|
+
await plugins.smartfile.memory.toFs(updatedContent, npmextraJsonPath);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error('Error updating context configuration:', error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import type { ITrimConfig, ContextMode } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Class responsible for trimming file contents to reduce token usage
|
|
6
|
+
* while preserving important information for context
|
|
7
|
+
*/
|
|
8
|
+
export class ContextTrimmer {
|
|
9
|
+
private config: ITrimConfig;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create a new ContextTrimmer with the given configuration
|
|
13
|
+
* @param config The trimming configuration
|
|
14
|
+
*/
|
|
15
|
+
constructor(config?: ITrimConfig) {
|
|
16
|
+
this.config = {
|
|
17
|
+
removeImplementations: true,
|
|
18
|
+
preserveInterfaces: true,
|
|
19
|
+
preserveTypeDefs: true,
|
|
20
|
+
preserveJSDoc: true,
|
|
21
|
+
maxFunctionLines: 5,
|
|
22
|
+
removeComments: true,
|
|
23
|
+
removeBlankLines: true,
|
|
24
|
+
...config
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Trim a file's contents based on the configuration
|
|
30
|
+
* @param filePath The path to the file
|
|
31
|
+
* @param content The file's contents
|
|
32
|
+
* @param mode The context mode to use
|
|
33
|
+
* @returns The trimmed file contents
|
|
34
|
+
*/
|
|
35
|
+
public trimFile(filePath: string, content: string, mode: ContextMode = 'trimmed'): string {
|
|
36
|
+
// If mode is 'full', return the original content
|
|
37
|
+
if (mode === 'full') {
|
|
38
|
+
return content;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Process based on file type
|
|
42
|
+
if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
|
|
43
|
+
return this.trimTypeScriptFile(content);
|
|
44
|
+
} else if (filePath.endsWith('.md')) {
|
|
45
|
+
return this.trimMarkdownFile(content);
|
|
46
|
+
} else if (filePath.endsWith('.json')) {
|
|
47
|
+
return this.trimJsonFile(content);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Default to returning the original content for unknown file types
|
|
51
|
+
return content;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Trim a TypeScript file to reduce token usage
|
|
56
|
+
* @param content The TypeScript file contents
|
|
57
|
+
* @returns The trimmed file contents
|
|
58
|
+
*/
|
|
59
|
+
private trimTypeScriptFile(content: string): string {
|
|
60
|
+
let result = content;
|
|
61
|
+
|
|
62
|
+
// Step 1: Preserve JSDoc comments if configured
|
|
63
|
+
const jsDocComments: string[] = [];
|
|
64
|
+
if (this.config.preserveJSDoc) {
|
|
65
|
+
const jsDocRegex = /\/\*\*[\s\S]*?\*\//g;
|
|
66
|
+
const matches = result.match(jsDocRegex) || [];
|
|
67
|
+
jsDocComments.push(...matches);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Step 2: Remove comments if configured
|
|
71
|
+
if (this.config.removeComments) {
|
|
72
|
+
// Remove single-line comments
|
|
73
|
+
result = result.replace(/\/\/.*$/gm, '');
|
|
74
|
+
// Remove multi-line comments (except JSDoc if preserveJSDoc is true)
|
|
75
|
+
if (!this.config.preserveJSDoc) {
|
|
76
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
77
|
+
} else {
|
|
78
|
+
// Only remove non-JSDoc comments
|
|
79
|
+
result = result.replace(/\/\*(?!\*)[\s\S]*?\*\//g, '');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Step 3: Remove function implementations if configured
|
|
84
|
+
if (this.config.removeImplementations) {
|
|
85
|
+
// Match function and method bodies
|
|
86
|
+
result = result.replace(
|
|
87
|
+
/(\b(function|constructor|async function)\s+[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
88
|
+
(match, start, funcType, body, end) => {
|
|
89
|
+
// Keep function signature and opening brace, replace body with comment
|
|
90
|
+
return `${start} /* implementation removed */ ${end}`;
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Match arrow function bodies
|
|
95
|
+
result = result.replace(
|
|
96
|
+
/(\([^)]*\)\s*=>\s*{)([\s\S]*?)(})/g,
|
|
97
|
+
(match, start, body, end) => {
|
|
98
|
+
return `${start} /* implementation removed */ ${end}`;
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// Match method declarations
|
|
103
|
+
result = result.replace(
|
|
104
|
+
/(^\s*[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/gm,
|
|
105
|
+
(match, start, body, end) => {
|
|
106
|
+
return `${start} /* implementation removed */ ${end}`;
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Match class methods
|
|
111
|
+
result = result.replace(
|
|
112
|
+
/(\b(public|private|protected|static|async)?\s+[\w$]+\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
113
|
+
(match, start, modifier, body, end) => {
|
|
114
|
+
return `${start} /* implementation removed */ ${end}`;
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
} else if (this.config.maxFunctionLines && this.config.maxFunctionLines > 0) {
|
|
118
|
+
// If not removing implementations completely, limit the number of lines
|
|
119
|
+
// Match function and method bodies
|
|
120
|
+
result = result.replace(
|
|
121
|
+
/(\b(function|constructor|async function)\s+[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
122
|
+
(match, start, funcType, body, end) => {
|
|
123
|
+
return this.limitFunctionBody(start, body, end);
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Match arrow function bodies
|
|
128
|
+
result = result.replace(
|
|
129
|
+
/(\([^)]*\)\s*=>\s*{)([\s\S]*?)(})/g,
|
|
130
|
+
(match, start, body, end) => {
|
|
131
|
+
return this.limitFunctionBody(start, body, end);
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Match method declarations
|
|
136
|
+
result = result.replace(
|
|
137
|
+
/(^\s*[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/gm,
|
|
138
|
+
(match, start, body, end) => {
|
|
139
|
+
return this.limitFunctionBody(start, body, end);
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// Match class methods
|
|
144
|
+
result = result.replace(
|
|
145
|
+
/(\b(public|private|protected|static|async)?\s+[\w$]+\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
146
|
+
(match, start, modifier, body, end) => {
|
|
147
|
+
return this.limitFunctionBody(start, body, end);
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Step 4: Remove blank lines if configured
|
|
153
|
+
if (this.config.removeBlankLines) {
|
|
154
|
+
result = result.replace(/^\s*[\r\n]/gm, '');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Step 5: Restore preserved JSDoc comments
|
|
158
|
+
if (this.config.preserveJSDoc && jsDocComments.length > 0) {
|
|
159
|
+
// This is a placeholder; we already preserved JSDoc comments in the regex steps
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Limit a function body to a maximum number of lines
|
|
167
|
+
* @param start The function signature and opening brace
|
|
168
|
+
* @param body The function body
|
|
169
|
+
* @param end The closing brace
|
|
170
|
+
* @returns The limited function body
|
|
171
|
+
*/
|
|
172
|
+
private limitFunctionBody(start: string, body: string, end: string): string {
|
|
173
|
+
const lines = body.split('\n');
|
|
174
|
+
if (lines.length > this.config.maxFunctionLines!) {
|
|
175
|
+
const limitedBody = lines.slice(0, this.config.maxFunctionLines!).join('\n');
|
|
176
|
+
return `${start}${limitedBody}\n // ... (${lines.length - this.config.maxFunctionLines!} lines trimmed)\n${end}`;
|
|
177
|
+
}
|
|
178
|
+
return `${start}${body}${end}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Trim a Markdown file to reduce token usage
|
|
183
|
+
* @param content The Markdown file contents
|
|
184
|
+
* @returns The trimmed file contents
|
|
185
|
+
*/
|
|
186
|
+
private trimMarkdownFile(content: string): string {
|
|
187
|
+
// For markdown files, we generally want to keep most content
|
|
188
|
+
// but we can remove lengthy code blocks if needed
|
|
189
|
+
return content;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Trim a JSON file to reduce token usage
|
|
194
|
+
* @param content The JSON file contents
|
|
195
|
+
* @returns The trimmed file contents
|
|
196
|
+
*/
|
|
197
|
+
private trimJsonFile(content: string): string {
|
|
198
|
+
try {
|
|
199
|
+
// Parse the JSON
|
|
200
|
+
const json = JSON.parse(content);
|
|
201
|
+
|
|
202
|
+
// For package.json, keep only essential information
|
|
203
|
+
if ('name' in json && 'version' in json && 'dependencies' in json) {
|
|
204
|
+
const essentialKeys = [
|
|
205
|
+
'name', 'version', 'description', 'author', 'license',
|
|
206
|
+
'main', 'types', 'exports', 'type'
|
|
207
|
+
];
|
|
208
|
+
|
|
209
|
+
const trimmedJson: any = {};
|
|
210
|
+
essentialKeys.forEach(key => {
|
|
211
|
+
if (key in json) {
|
|
212
|
+
trimmedJson[key] = json[key];
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Add dependency information without versions
|
|
217
|
+
if ('dependencies' in json) {
|
|
218
|
+
trimmedJson.dependencies = Object.keys(json.dependencies).reduce((acc, dep) => {
|
|
219
|
+
acc[dep] = '*'; // Replace version with wildcard
|
|
220
|
+
return acc;
|
|
221
|
+
}, {} as Record<string, string>);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Return the trimmed JSON
|
|
225
|
+
return JSON.stringify(trimmedJson, null, 2);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// For other JSON files, leave as is
|
|
229
|
+
return content;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
// If there's an error parsing the JSON, return the original content
|
|
232
|
+
return content;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Update the trimmer configuration
|
|
238
|
+
* @param config The new configuration to apply
|
|
239
|
+
*/
|
|
240
|
+
public updateConfig(config: ITrimConfig): void {
|
|
241
|
+
this.config = {
|
|
242
|
+
...this.config,
|
|
243
|
+
...config
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|