tsfmt 0.0.0 → 0.2.1

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.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/dist/build-plugins/transformGenericsPlugin.js +86 -0
  3. package/dist/cli.js +174 -0
  4. package/dist/core/ast/ASTAnalyzer.js +136 -0
  5. package/dist/core/ast/ASTTransformer.js +85 -0
  6. package/dist/core/ast/DependencyResolver.js +144 -0
  7. package/dist/core/config/ConfigDefaults.js +178 -0
  8. package/dist/core/config/ConfigLoader.js +251 -0
  9. package/dist/core/config/ConfigMerger.js +45 -0
  10. package/dist/core/config/ConfigTypes.js +70 -0
  11. package/dist/core/config/ConfigValidator.js +74 -0
  12. package/dist/core/di/Container.js +175 -0
  13. package/dist/core/di/ServiceRegistration.js +38 -0
  14. package/dist/core/formatters/BaseFormattingRule.js +37 -0
  15. package/dist/core/formatters/rules/ast/ClassMemberSortingRule.js +171 -0
  16. package/dist/core/formatters/rules/ast/FileDeclarationSortingRule.js +162 -0
  17. package/dist/core/formatters/rules/imports/ImportOrganizationRule.js +196 -0
  18. package/dist/core/formatters/rules/index-generation/IndexGenerationRule.js +208 -0
  19. package/dist/core/formatters/rules/spacing/BlankLineBeforeReturnsRule.js +32 -0
  20. package/dist/core/formatters/rules/spacing/BlankLineBetweenDeclarationsRule.js +93 -0
  21. package/dist/core/formatters/rules/spacing/BlankLineBetweenStatementTypesRule.js +57 -0
  22. package/dist/core/formatters/rules/spacing/BlockSpacingRule.js +17 -0
  23. package/dist/core/formatters/rules/spacing/BracketSpacingRule.js +108 -0
  24. package/dist/core/formatters/rules/style/DocBlockCommentRule.js +19 -0
  25. package/dist/core/formatters/rules/style/IndentationRule.js +45 -0
  26. package/dist/core/formatters/rules/style/QuoteStyleRule.js +63 -0
  27. package/dist/core/formatters/rules/style/SemicolonRule.js +68 -0
  28. package/dist/core/formatters/rules/style/StructuralIndentationRule.js +250 -0
  29. package/dist/core/pipeline/FormatterPipeline.js +252 -0
  30. package/dist/formatters/package.js +29 -0
  31. package/dist/index.js +66 -0
  32. package/dist/shared/types.js +28 -0
  33. package/dist/sortPackage.js +34 -0
  34. package/dist/sortTSConfig.js +34 -0
  35. package/package.json +11 -8
  36. package/bin/ci_build.sh +0 -50
  37. package/bin/cli.js +0 -20
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("typescript");
4
+ require("./ConfigLoader.js");
5
+ const ConfigTypes = require("./ConfigTypes.js");
6
+ require("reflect-metadata");
7
+ const ClassMemberSortingRule = require("../formatters/rules/ast/ClassMemberSortingRule.js");
8
+ const FileDeclarationSortingRule = require("../formatters/rules/ast/FileDeclarationSortingRule.js");
9
+ require("fs");
10
+ require("path");
11
+ require("fs/promises");
12
+ const types = require("../../shared/types.js");
13
+ class ConfigDefaults {
14
+ static {
15
+ this.DEFAULT_EXCLUDE_PATTERNS = ["node_modules/**", "dist/**", "vendor/**", "bin/**"];
16
+ }
17
+ static {
18
+ this.DEFAULT_INDEX_DIRECTORIES = ["src/", "packages/"];
19
+ }
20
+ static {
21
+ this.DEFAULT_JS_INCLUDE_PATTERNS = ["**/*.{js,ts,jsx,tsx}"];
22
+ }
23
+ static {
24
+ this.DEFAULT_TS_INCLUDE_PATTERNS = ["**/*.{ts,tsx}"];
25
+ }
26
+ /** Get default code style configuration */
27
+ static getDefaultCodeStyleConfig() {
28
+ return {
29
+ enabled: true,
30
+ quoteStyle: "double",
31
+ semicolons: "always",
32
+ bracketSpacing: false,
33
+ indentStyle: "space",
34
+ indentWidth: 4,
35
+ lineWidth: 120,
36
+ trailingCommas: "all",
37
+ arrowParens: "avoid"
38
+ };
39
+ }
40
+ /** Get default directories for index generation */
41
+ static getDefaultIndexDirectories() {
42
+ return [...this.DEFAULT_INDEX_DIRECTORIES];
43
+ }
44
+ /** Get default index generation configuration */
45
+ static getDefaultIndexGenerationConfig() {
46
+ return {
47
+ enabled: true,
48
+ directories: this.getDefaultIndexDirectories(),
49
+ options: {
50
+ fileExtension: ".ts",
51
+ indexFileName: "index.ts",
52
+ recursive: true
53
+ },
54
+ updateMainIndex: true
55
+ };
56
+ }
57
+ /** Get default import configuration */
58
+ static getDefaultImportConfig() {
59
+ return {
60
+ enabled: true,
61
+ sortImports: true,
62
+ removeUnused: true,
63
+ removeSideEffects: false,
64
+ groupImports: true,
65
+ groupOrder: ConfigTypes.ConfigTypes.getImportGroupOptions(),
66
+ separateGroups: false
67
+ };
68
+ }
69
+ /** Get default include patterns for TypeScript files */
70
+ static getDefaultIncludePatterns() {
71
+ return [...this.DEFAULT_TS_INCLUDE_PATTERNS];
72
+ }
73
+ /** Get default exclude patterns for file processing */
74
+ static getDefaultExcludePatterns() {
75
+ return [...this.DEFAULT_EXCLUDE_PATTERNS];
76
+ }
77
+ /** Get default sorting configuration */
78
+ static getDefaultSortingConfig() {
79
+ return {
80
+ enabled: true,
81
+ classMembers: {
82
+ enabled: true,
83
+ order: ClassMemberSortingRule.DEFAULT_CLASS_ORDER,
84
+ groupByVisibility: false,
85
+ respectDependencies: true
86
+ },
87
+ reactComponents: {
88
+ enabled: true,
89
+ order: ClassMemberSortingRule.DEFAULT_CLASS_ORDER,
90
+ groupByVisibility: false,
91
+ respectDependencies: true
92
+ },
93
+ fileDeclarations: {
94
+ enabled: true,
95
+ order: FileDeclarationSortingRule.DEFAULT_FILE_ORDER,
96
+ respectDependencies: true
97
+ },
98
+ include: this.getDefaultIncludePatterns(),
99
+ exclude: this.getDefaultExcludePatterns()
100
+ };
101
+ }
102
+ /** Get default spacing configuration */
103
+ static getDefaultSpacingConfig() {
104
+ return {
105
+ enabled: false,
106
+ betweenDeclarations: true,
107
+ beforeReturns: true,
108
+ betweenStatementTypes: true
109
+ };
110
+ }
111
+ /** Get default package.json configuration */
112
+ static getDefaultPackageJsonConfig() {
113
+ return {
114
+ enabled: true,
115
+ customSortOrder: types.DefaultSortOptions.customSortOrder,
116
+ indentation: 4
117
+ };
118
+ }
119
+ /** Get default tsconfig.json configuration */
120
+ static getDefaultTsConfigConfig() {
121
+ return {
122
+ enabled: true,
123
+ indentation: 4
124
+ };
125
+ }
126
+ /** Get default formatter order */
127
+ static getDefaultFormatterOrder() {
128
+ return [
129
+ ConfigTypes.FormatterOrder.IndexGeneration,
130
+ ConfigTypes.FormatterOrder.CodeStyle,
131
+ ConfigTypes.FormatterOrder.ImportOrganization,
132
+ ConfigTypes.FormatterOrder.ASTTransformation,
133
+ ConfigTypes.FormatterOrder.Spacing
134
+ ];
135
+ }
136
+ /** Get the complete default configuration */
137
+ static getDefaultConfig() {
138
+ return {
139
+ indexGeneration: this.getDefaultIndexGenerationConfig(),
140
+ codeStyle: this.getDefaultCodeStyleConfig(),
141
+ imports: this.getDefaultImportConfig(),
142
+ sorting: this.getDefaultSortingConfig(),
143
+ spacing: this.getDefaultSpacingConfig(),
144
+ packageJson: this.getDefaultPackageJsonConfig(),
145
+ tsConfig: this.getDefaultTsConfigConfig(),
146
+ formatterOrder: this.getDefaultFormatterOrder()
147
+ };
148
+ }
149
+ /** Get default include patterns for JavaScript files */
150
+ static getDefaultJavaScriptIncludePatterns() {
151
+ return [...this.DEFAULT_JS_INCLUDE_PATTERNS];
152
+ }
153
+ /** Create a configuration with all features disabled */
154
+ static getDisabledConfig() {
155
+ return {
156
+ indexGeneration: { enabled: false },
157
+ codeStyle: { enabled: false },
158
+ imports: { enabled: false },
159
+ sorting: { enabled: false },
160
+ spacing: { enabled: false },
161
+ packageJson: { enabled: false },
162
+ tsConfig: { enabled: false }
163
+ };
164
+ }
165
+ /** Create a minimal configuration with only enabled features */
166
+ static getMinimalConfig() {
167
+ return {
168
+ indexGeneration: { enabled: true },
169
+ codeStyle: { enabled: true },
170
+ imports: { enabled: true },
171
+ sorting: { enabled: true },
172
+ spacing: { enabled: false },
173
+ packageJson: { enabled: true },
174
+ tsConfig: { enabled: true }
175
+ };
176
+ }
177
+ }
178
+ exports.ConfigDefaults = ConfigDefaults;
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const ts = require("typescript");
6
+ const ConfigDefaults = require("./ConfigDefaults.js");
7
+ const ConfigMerger = require("./ConfigMerger.js");
8
+ const ConfigValidator = require("./ConfigValidator.js");
9
+ function _interopNamespaceDefault(e) {
10
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
+ if (e) {
12
+ for (const k in e) {
13
+ if (k !== "default") {
14
+ const d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: () => e[k]
18
+ });
19
+ }
20
+ }
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+ const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
26
+ const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path);
27
+ const ts__namespace = /* @__PURE__ */ _interopNamespaceDefault(ts);
28
+ class ConfigLoader {
29
+ static {
30
+ this.CONFIG_FILE_NAME = "tsfmt.config.ts";
31
+ }
32
+ static {
33
+ this.configCache = /* @__PURE__ */ new Map();
34
+ }
35
+ /** Clears the configuration cache */
36
+ static clearCache() {
37
+ this.configCache.clear();
38
+ }
39
+ /**
40
+ * Gets the path to the config file
41
+ * @param projectRoot - The root directory of the project
42
+ * @returns Full path to the config file
43
+ */
44
+ static getConfigFilePath(projectRoot = process.cwd()) {
45
+ return path__namespace.join(projectRoot, this.CONFIG_FILE_NAME);
46
+ }
47
+ /**
48
+ * Creates a sample configuration file
49
+ * @param projectRoot - The root directory of the project
50
+ * @param overwrite - Whether to overwrite existing file (default: false)
51
+ * @throws Error if file exists and overwrite is false
52
+ */
53
+ static createSampleConfig(projectRoot = process.cwd(), overwrite = false) {
54
+ const configPath = this.getConfigFilePath(projectRoot);
55
+ if (fs__namespace.existsSync(configPath) && !overwrite) {
56
+ throw new Error(`Configuration file already exists at ${configPath}. Use overwrite=true to replace it.`);
57
+ }
58
+ const sampleConfig = `/*
59
+ * tsfmt Configuration File
60
+ *
61
+ * This file defines the configuration for tsfmt formatting.
62
+ * All options are optional - defaults will be used for missing values.
63
+ */
64
+
65
+ import { CoreConfig } from "tsfmt";
66
+
67
+ const config: CoreConfig = {
68
+ // Enable/disable index file generation
69
+ indexGeneration: {
70
+ enabled: true,
71
+ directories: ConfigDefaults.getDefaultIndexDirectories(),
72
+ updateMainIndex: true,
73
+ },
74
+
75
+ // Code style configuration
76
+ codeStyle: {
77
+ enabled: true,
78
+ quoteStyle: "double",
79
+ semicolons: "always",
80
+ indentWidth: 4,
81
+ lineWidth: 120,
82
+ },
83
+
84
+ // Import organization
85
+ imports: {
86
+ enabled: true,
87
+ sortImports: true,
88
+ removeUnused: true,
89
+ groupImports: true,
90
+ },
91
+
92
+ // AST-based sorting
93
+ sorting: {
94
+ enabled: true,
95
+ classMembers: { enabled: true },
96
+ fileDeclarations: { enabled: true },
97
+ },
98
+
99
+ // Spacing rules
100
+ spacing: {
101
+ enabled: false,
102
+ betweenDeclarations: true,
103
+ beforeReturns: true,
104
+ },
105
+
106
+ // JSON file sorting
107
+ packageJson: { enabled: true },
108
+ tsConfig: { enabled: true },
109
+ };
110
+
111
+ export default config;
112
+ `;
113
+ fs__namespace.writeFileSync(configPath, sampleConfig, "utf-8");
114
+ }
115
+ /**
116
+ * Gets cache statistics for debugging
117
+ * @returns Object with cache information
118
+ */
119
+ static getCacheStats() {
120
+ return {
121
+ size: this.configCache.size,
122
+ keys: Array.from(this.configCache.keys())
123
+ };
124
+ }
125
+ /**
126
+ * Gets file modification time for cache invalidation
127
+ * @param filePath - Path to the file
128
+ * @returns File modification time in milliseconds
129
+ */
130
+ static getFileModTime(filePath) {
131
+ try {
132
+ return fs__namespace.statSync(filePath).mtime.getTime();
133
+ } catch {
134
+ return 0;
135
+ }
136
+ }
137
+ /**
138
+ * Checks if a tsfmt.config.ts file exists in the project
139
+ * @param projectRoot - The root directory of the project (defaults to current working directory)
140
+ * @returns true if tsfmt.config.ts exists
141
+ */
142
+ static hasConfigFile(projectRoot = process.cwd()) {
143
+ const configPath = path__namespace.join(projectRoot, this.CONFIG_FILE_NAME);
144
+ return fs__namespace.existsSync(configPath);
145
+ }
146
+ /**
147
+ * Transpiles TypeScript code to JavaScript
148
+ * @param code - TypeScript code to transpile
149
+ * @returns Transpiled JavaScript code
150
+ */
151
+ static transpileTypeScript(code) {
152
+ const result = ts__namespace.transpileModule(code, {
153
+ compilerOptions: {
154
+ module: ts__namespace.ModuleKind.CommonJS,
155
+ target: ts__namespace.ScriptTarget.ES2015,
156
+ esModuleInterop: true,
157
+ allowSyntheticDefaultImports: true
158
+ }
159
+ });
160
+ return result.outputText;
161
+ }
162
+ /**
163
+ * Loads and evaluates a TypeScript config file
164
+ * @param filePath - Path to the config file
165
+ * @returns Partial configuration from the file
166
+ * @throws Error if the config file is invalid
167
+ */
168
+ static loadTypeScriptConfig(filePath) {
169
+ try {
170
+ const code = fs__namespace.readFileSync(filePath, "utf-8");
171
+ const transpiled = this.transpileTypeScript(code);
172
+ const module2 = { exports: {} };
173
+ const exports$1 = module2.exports;
174
+ const requireFunc = (moduleName) => {
175
+ if (moduleName.startsWith(".")) {
176
+ const resolvedPath = path__namespace.resolve(path__namespace.dirname(filePath), moduleName);
177
+ return require(resolvedPath);
178
+ }
179
+ return require(moduleName);
180
+ };
181
+ const func = new Function("exports", "module", "require", "__filename", "__dirname", transpiled);
182
+ func(exports$1, module2, requireFunc, filePath, path__namespace.dirname(filePath));
183
+ const config = module2.exports.default || module2.exports;
184
+ if (typeof config !== "object" || config === null) {
185
+ throw new Error(`${this.CONFIG_FILE_NAME} must export a configuration object. Found: ${typeof config}`);
186
+ }
187
+ return config;
188
+ } catch (error) {
189
+ throw new Error(`Failed to load ${this.CONFIG_FILE_NAME}: ${error instanceof Error ? error.message : String(error)}`);
190
+ }
191
+ }
192
+ /**
193
+ * Loads the configuration from cache if valid, otherwise from file
194
+ * @param filePath - Path to the config file
195
+ * @returns Loaded configuration
196
+ */
197
+ static loadConfigWithCache(filePath) {
198
+ const currentMtime = this.getFileModTime(filePath);
199
+ const cached = this.configCache.get(filePath);
200
+ if (cached && cached.mtime === currentMtime) {
201
+ return cached.config;
202
+ }
203
+ const config = this.loadTypeScriptConfig(filePath);
204
+ this.configCache.set(filePath, { config, mtime: currentMtime });
205
+ return config;
206
+ }
207
+ /**
208
+ * Loads the configuration from tsfmt.config.ts if it exists, otherwise returns default config
209
+ * @param projectRoot - The root directory of the project (defaults to current working directory)
210
+ * @param validate - Whether to validate the configuration (default: true)
211
+ * @returns The merged configuration
212
+ */
213
+ static loadConfig(projectRoot = process.cwd(), validate = true) {
214
+ const configPath = this.getConfigFilePath(projectRoot);
215
+ if (!fs__namespace.existsSync(configPath)) {
216
+ return ConfigDefaults.ConfigDefaults.getDefaultConfig();
217
+ }
218
+ try {
219
+ const userConfig = this.loadConfigWithCache(configPath);
220
+ const mergedConfig = ConfigMerger.ConfigMerger.merge(userConfig);
221
+ if (validate) {
222
+ ConfigValidator.ConfigValidator.validateOrThrow(mergedConfig);
223
+ }
224
+ return mergedConfig;
225
+ } catch (error) {
226
+ console.error(`Error loading configuration from ${configPath}:`);
227
+ console.error(error instanceof Error ? error.message : String(error));
228
+ console.error("Falling back to default configuration.");
229
+ return ConfigDefaults.ConfigDefaults.getDefaultConfig();
230
+ }
231
+ }
232
+ /**
233
+ * Loads configuration without validation (for debugging or inspection)
234
+ * @param projectRoot - The root directory of the project
235
+ * @returns The merged configuration without validation
236
+ */
237
+ static loadConfigWithoutValidation(projectRoot = process.cwd()) {
238
+ return this.loadConfig(projectRoot, false);
239
+ }
240
+ /**
241
+ * Reloads configuration by clearing cache and loading fresh
242
+ * @param projectRoot - The root directory of the project
243
+ * @returns The reloaded configuration
244
+ */
245
+ static reloadConfig(projectRoot = process.cwd()) {
246
+ const configPath = this.getConfigFilePath(projectRoot);
247
+ this.configCache.delete(configPath);
248
+ return this.loadConfig(projectRoot);
249
+ }
250
+ }
251
+ exports.ConfigLoader = ConfigLoader;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const ConfigDefaults = require("./ConfigDefaults.js");
4
+ class ConfigMerger {
5
+ /**
6
+ * Deep merge two configuration objects
7
+ * @param target - Target configuration (defaults)
8
+ * @param source - Source configuration (user overrides)
9
+ * @returns Merged configuration
10
+ */
11
+ static deepMerge(target, source) {
12
+ const result = { ...target };
13
+ for (const key in source) {
14
+ if (source[key] !== void 0) {
15
+ if (typeof source[key] === "object" && source[key] !== null && !Array.isArray(source[key]) && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
16
+ result[key] = this.deepMerge(result[key], source[key]);
17
+ } else {
18
+ result[key] = source[key];
19
+ }
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ /**
25
+ * Merge user config with default config
26
+ * @param userConfig - Partial user configuration
27
+ * @returns Complete merged configuration
28
+ */
29
+ static merge(userConfig) {
30
+ return this.deepMerge(ConfigDefaults.ConfigDefaults.getDefaultConfig(), userConfig);
31
+ }
32
+ /**
33
+ * Merge multiple partial configs together
34
+ * @param configs - Array of partial configurations to merge
35
+ * @returns Merged configuration
36
+ */
37
+ static mergeMultiple(...configs) {
38
+ let result = ConfigDefaults.ConfigDefaults.getDefaultConfig();
39
+ for (const config of configs) {
40
+ result = this.deepMerge(result, config);
41
+ }
42
+ return result;
43
+ }
44
+ }
45
+ exports.ConfigMerger = ConfigMerger;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ var FormatterOrder = /* @__PURE__ */ ((FormatterOrder2) => {
4
+ FormatterOrder2["IndexGeneration"] = "IndexGeneration";
5
+ FormatterOrder2["CodeStyle"] = "CodeStyle";
6
+ FormatterOrder2["ImportOrganization"] = "ImportOrganization";
7
+ FormatterOrder2["ASTTransformation"] = "ASTTransformation";
8
+ FormatterOrder2["Spacing"] = "Spacing";
9
+ return FormatterOrder2;
10
+ })(FormatterOrder || {});
11
+ class ConfigTypes {
12
+ /** Get all available arrow parentheses options */
13
+ static getArrowParenOptions() {
14
+ return ["always", "avoid"];
15
+ }
16
+ /** Get all formatter order options */
17
+ static getFormatterOrderOptions() {
18
+ return Object.values(FormatterOrder);
19
+ }
20
+ /** Get all available import group options */
21
+ static getImportGroupOptions() {
22
+ return ["external", "internal", "relative"];
23
+ }
24
+ /** Get all available indent style options */
25
+ static getIndentStyleOptions() {
26
+ return ["tab", "space"];
27
+ }
28
+ /** Get all available quote style options */
29
+ static getQuoteStyleOptions() {
30
+ return ["single", "double"];
31
+ }
32
+ /** Get all available semicolon options */
33
+ static getSemicolonOptions() {
34
+ return ["always", "never"];
35
+ }
36
+ /** Get all available trailing comma options */
37
+ static getTrailingCommaOptions() {
38
+ return ["none", "es5", "all"];
39
+ }
40
+ /** Check if a line width is in recommended range */
41
+ static isRecommendedLineWidth(width) {
42
+ return width >= 80 && width <= 120;
43
+ }
44
+ /** Validate an arrow parentheses option */
45
+ static isValidArrowParenOption(option) {
46
+ return this.getArrowParenOptions().includes(option);
47
+ }
48
+ /** Validate an indent style option */
49
+ static isValidIndentStyle(style) {
50
+ return this.getIndentStyleOptions().includes(style);
51
+ }
52
+ /** Check if an indent width is valid */
53
+ static isValidIndentWidth(width) {
54
+ return width >= 1 && width <= 8;
55
+ }
56
+ /** Validate a quote style option */
57
+ static isValidQuoteStyle(style) {
58
+ return this.getQuoteStyleOptions().includes(style);
59
+ }
60
+ /** Validate a semicolon option */
61
+ static isValidSemicolonOption(option) {
62
+ return this.getSemicolonOptions().includes(option);
63
+ }
64
+ /** Validate a trailing comma option */
65
+ static isValidTrailingCommaOption(option) {
66
+ return this.getTrailingCommaOptions().includes(option);
67
+ }
68
+ }
69
+ exports.ConfigTypes = ConfigTypes;
70
+ exports.FormatterOrder = FormatterOrder;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const ConfigTypes = require("./ConfigTypes.js");
4
+ class ConfigValidator {
5
+ /**
6
+ * Validate a CoreConfig object
7
+ * @param config - Configuration to validate
8
+ * @returns Validation result with errors and warnings
9
+ */
10
+ static validate(config) {
11
+ const errors = [];
12
+ const warnings = [];
13
+ if (config.codeStyle) {
14
+ if (config.codeStyle.enabled && config.codeStyle.quoteStyle) {
15
+ if (!ConfigTypes.ConfigTypes.isValidQuoteStyle(config.codeStyle.quoteStyle)) {
16
+ errors.push(`Invalid quoteStyle: ${config.codeStyle.quoteStyle}. Must be ${ConfigTypes.ConfigTypes.getQuoteStyleOptions().map((s) => `'${s}'`).join(" or ")}.`);
17
+ }
18
+ }
19
+ if (config.codeStyle.enabled && config.codeStyle.semicolons) {
20
+ if (!ConfigTypes.ConfigTypes.isValidSemicolonOption(config.codeStyle.semicolons)) {
21
+ errors.push(`Invalid semicolons: ${config.codeStyle.semicolons}. Must be ${ConfigTypes.ConfigTypes.getSemicolonOptions().map((s) => `'${s}'`).join(" or ")}.`);
22
+ }
23
+ }
24
+ if (config.codeStyle.indentWidth !== void 0) {
25
+ if (!ConfigTypes.ConfigTypes.isValidIndentWidth(config.codeStyle.indentWidth)) {
26
+ errors.push(`Invalid indentWidth: ${config.codeStyle.indentWidth}. Must be between 1 and 8.`);
27
+ }
28
+ }
29
+ if (config.codeStyle.lineWidth !== void 0) {
30
+ if (config.codeStyle.lineWidth < 40 || config.codeStyle.lineWidth > 200) {
31
+ if (!ConfigTypes.ConfigTypes.isRecommendedLineWidth(config.codeStyle.lineWidth)) {
32
+ warnings.push(`Unusual lineWidth: ${config.codeStyle.lineWidth}. Recommended range is 80-120.`);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ if (config.imports) {
38
+ if (config.imports.groupOrder && config.imports.groupOrder.length > 0) {
39
+ const validGroups = ConfigTypes.ConfigTypes.getImportGroupOptions();
40
+ const invalidGroups = config.imports.groupOrder.filter((g) => !validGroups.includes(g));
41
+ if (invalidGroups.length > 0) {
42
+ errors.push(`Invalid group in groupOrder: ${invalidGroups.join(", ")}. Valid groups: ${validGroups.join(", ")}`);
43
+ }
44
+ }
45
+ }
46
+ if (config.sorting) {
47
+ if (config.sorting.include && config.sorting.include.length === 0) {
48
+ warnings.push("Sorting include patterns is empty - no files will be sorted.");
49
+ }
50
+ }
51
+ return {
52
+ valid: errors.length === 0,
53
+ errors,
54
+ warnings
55
+ };
56
+ }
57
+ /**
58
+ * Validate and throw if invalid
59
+ * @param config - Configuration to validate
60
+ * @throws Error if configuration is invalid
61
+ */
62
+ static validateOrThrow(config) {
63
+ const result = this.validate(config);
64
+ if (!result.valid) {
65
+ throw new Error(`Invalid configuration:
66
+ ${result.errors.join("\n")}`);
67
+ }
68
+ if (result.warnings.length > 0) {
69
+ console.warn("Configuration warnings:");
70
+ result.warnings.forEach((warning) => console.warn(` - ${warning}`));
71
+ }
72
+ }
73
+ }
74
+ exports.ConfigValidator = ConfigValidator;