@noego/forge 0.1.23 → 0.1.24

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/bin/forge.js CHANGED
@@ -4,13 +4,29 @@ import { spawn } from 'child_process';
4
4
  import { glob } from 'glob';
5
5
 
6
6
  const args = process.argv.slice(2);
7
+ const command = args[0];
8
+
9
+ // Handle 'lint' subcommand
10
+ if (command === 'lint') {
11
+ const { runLint } = await import('../dist/lint/cli.js');
12
+ const lintArgs = args.slice(1);
13
+ const exitCode = await runLint(lintArgs);
14
+ process.exit(exitCode);
15
+ }
7
16
 
8
17
  if (args.length === 0) {
9
- console.log('Usage: forge <pattern|files...>');
18
+ console.log('Usage: forge <command|pattern|files...>');
19
+ console.log('');
20
+ console.log('Commands:');
21
+ console.log(' lint [files...] Lint Svelte and TypeScript files');
10
22
  console.log('');
11
- console.log('Runs TypeScript files with Svelte support.');
23
+ console.log('File Execution:');
24
+ console.log(' Runs TypeScript files with Svelte support.');
12
25
  console.log('');
13
26
  console.log('Examples:');
27
+ console.log(' forge lint');
28
+ console.log(' forge lint --fix');
29
+ console.log(' forge lint src/component.svelte');
14
30
  console.log(' forge test/ui/auth.test.ts');
15
31
  console.log(' forge test/ui/*.test.ts');
16
32
  console.log(' forge "test/ui/**/*.test.ts"');
@@ -0,0 +1,9 @@
1
+ export interface LintOptions {
2
+ fix?: boolean;
3
+ deps?: boolean;
4
+ files: string[];
5
+ help?: boolean;
6
+ warnings?: boolean;
7
+ }
8
+ export declare function parseArgs(args: string[]): LintOptions;
9
+ export declare function runLint(args: string[]): Promise<number>;
@@ -0,0 +1,228 @@
1
+ import { loadESLint } from './eslint_loader.js';
2
+ import { DependencyCollector } from './dependency_collector.js';
3
+ import { getSvelteFilesFromRoutes } from './route_parser.js';
4
+ import { loadLintConfig } from './config.js';
5
+ import path from 'path';
6
+ function showHelp() {
7
+ console.log(`
8
+ Usage: forge lint [options] [files...]
9
+
10
+ Lint Svelte and TypeScript files with smart dependency analysis.
11
+
12
+ Options:
13
+ --fix Automatically fix problems
14
+ --no-deps Skip dependency analysis for specified files
15
+ --warnings, --warn, -w Show warnings (hidden by default)
16
+ --help, -h Show this help message
17
+
18
+ Examples:
19
+ forge lint Lint all components from route config
20
+ forge lint src/App.svelte Lint App.svelte and all its dependencies
21
+ forge lint --fix Lint and auto-fix all files
22
+ forge lint --no-deps src/utils.ts Lint only utils.ts (no dependencies)
23
+
24
+ How it works:
25
+ - Without files: Discovers components from routes.yaml/openapi.yaml
26
+ - With files: Lints specified files + their dependencies (unless --no-deps)
27
+ - Fallback: Uses src/**/*.{svelte,ts,js} if no route config found
28
+
29
+ Notes:
30
+ - Zero-setup: No eslint.config.js required in your project
31
+ - Requires: npm install eslint eslint-plugin-svelte typescript-eslint
32
+ - Circular dependencies are reported as warnings
33
+ - Exit code 0 = no errors, 1 = errors found
34
+ `);
35
+ }
36
+ export function parseArgs(args) {
37
+ const options = {
38
+ fix: false,
39
+ deps: true,
40
+ files: [],
41
+ help: false,
42
+ warnings: false,
43
+ };
44
+ for (let i = 0; i < args.length; i++) {
45
+ const arg = args[i];
46
+ if (arg === '--help' || arg === '-h') {
47
+ options.help = true;
48
+ }
49
+ else if (arg === '--fix') {
50
+ options.fix = true;
51
+ }
52
+ else if (arg === '--no-deps') {
53
+ options.deps = false;
54
+ }
55
+ else if (arg === '--warnings' || arg === '--warn' || arg === '-w') {
56
+ options.warnings = true;
57
+ }
58
+ else if (!arg.startsWith('-')) {
59
+ options.files.push(arg);
60
+ }
61
+ }
62
+ return options;
63
+ }
64
+ export async function runLint(args) {
65
+ const options = parseArgs(args);
66
+ // Handle --help flag
67
+ if (options.help) {
68
+ showHelp();
69
+ return 0;
70
+ }
71
+ const cwd = process.cwd();
72
+ try {
73
+ // Load ESLint dynamically
74
+ const { ESLint } = await loadESLint();
75
+ let filesToLint = [];
76
+ if (options.files.length === 0) {
77
+ // Discover files the same way forge does - by parsing routes
78
+ console.log('Discovering files from route configuration...\n');
79
+ const routeFiles = await getSvelteFilesFromRoutes(cwd);
80
+ if (routeFiles.length > 0) {
81
+ filesToLint = routeFiles;
82
+ console.log(`Found ${filesToLint.length} component(s) from route configuration\n`);
83
+ }
84
+ else {
85
+ // Fallback: No route config found, use glob patterns
86
+ console.log('⚠️ No route configuration found (routes.yaml, openapi.yaml, etc.)');
87
+ console.log(' Using fallback pattern: src/**/*.{svelte,ts,js}\n');
88
+ filesToLint = ['src/**/*.svelte', 'src/**/*.ts', 'src/**/*.js'];
89
+ }
90
+ }
91
+ else {
92
+ // Lint specific files with optional dependency analysis
93
+ for (const file of options.files) {
94
+ const absolutePath = path.isAbsolute(file)
95
+ ? file
96
+ : path.resolve(cwd, file);
97
+ if (file.endsWith('.svelte') && options.deps) {
98
+ // Collect dependencies for Svelte files
99
+ const collector = new DependencyCollector({
100
+ recursive: true,
101
+ projectRoot: cwd,
102
+ });
103
+ const result = await collector.collect(absolutePath);
104
+ // Add all files from the dependency graph
105
+ for (const dep of result.dependencies) {
106
+ filesToLint.push(dep.file);
107
+ }
108
+ // Report circular dependencies as warnings
109
+ if (result.circular.length > 0) {
110
+ console.warn(`\n⚠️ Warning: Detected ${result.circular.length} circular dependencies:`);
111
+ for (const circ of result.circular) {
112
+ console.warn(` ${path.basename(circ.from)} ⟷ ${path.basename(circ.to)}`);
113
+ }
114
+ console.warn('');
115
+ }
116
+ }
117
+ else {
118
+ // Just lint the single file
119
+ filesToLint.push(absolutePath);
120
+ }
121
+ }
122
+ }
123
+ // Load built-in config for zero-setup linting
124
+ const config = await loadLintConfig();
125
+ // Create ESLint instance with built-in config
126
+ const eslint = new ESLint({
127
+ fix: options.fix,
128
+ overrideConfigFile: true, // Ignore any eslint.config.js in target project
129
+ overrideConfig: config,
130
+ });
131
+ console.log(`\nLinting ${filesToLint.length} file(s):\n`);
132
+ for (const file of filesToLint) {
133
+ console.log(` ${path.relative(cwd, file)}`);
134
+ }
135
+ console.log('');
136
+ // Lint the files
137
+ const results = await eslint.lintFiles(filesToLint);
138
+ // Apply fixes if requested
139
+ if (options.fix) {
140
+ await ESLint.outputFixes(results);
141
+ }
142
+ // Filter out warnings if --warnings flag not provided
143
+ const filteredResults = options.warnings
144
+ ? results
145
+ : results.map((result) => ({
146
+ ...result,
147
+ messages: result.messages.filter((msg) => msg.severity === 2), // 2 = error, 1 = warning
148
+ warningCount: 0,
149
+ }));
150
+ // Format results
151
+ const formatter = await eslint.loadFormatter('stylish');
152
+ const resultText = await formatter.format(filteredResults);
153
+ if (resultText) {
154
+ console.log(resultText);
155
+ }
156
+ // Calculate totals
157
+ const errorCount = results.reduce((sum, r) => sum + r.errorCount, 0);
158
+ const warningCount = results.reduce((sum, r) => sum + r.warningCount, 0);
159
+ // Print summary
160
+ if (errorCount === 0 && warningCount === 0) {
161
+ console.log('✓ No errors found\n');
162
+ }
163
+ else {
164
+ console.log(`\nLint complete: ${errorCount} error(s), ${warningCount} warning(s)`);
165
+ if (options.fix) {
166
+ console.log('Fixed issues have been written to disk');
167
+ }
168
+ else if (errorCount > 0 || warningCount > 0) {
169
+ console.log('Run "forge lint --fix" to auto-fix issues\n');
170
+ }
171
+ }
172
+ // Return exit code
173
+ return errorCount > 0 ? 1 : 0;
174
+ }
175
+ catch (error) {
176
+ // Handle specific error types with better messages
177
+ if (error instanceof Error) {
178
+ // ESLint configuration errors
179
+ if (error.message.includes('Cannot find package') ||
180
+ error.message.includes('Cannot find module')) {
181
+ const packageMatch = error.message.match(/Cannot find (?:package|module) '([^']+)'/);
182
+ const packageName = packageMatch ? packageMatch[1] : 'unknown';
183
+ console.error('\n❌ ESLint Configuration Error\n');
184
+ console.error(` Missing package: ${packageName}`);
185
+ console.error('\n This package is imported in your eslint.config.js but not installed.');
186
+ console.error('\n To fix this, install the missing package:');
187
+ console.error(` npm install --save-dev ${packageName}`);
188
+ console.error('');
189
+ return 1;
190
+ }
191
+ // Config file missing error
192
+ if (error.message.includes('Could not find config file')) {
193
+ console.error('\n❌ ESLint Configuration Missing\n');
194
+ console.error(' No eslint.config.js found in your project.');
195
+ console.error('\n To fix this, create an eslint.config.js file:');
196
+ console.error(' npm install --save-dev eslint eslint-plugin-svelte');
197
+ console.error(' npx eslint --init');
198
+ console.error('');
199
+ return 1;
200
+ }
201
+ // No files found error
202
+ if (error.message.includes('No files matching')) {
203
+ console.error('\n❌ No Files Found\n');
204
+ console.error(' ' + error.message);
205
+ console.error('\n Try specifying files explicitly:');
206
+ console.error(' forge lint src/Component.svelte');
207
+ console.error('');
208
+ return 1;
209
+ }
210
+ // Generic error with better formatting
211
+ console.error('\n❌ Error\n');
212
+ console.error(' ' + error.message);
213
+ // Show stack trace only in verbose mode or if it's not a known error type
214
+ if (process.env.DEBUG || process.env.VERBOSE) {
215
+ console.error('\n Stack trace:');
216
+ console.error(error.stack?.split('\n').map(line => ' ' + line).join('\n'));
217
+ }
218
+ console.error('');
219
+ }
220
+ else {
221
+ console.error('\n❌ Unexpected Error\n');
222
+ console.error(' ', error);
223
+ console.error('');
224
+ }
225
+ return 1;
226
+ }
227
+ }
228
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/lint/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Linter } from 'eslint';
2
+ /**
3
+ * Dynamically loads the lint configuration for zero-setup linting.
4
+ * Supports TypeScript in Svelte files out of the box.
5
+ */
6
+ export declare function loadLintConfig(): Promise<Linter.Config[]>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Dynamically loads the lint configuration for zero-setup linting.
3
+ * Supports TypeScript in Svelte files out of the box.
4
+ */
5
+ export async function loadLintConfig() {
6
+ // Load required packages dynamically
7
+ const [js, tseslint, sveltePlugin, globals] = await Promise.all([
8
+ import('@eslint/js').then((m) => m.default),
9
+ import('typescript-eslint').then((m) => m.default),
10
+ import('eslint-plugin-svelte').then((m) => m.default),
11
+ import('globals').then((m) => m.default),
12
+ ]);
13
+ return [
14
+ js.configs.recommended,
15
+ ...tseslint.configs.recommended,
16
+ ...sveltePlugin.configs['flat/recommended'],
17
+ {
18
+ languageOptions: {
19
+ ecmaVersion: 2022,
20
+ sourceType: 'module',
21
+ globals: {
22
+ ...globals.browser,
23
+ ...globals.node,
24
+ },
25
+ },
26
+ rules: {
27
+ // Svelte 5 specific rules
28
+ 'svelte/valid-compile': 'error',
29
+ // Disable rules that TypeScript handles
30
+ 'no-unused-vars': 'off',
31
+ 'no-undef': 'off',
32
+ // Unused vars as warning, not error
33
+ '@typescript-eslint/no-unused-vars': 'warn',
34
+ },
35
+ },
36
+ {
37
+ files: ['**/*.svelte'],
38
+ languageOptions: {
39
+ parserOptions: {
40
+ parser: tseslint.parser,
41
+ },
42
+ },
43
+ },
44
+ {
45
+ ignores: ['node_modules', 'dist', 'dist-ssr', '.svelte-kit'],
46
+ },
47
+ ];
48
+ }
49
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lint/config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,qCAAqC;IACrC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9D,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3C,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACrD,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KACzC,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,CAAC,OAAO,CAAC,WAAW;QACtB,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW;QAC/B,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC;QAC3C;YACE,eAAe,EAAE;gBACf,WAAW,EAAE,IAAI;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE;oBACP,GAAG,OAAO,CAAC,OAAO;oBAClB,GAAG,OAAO,CAAC,IAAI;iBAChB;aACF;YACD,KAAK,EAAE;gBACL,0BAA0B;gBAC1B,sBAAsB,EAAE,OAAO;gBAE/B,wCAAwC;gBACxC,gBAAgB,EAAE,KAAK;gBACvB,UAAU,EAAE,KAAK;gBAEjB,oCAAoC;gBACpC,mCAAmC,EAAE,MAAM;aAC5C;SACF;QACD;YACE,KAAK,EAAE,CAAC,aAAa,CAAC;YACtB,eAAe,EAAE;gBACf,aAAa,EAAE;oBACb,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACxB;aACF;SACF;QACD;YACE,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC;SAC7D;KACiB,CAAC;AACvB,CAAC"}
@@ -0,0 +1,39 @@
1
+ export interface DependencyInfo {
2
+ file: string;
3
+ imports: string[];
4
+ }
5
+ export interface CircularDependency {
6
+ from: string;
7
+ to: string;
8
+ }
9
+ export interface MissingImport {
10
+ file: string;
11
+ importPath: string;
12
+ }
13
+ export interface CollectionResult {
14
+ dependencies: DependencyInfo[];
15
+ circular: CircularDependency[];
16
+ missing: MissingImport[];
17
+ }
18
+ export interface CollectorOptions {
19
+ recursive?: boolean;
20
+ reportMissing?: boolean;
21
+ aliases?: Record<string, string>;
22
+ projectRoot?: string;
23
+ }
24
+ export declare class DependencyCollector {
25
+ private visited;
26
+ private inProgress;
27
+ private dependencies;
28
+ private circular;
29
+ private missing;
30
+ private options;
31
+ private initialized;
32
+ constructor(options?: CollectorOptions);
33
+ collect(entryFile: string): Promise<CollectionResult>;
34
+ private traverse;
35
+ private extractJavaScript;
36
+ private isExternalPackage;
37
+ private resolveImport;
38
+ private tryResolveFile;
39
+ }
@@ -0,0 +1,205 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { init, parse } from 'es-module-lexer';
4
+ export class DependencyCollector {
5
+ constructor(options = {}) {
6
+ this.visited = new Set();
7
+ this.inProgress = new Set();
8
+ this.dependencies = new Map();
9
+ this.circular = [];
10
+ this.missing = [];
11
+ this.initialized = false;
12
+ this.options = {
13
+ recursive: options.recursive ?? true,
14
+ reportMissing: options.reportMissing ?? false,
15
+ aliases: options.aliases ?? {},
16
+ projectRoot: options.projectRoot ?? process.cwd(),
17
+ };
18
+ }
19
+ async collect(entryFile) {
20
+ // Initialize es-module-lexer once
21
+ if (!this.initialized) {
22
+ await init;
23
+ this.initialized = true;
24
+ }
25
+ // Reset state for new collection
26
+ this.visited.clear();
27
+ this.inProgress.clear();
28
+ this.dependencies.clear();
29
+ this.circular = [];
30
+ this.missing = [];
31
+ const absolutePath = path.isAbsolute(entryFile)
32
+ ? entryFile
33
+ : path.resolve(this.options.projectRoot, entryFile);
34
+ await this.traverse(absolutePath);
35
+ // Convert Map to array of DependencyInfo
36
+ const dependencies = [];
37
+ for (const [file, imports] of this.dependencies.entries()) {
38
+ dependencies.push({ file, imports });
39
+ }
40
+ return {
41
+ dependencies,
42
+ circular: this.circular,
43
+ missing: this.missing,
44
+ };
45
+ }
46
+ async traverse(filePath) {
47
+ // Normalize the path
48
+ const normalizedPath = path.normalize(filePath);
49
+ // Check if already visited
50
+ if (this.visited.has(normalizedPath)) {
51
+ return;
52
+ }
53
+ // Check for circular dependency
54
+ if (this.inProgress.has(normalizedPath)) {
55
+ return;
56
+ }
57
+ this.inProgress.add(normalizedPath);
58
+ try {
59
+ // Read file content
60
+ const content = await fs.readFile(normalizedPath, 'utf-8');
61
+ // Extract JavaScript content (for .svelte files, extract <script> content)
62
+ const jsContent = this.extractJavaScript(content, normalizedPath);
63
+ // Parse imports using es-module-lexer
64
+ const [imports] = parse(jsContent);
65
+ const importPaths = [];
66
+ // Process each import
67
+ for (const imp of imports) {
68
+ const importSpecifier = imp.n;
69
+ if (!importSpecifier)
70
+ continue;
71
+ // Skip external packages (node_modules)
72
+ if (this.isExternalPackage(importSpecifier)) {
73
+ continue;
74
+ }
75
+ // Resolve the import path
76
+ const resolvedPath = await this.resolveImport(importSpecifier, normalizedPath);
77
+ if (!resolvedPath) {
78
+ if (this.options.reportMissing) {
79
+ this.missing.push({
80
+ file: normalizedPath,
81
+ importPath: importSpecifier,
82
+ });
83
+ }
84
+ continue;
85
+ }
86
+ importPaths.push(resolvedPath);
87
+ // Check for circular dependency before recursing
88
+ if (this.inProgress.has(resolvedPath)) {
89
+ this.circular.push({
90
+ from: normalizedPath,
91
+ to: resolvedPath,
92
+ });
93
+ continue;
94
+ }
95
+ // Recursively collect dependencies
96
+ if (this.options.recursive) {
97
+ await this.traverse(resolvedPath);
98
+ }
99
+ }
100
+ // Store dependencies for this file
101
+ this.dependencies.set(normalizedPath, importPaths);
102
+ }
103
+ catch (error) {
104
+ // Re-throw file system errors (ENOENT, etc.)
105
+ throw error;
106
+ }
107
+ finally {
108
+ this.inProgress.delete(normalizedPath);
109
+ this.visited.add(normalizedPath);
110
+ }
111
+ }
112
+ extractJavaScript(content, filePath) {
113
+ // For .svelte files, extract script content
114
+ if (filePath.endsWith('.svelte')) {
115
+ let scriptContent = '';
116
+ // Match <script> tags (both regular and module)
117
+ // Handles <script>, <script lang="ts">, <script context="module">, etc.
118
+ const scriptRegex = /<script[^>]*>([\s\S]*?)<\/script>/gi;
119
+ let match;
120
+ while ((match = scriptRegex.exec(content)) !== null) {
121
+ scriptContent += match[1] + '\n';
122
+ }
123
+ return scriptContent;
124
+ }
125
+ // For .ts, .js files, return content as-is
126
+ return content;
127
+ }
128
+ isExternalPackage(importPath) {
129
+ // External packages don't start with . or /
130
+ // They also don't start with configured aliases
131
+ if (importPath.startsWith('.') || importPath.startsWith('/')) {
132
+ return false;
133
+ }
134
+ // Check if it matches any configured alias
135
+ for (const alias of Object.keys(this.options.aliases)) {
136
+ if (importPath.startsWith(alias)) {
137
+ return false;
138
+ }
139
+ }
140
+ // Everything else is external
141
+ return true;
142
+ }
143
+ async resolveImport(importPath, fromFile) {
144
+ // Handle alias resolution first
145
+ for (const [alias, target] of Object.entries(this.options.aliases)) {
146
+ if (importPath.startsWith(alias)) {
147
+ const resolved = importPath.replace(alias, target);
148
+ importPath = path.resolve(this.options.projectRoot, resolved);
149
+ return this.tryResolveFile(importPath);
150
+ }
151
+ }
152
+ // Handle relative imports
153
+ if (importPath.startsWith('.')) {
154
+ const dir = path.dirname(fromFile);
155
+ const resolved = path.resolve(dir, importPath);
156
+ return this.tryResolveFile(resolved);
157
+ }
158
+ // Handle absolute imports
159
+ if (importPath.startsWith('/')) {
160
+ return this.tryResolveFile(importPath);
161
+ }
162
+ return null;
163
+ }
164
+ async tryResolveFile(filePath) {
165
+ // Try exact path first
166
+ try {
167
+ const stat = await fs.stat(filePath);
168
+ if (stat.isFile()) {
169
+ return filePath;
170
+ }
171
+ }
172
+ catch {
173
+ // Continue to try with extensions
174
+ }
175
+ // Try with common extensions
176
+ const extensions = ['.svelte', '.ts', '.js', '.tsx', '.jsx'];
177
+ for (const ext of extensions) {
178
+ const withExt = filePath + ext;
179
+ try {
180
+ const stat = await fs.stat(withExt);
181
+ if (stat.isFile()) {
182
+ return withExt;
183
+ }
184
+ }
185
+ catch {
186
+ continue;
187
+ }
188
+ }
189
+ // Try index files
190
+ for (const ext of extensions) {
191
+ const indexFile = path.join(filePath, `index${ext}`);
192
+ try {
193
+ const stat = await fs.stat(indexFile);
194
+ if (stat.isFile()) {
195
+ return indexFile;
196
+ }
197
+ }
198
+ catch {
199
+ continue;
200
+ }
201
+ }
202
+ return null;
203
+ }
204
+ }
205
+ //# sourceMappingURL=dependency_collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency_collector.js","sourceRoot":"","sources":["../../src/lint/dependency_collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AA8B9C,MAAM,OAAO,mBAAmB;IAS9B,YAAY,UAA4B,EAAE;QARlC,YAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAC5B,eAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,iBAAY,GAA0B,IAAI,GAAG,EAAE,CAAC;QAChD,aAAQ,GAAyB,EAAE,CAAC;QACpC,YAAO,GAAoB,EAAE,CAAC;QAE9B,gBAAW,GAAG,KAAK,CAAC;QAG1B,IAAI,CAAC,OAAO,GAAG;YACb,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;YACpC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK;YAC7C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE;SAClD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,kCAAkC;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC;YACX,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAElB,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAC7C,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAEtD,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAElC,yCAAyC;QACzC,MAAM,YAAY,GAAqB,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1D,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACvC,CAAC;QAED,OAAO;YACL,YAAY;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAgB;QACrC,qBAAqB;QACrB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEhD,2BAA2B;QAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAEpC,IAAI,CAAC;YACH,oBAAoB;YACpB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YAE3D,2EAA2E;YAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAElE,sCAAsC;YACtC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAEnC,MAAM,WAAW,GAAa,EAAE,CAAC;YAEjC,sBAAsB;YACtB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,eAAe,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,eAAe;oBAAE,SAAS;gBAE/B,wCAAwC;gBACxC,IAAI,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC;oBAC5C,SAAS;gBACX,CAAC;gBAED,0BAA0B;gBAC1B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,aAAa,CAC3C,eAAe,EACf,cAAc,CACf,CAAC;gBAEF,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;4BAChB,IAAI,EAAE,cAAc;4BACpB,UAAU,EAAE,eAAe;yBAC5B,CAAC,CAAC;oBACL,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAE/B,iDAAiD;gBACjD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACjB,IAAI,EAAE,cAAc;wBACpB,EAAE,EAAE,YAAY;qBACjB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBAED,mCAAmC;gBACnC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,6CAA6C;YAC7C,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,OAAe,EAAE,QAAgB;QACzD,4CAA4C;QAC5C,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,IAAI,aAAa,GAAG,EAAE,CAAC;YAEvB,gDAAgD;YAChD,wEAAwE;YACxE,MAAM,WAAW,GAAG,qCAAqC,CAAC;YAC1D,IAAI,KAAK,CAAC;YAEV,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBACpD,aAAa,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACnC,CAAC;YAED,OAAO,aAAa,CAAC;QACvB,CAAC;QAED,2CAA2C;QAC3C,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,iBAAiB,CAAC,UAAkB;QAC1C,4CAA4C;QAC5C,gDAAgD;QAChD,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,2CAA2C;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,8BAA8B;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,UAAkB,EAClB,QAAgB;QAEhB,gCAAgC;QAChC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACnE,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACnD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAC9D,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAED,0BAA0B;QAC1B,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC3C,uBAAuB;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;QAED,6BAA6B;QAC7B,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7D,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,QAAQ,GAAG,GAAG,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;oBAClB,OAAO,OAAO,CAAC;gBACjB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;oBAClB,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export declare class ESLintNotInstalledError extends Error {
2
+ name: "ESLintNotInstalledError";
3
+ constructor();
4
+ }
@@ -0,0 +1,10 @@
1
+ export class ESLintNotInstalledError extends Error {
2
+ constructor() {
3
+ super('forge lint requires ESLint and eslint-plugin-svelte. Install them with:\n\n' +
4
+ ' npm install eslint eslint-plugin-svelte\n\n' +
5
+ 'Then create an eslint.config.js in your project root.\n' +
6
+ 'See https://eslint.org/docs/user-guide/getting-started');
7
+ this.name = 'ESLintNotInstalledError';
8
+ }
9
+ }
10
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lint/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAGhD;QACE,KAAK,CACH,6EAA6E;YAC3E,+CAA+C;YAC/C,yDAAyD;YACzD,wDAAwD,CAC3D,CAAC;QARJ,SAAI,GAAG,yBAAkC,CAAC;IAS1C,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ type ESLintModule = typeof import('eslint');
2
+ export declare function loadESLint(): Promise<ESLintModule>;
3
+ export {};
@@ -0,0 +1,11 @@
1
+ import { ESLintNotInstalledError } from './errors.js';
2
+ export async function loadESLint() {
3
+ try {
4
+ const eslint = await import('eslint');
5
+ return eslint;
6
+ }
7
+ catch (error) {
8
+ throw new ESLintNotInstalledError();
9
+ }
10
+ }
11
+ //# sourceMappingURL=eslint_loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint_loader.js","sourceRoot":"","sources":["../../src/lint/eslint_loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAItD,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function findRouteConfig(rootDir: string): Promise<string | null>;
2
+ export declare function getSvelteFilesFromRoutes(cwd: string): Promise<string[]>;
@@ -0,0 +1,236 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import yaml from 'js-yaml';
4
+ const NOEGO_CONFIG_FILENAMES = [
5
+ 'noego.yaml',
6
+ 'noego.yml',
7
+ 'noego.config.yaml',
8
+ 'noego.config.yml',
9
+ 'app.yaml',
10
+ 'app.yml',
11
+ 'app.config.yaml',
12
+ 'app.config.yml',
13
+ 'hammer.yaml',
14
+ 'hammer.yml',
15
+ 'hammer.config.yaml',
16
+ 'hammer.config.yml',
17
+ ];
18
+ const ROUTE_CONFIG_FILENAMES = [
19
+ 'routes.yaml',
20
+ 'routes.yml',
21
+ 'api.yaml',
22
+ 'api.yml',
23
+ 'openapi.yaml',
24
+ 'openapi.yml',
25
+ 'stitch.yaml',
26
+ 'stitch.yml',
27
+ ];
28
+ async function findNoegoConfig(rootDir) {
29
+ for (const fileName of NOEGO_CONFIG_FILENAMES) {
30
+ const candidate = path.join(rootDir, fileName);
31
+ try {
32
+ await fs.access(candidate);
33
+ return candidate;
34
+ }
35
+ catch {
36
+ continue;
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+ export async function findRouteConfig(rootDir) {
42
+ // First, check if there's a noego.config.yml that points to the routes
43
+ const noegoConfigPath = await findNoegoConfig(rootDir);
44
+ if (process.env.DEBUG) {
45
+ console.log('[DEBUG] Looking for config in:', rootDir);
46
+ console.log('[DEBUG] Found noego config:', noegoConfigPath);
47
+ }
48
+ if (noegoConfigPath) {
49
+ try {
50
+ const content = await fs.readFile(noegoConfigPath, 'utf-8');
51
+ const config = yaml.load(content);
52
+ // Check for client.openapi path
53
+ if (config?.client?.openapi) {
54
+ const openapiPath = path.isAbsolute(config.client.openapi)
55
+ ? config.client.openapi
56
+ : path.resolve(rootDir, config.client.openapi);
57
+ if (process.env.DEBUG) {
58
+ console.log('[DEBUG] Checking client.openapi:', openapiPath);
59
+ }
60
+ try {
61
+ await fs.access(openapiPath);
62
+ if (process.env.DEBUG) {
63
+ console.log('[DEBUG] Found routes at:', openapiPath);
64
+ }
65
+ return openapiPath;
66
+ }
67
+ catch {
68
+ // Path in config doesn't exist, continue to fallback
69
+ }
70
+ }
71
+ // Check for server.openapi as fallback
72
+ if (config?.server?.openapi) {
73
+ const openapiPath = path.isAbsolute(config.server.openapi)
74
+ ? config.server.openapi
75
+ : path.resolve(rootDir, config.server.openapi);
76
+ try {
77
+ await fs.access(openapiPath);
78
+ return openapiPath;
79
+ }
80
+ catch {
81
+ // Path in config doesn't exist, continue to fallback
82
+ }
83
+ }
84
+ }
85
+ catch (error) {
86
+ // Config file couldn't be parsed, continue to fallback
87
+ }
88
+ }
89
+ // Fallback: Look for common route file names in the root
90
+ for (const fileName of ROUTE_CONFIG_FILENAMES) {
91
+ const candidate = path.join(rootDir, fileName);
92
+ try {
93
+ await fs.access(candidate);
94
+ return candidate;
95
+ }
96
+ catch {
97
+ continue;
98
+ }
99
+ }
100
+ return null;
101
+ }
102
+ function extractComponentsFromRoute(route, svelteFiles) {
103
+ if (route.view || route['x-view']) {
104
+ svelteFiles.add(route.view || route['x-view']);
105
+ }
106
+ if (route.layout || route['x-layout']) {
107
+ const layouts = route.layout || route['x-layout'];
108
+ if (Array.isArray(layouts)) {
109
+ for (const layout of layouts) {
110
+ svelteFiles.add(layout);
111
+ }
112
+ }
113
+ else if (layouts) {
114
+ svelteFiles.add(layouts);
115
+ }
116
+ }
117
+ }
118
+ async function parseYamlFile(filePath, processedFiles = new Set()) {
119
+ // Avoid circular references
120
+ if (processedFiles.has(filePath)) {
121
+ return {};
122
+ }
123
+ processedFiles.add(filePath);
124
+ const content = await fs.readFile(filePath, 'utf-8');
125
+ const config = yaml.load(content);
126
+ // Handle stitch files that reference other files
127
+ if (config?.stitch && Array.isArray(config.stitch)) {
128
+ const baseDir = path.dirname(filePath);
129
+ const mergedConfig = { paths: {}, modules: [] };
130
+ for (const stitchPattern of config.stitch) {
131
+ // Resolve glob patterns
132
+ const { glob } = await import('glob');
133
+ const resolvedPattern = path.resolve(baseDir, stitchPattern);
134
+ const files = await glob(resolvedPattern);
135
+ for (const file of files) {
136
+ const subConfig = await parseYamlFile(file, processedFiles);
137
+ // Merge paths
138
+ if (subConfig.paths) {
139
+ mergedConfig.paths = { ...mergedConfig.paths, ...subConfig.paths };
140
+ }
141
+ // Merge x-fallback values
142
+ if (subConfig['x-fallback-view'] && !mergedConfig['x-fallback-view']) {
143
+ mergedConfig['x-fallback-view'] = subConfig['x-fallback-view'];
144
+ }
145
+ if (subConfig['x-fallback-layout'] && !mergedConfig['x-fallback-layout']) {
146
+ mergedConfig['x-fallback-layout'] = subConfig['x-fallback-layout'];
147
+ }
148
+ }
149
+ }
150
+ return mergedConfig;
151
+ }
152
+ return config;
153
+ }
154
+ export async function getSvelteFilesFromRoutes(cwd) {
155
+ // Find the route configuration file
156
+ const routeConfigPath = await findRouteConfig(cwd);
157
+ if (!routeConfigPath) {
158
+ // No route config found, return empty array (will fall back to manual patterns)
159
+ return [];
160
+ }
161
+ // Get componentDir from noego.config.yml
162
+ let componentDir = cwd;
163
+ const noegoConfigPath = await findNoegoConfig(cwd);
164
+ if (noegoConfigPath) {
165
+ try {
166
+ const noegoContent = await fs.readFile(noegoConfigPath, 'utf-8');
167
+ const noegoConfig = yaml.load(noegoContent);
168
+ if (noegoConfig?.client?.componentDir) {
169
+ componentDir = path.resolve(cwd, noegoConfig.client.componentDir);
170
+ }
171
+ }
172
+ catch {
173
+ // Ignore errors, use cwd as fallback
174
+ }
175
+ }
176
+ // Read and parse the YAML file (handles stitch files)
177
+ const config = await parseYamlFile(routeConfigPath);
178
+ const svelteFiles = new Set();
179
+ // Add fallback view and layouts (x-fallback-view, x-fallback-layout)
180
+ if (config['x-fallback-view']) {
181
+ svelteFiles.add(config['x-fallback-view']);
182
+ }
183
+ if (config['x-fallback-layout']) {
184
+ const layouts = config['x-fallback-layout'];
185
+ if (Array.isArray(layouts)) {
186
+ for (const layout of layouts) {
187
+ svelteFiles.add(layout);
188
+ }
189
+ }
190
+ else {
191
+ svelteFiles.add(layouts);
192
+ }
193
+ }
194
+ // Extract components from paths
195
+ if (config.paths) {
196
+ for (const [pathName, pathConfig] of Object.entries(config.paths)) {
197
+ if (typeof pathConfig === 'object') {
198
+ // Check each HTTP method
199
+ for (const [method, methodConfig] of Object.entries(pathConfig)) {
200
+ if (typeof methodConfig === 'object') {
201
+ extractComponentsFromRoute(methodConfig, svelteFiles);
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ // Extract components from modules
208
+ if (config.modules) {
209
+ const modules = Array.isArray(config.modules)
210
+ ? config.modules
211
+ : Object.values(config.modules);
212
+ for (const module of modules) {
213
+ if (module.paths) {
214
+ for (const [pathName, pathConfig] of Object.entries(module.paths)) {
215
+ if (typeof pathConfig === 'object') {
216
+ for (const [method, methodConfig] of Object.entries(pathConfig)) {
217
+ if (typeof methodConfig === 'object') {
218
+ extractComponentsFromRoute(methodConfig, svelteFiles);
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ // Convert relative paths to absolute paths using componentDir as base
227
+ const absolutePaths = [];
228
+ for (const file of svelteFiles) {
229
+ const absolutePath = path.isAbsolute(file)
230
+ ? file
231
+ : path.resolve(componentDir, file);
232
+ absolutePaths.push(absolutePath);
233
+ }
234
+ return absolutePaths;
235
+ }
236
+ //# sourceMappingURL=route_parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route_parser.js","sourceRoot":"","sources":["../../src/lint/route_parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,220 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { describe, it, expect, beforeEach } from 'vitest';
4
+ import { DependencyCollector } from '../dependency_collector';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const FIXTURES = path.join(__dirname, 'fixtures/svelte');
8
+ describe('DependencyCollector', () => {
9
+ let collector;
10
+ beforeEach(() => {
11
+ collector = new DependencyCollector();
12
+ });
13
+ describe('Simple Imports', () => {
14
+ it('should collect direct imports from a component', async () => {
15
+ const result = await collector.collect(path.join(FIXTURES, 'simple/Card.svelte'));
16
+ // With recursive=true (default), collects Card and Button
17
+ expect(result.dependencies).toHaveLength(2);
18
+ // Find Card component
19
+ const cardDep = result.dependencies.find((d) => d.file.includes('Card.svelte'));
20
+ expect(cardDep).toBeDefined();
21
+ expect(cardDep.imports).toHaveLength(1);
22
+ expect(cardDep.imports[0]).toContain('Button.svelte');
23
+ });
24
+ it('should return empty imports for component with no imports', async () => {
25
+ const result = await collector.collect(path.join(FIXTURES, 'simple/Button.svelte'));
26
+ expect(result.dependencies).toHaveLength(1);
27
+ expect(result.dependencies[0].imports).toHaveLength(0);
28
+ });
29
+ });
30
+ describe('Nested Imports', () => {
31
+ it('should recursively collect all nested dependencies', async () => {
32
+ const result = await collector.collect(path.join(FIXTURES, 'nested/Parent.svelte'));
33
+ // Should have Parent, Child, and Grandchild
34
+ expect(result.dependencies.length).toBeGreaterThanOrEqual(3);
35
+ const files = result.dependencies.map((d) => path.basename(d.file));
36
+ expect(files).toContain('Parent.svelte');
37
+ expect(files).toContain('Child.svelte');
38
+ expect(files).toContain('Grandchild.svelte');
39
+ });
40
+ it('should maintain correct dependency relationships', async () => {
41
+ const result = await collector.collect(path.join(FIXTURES, 'nested/Parent.svelte'));
42
+ // Find Parent component
43
+ const parent = result.dependencies.find((d) => d.file.includes('Parent.svelte'));
44
+ expect(parent).toBeDefined();
45
+ expect(parent.imports[0]).toContain('Child.svelte');
46
+ // Find Child component
47
+ const child = result.dependencies.find((d) => d.file.includes('Child.svelte'));
48
+ expect(child).toBeDefined();
49
+ expect(child.imports[0]).toContain('Grandchild.svelte');
50
+ // Grandchild has no imports
51
+ const grandchild = result.dependencies.find((d) => d.file.includes('Grandchild.svelte'));
52
+ expect(grandchild).toBeDefined();
53
+ expect(grandchild.imports).toHaveLength(0);
54
+ });
55
+ it('should not collect dependencies when recursive is false', async () => {
56
+ const nonRecursiveCollector = new DependencyCollector({
57
+ recursive: false,
58
+ });
59
+ const result = await nonRecursiveCollector.collect(path.join(FIXTURES, 'nested/Parent.svelte'));
60
+ // Should only have Parent
61
+ expect(result.dependencies).toHaveLength(1);
62
+ expect(result.dependencies[0].file).toContain('Parent.svelte');
63
+ });
64
+ });
65
+ describe('Circular Dependencies', () => {
66
+ it('should detect circular dependencies', async () => {
67
+ const result = await collector.collect(path.join(FIXTURES, 'circular/A.svelte'));
68
+ expect(result.circular).toHaveLength(1);
69
+ // Circular can be detected in either direction (A→B or B→A)
70
+ const circular = result.circular[0];
71
+ const hasA = circular.from.includes('A.svelte') || circular.to.includes('A.svelte');
72
+ const hasB = circular.from.includes('B.svelte') || circular.to.includes('B.svelte');
73
+ expect(hasA).toBe(true);
74
+ expect(hasB).toBe(true);
75
+ });
76
+ it('should not infinitely recurse on circular deps', async () => {
77
+ // This test passes if it completes without hanging
78
+ const startTime = Date.now();
79
+ const result = await collector.collect(path.join(FIXTURES, 'circular/A.svelte'));
80
+ const duration = Date.now() - startTime;
81
+ expect(result).toBeDefined();
82
+ expect(result.dependencies).toBeDefined();
83
+ // Should complete in less than 1 second
84
+ expect(duration).toBeLessThan(1000);
85
+ });
86
+ it('should visit both components in circular dependency', async () => {
87
+ const result = await collector.collect(path.join(FIXTURES, 'circular/A.svelte'));
88
+ const files = result.dependencies.map((d) => path.basename(d.file));
89
+ expect(files).toContain('A.svelte');
90
+ expect(files).toContain('B.svelte');
91
+ });
92
+ });
93
+ describe('TypeScript Imports', () => {
94
+ it('should collect .ts file imports', async () => {
95
+ const result = await collector.collect(path.join(FIXTURES, 'typescript/Component.svelte'));
96
+ const files = result.dependencies.map((d) => d.file);
97
+ expect(files.some((f) => f.includes('helper.ts'))).toBe(true);
98
+ });
99
+ it('should parse TypeScript files for their imports', async () => {
100
+ const result = await collector.collect(path.join(FIXTURES, 'typescript/Component.svelte'));
101
+ // Component imports helper.ts, which has no further imports
102
+ const helperDep = result.dependencies.find((d) => d.file.includes('helper.ts'));
103
+ expect(helperDep).toBeDefined();
104
+ expect(helperDep.imports).toHaveLength(0);
105
+ });
106
+ });
107
+ describe('Mixed Imports', () => {
108
+ it('should handle both .svelte and .ts imports', async () => {
109
+ const result = await collector.collect(path.join(FIXTURES, 'mixed/App.svelte'));
110
+ const files = result.dependencies.map((d) => d.file);
111
+ expect(files.some((f) => f.includes('Button.svelte'))).toBe(true);
112
+ expect(files.some((f) => f.includes('format.ts'))).toBe(true);
113
+ });
114
+ it('should resolve imports in subdirectories', async () => {
115
+ const result = await collector.collect(path.join(FIXTURES, 'mixed/App.svelte'));
116
+ const appDep = result.dependencies.find((d) => d.file.includes('App.svelte'));
117
+ expect(appDep).toBeDefined();
118
+ expect(appDep.imports.length).toBeGreaterThanOrEqual(2);
119
+ });
120
+ });
121
+ describe('External Package Imports', () => {
122
+ it('should exclude node_modules imports by default', async () => {
123
+ const result = await collector.collect(path.join(FIXTURES, 'external/WithExternals.svelte'));
124
+ const files = result.dependencies.map((d) => d.file);
125
+ // Should not include 'svelte' or 'svelte/store'
126
+ expect(files.every((f) => !f.includes('node_modules'))).toBe(true);
127
+ expect(files.every((f) => !f.includes('svelte/store'))).toBe(true);
128
+ });
129
+ it('should include local imports even when mixed with external', async () => {
130
+ const result = await collector.collect(path.join(FIXTURES, 'external/WithExternals.svelte'));
131
+ const files = result.dependencies.map((d) => d.file);
132
+ expect(files.some((f) => f.includes('Local.svelte'))).toBe(true);
133
+ });
134
+ it('should handle components that only have external imports', async () => {
135
+ const result = await collector.collect(path.join(FIXTURES, 'external/Local.svelte'));
136
+ // Local.svelte has no imports
137
+ expect(result.dependencies).toHaveLength(1);
138
+ expect(result.dependencies[0].imports).toHaveLength(0);
139
+ });
140
+ });
141
+ describe('Svelte 5 Patterns', () => {
142
+ it('should parse components using $state rune', async () => {
143
+ const result = await collector.collect(path.join(FIXTURES, 'svelte5/WithRunes.svelte'));
144
+ expect(result.dependencies).toBeDefined();
145
+ expect(result.dependencies.length).toBeGreaterThanOrEqual(1);
146
+ const runesDep = result.dependencies.find((d) => d.file.includes('WithRunes.svelte'));
147
+ expect(runesDep).toBeDefined();
148
+ expect(runesDep.imports[0]).toContain('Counter.svelte');
149
+ });
150
+ it('should parse components with {#snippet} blocks', async () => {
151
+ const result = await collector.collect(path.join(FIXTURES, 'svelte5/WithSnippets.svelte'));
152
+ expect(result.dependencies).toBeDefined();
153
+ const snippetDep = result.dependencies.find((d) => d.file.includes('WithSnippets.svelte'));
154
+ expect(snippetDep).toBeDefined();
155
+ expect(snippetDep.imports[0]).toContain('Card.svelte');
156
+ });
157
+ it('should handle $props destructuring', async () => {
158
+ const result = await collector.collect(path.join(FIXTURES, 'svelte5/Card.svelte'));
159
+ expect(result.dependencies).toBeDefined();
160
+ const cardDep = result.dependencies.find((d) => d.file.includes('Card.svelte'));
161
+ expect(cardDep).toBeDefined();
162
+ });
163
+ });
164
+ describe('Error Handling', () => {
165
+ it('should throw error for non-existent file', async () => {
166
+ await expect(collector.collect('/path/to/nonexistent.svelte')).rejects.toThrow();
167
+ });
168
+ it('should report missing imports when reportMissing is true', async () => {
169
+ const reportingCollector = new DependencyCollector({
170
+ reportMissing: true,
171
+ });
172
+ const result = await reportingCollector.collect(path.join(FIXTURES, 'errors/MissingImport.svelte'));
173
+ expect(result.missing).toHaveLength(1);
174
+ expect(result.missing[0].file).toContain('MissingImport.svelte');
175
+ expect(result.missing[0].importPath).toBe('./DoesNotExist.svelte');
176
+ });
177
+ it('should continue processing when import is missing', async () => {
178
+ const reportingCollector = new DependencyCollector({
179
+ reportMissing: true,
180
+ });
181
+ const result = await reportingCollector.collect(path.join(FIXTURES, 'errors/MissingImport.svelte'));
182
+ // Should still have the MissingImport.svelte in dependencies
183
+ expect(result.dependencies).toHaveLength(1);
184
+ expect(result.dependencies[0].file).toContain('MissingImport.svelte');
185
+ });
186
+ });
187
+ describe('Path Resolution', () => {
188
+ it('should handle relative imports with ../', async () => {
189
+ // This is implicitly tested by nested imports,
190
+ // but we can be explicit
191
+ const result = await collector.collect(path.join(FIXTURES, 'simple/Card.svelte'));
192
+ const cardDep = result.dependencies.find((d) => d.file.includes('Card.svelte'));
193
+ expect(cardDep).toBeDefined();
194
+ expect(path.isAbsolute(cardDep.imports[0])).toBe(true);
195
+ });
196
+ it('should normalize paths consistently', async () => {
197
+ const result = await collector.collect(path.join(FIXTURES, 'nested/Parent.svelte'));
198
+ // All dependency file paths should be normalized
199
+ result.dependencies.forEach((dep) => {
200
+ expect(dep.file).toBe(path.normalize(dep.file));
201
+ dep.imports.forEach((imp) => {
202
+ expect(imp).toBe(path.normalize(imp));
203
+ });
204
+ });
205
+ });
206
+ });
207
+ describe('Collection Reset', () => {
208
+ it('should reset state between multiple collections', async () => {
209
+ // First collection
210
+ const result1 = await collector.collect(path.join(FIXTURES, 'circular/A.svelte'));
211
+ expect(result1.circular).toHaveLength(1);
212
+ // Second collection with different file
213
+ const result2 = await collector.collect(path.join(FIXTURES, 'simple/Button.svelte'));
214
+ // Should not have circular deps from previous run
215
+ expect(result2.circular).toHaveLength(0);
216
+ expect(result2.dependencies).toHaveLength(1);
217
+ });
218
+ });
219
+ });
220
+ //# sourceMappingURL=dependency_collector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency_collector.test.js","sourceRoot":"","sources":["../../../src/lint/tests/dependency_collector.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function format(text: string): string;
2
+ export declare function truncate(text: string, length: number): string;
@@ -0,0 +1,7 @@
1
+ export function format(text) {
2
+ return text.toUpperCase();
3
+ }
4
+ export function truncate(text, length) {
5
+ return text.length > length ? text.slice(0, length) + '...' : text;
6
+ }
7
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../../../../src/lint/tests/fixtures/svelte/mixed/utils/format.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,MAAc;IACnD,OAAO,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function formatDate(date: Date): string;
2
+ export declare function formatTime(date: Date): string;
3
+ export type DateFormat = 'iso' | 'locale';
4
+ export interface DateOptions {
5
+ format: DateFormat;
6
+ timezone?: string;
7
+ }
@@ -0,0 +1,7 @@
1
+ export function formatDate(date) {
2
+ return date.toISOString();
3
+ }
4
+ export function formatTime(date) {
5
+ return date.toLocaleTimeString();
6
+ }
7
+ //# sourceMappingURL=helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../../../../../src/lint/tests/fixtures/svelte/typescript/helper.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noego/forge",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "imports": {
@@ -25,8 +25,9 @@
25
25
  "build:client": "vite build",
26
26
  "build:ssr": "SSR=true vite build --ssr",
27
27
  "build:plugins": "tsc -p tsconfig.plugins.es.json && tsc -p tsconfig.plugins.cjs.json && node ./scripts/build-plugins.js",
28
+ "build:lint": "tsc -p tsconfig.lint.json",
28
29
  "build:options": "node ./scripts/build-options.js",
29
- "build": "npm run build:client && npm run build:ssr && npm run build:plugins && npm run build:options",
30
+ "build": "npm run build:client && npm run build:ssr && npm run build:plugins && npm run build:lint && npm run build:options",
30
31
  "prepare": "npm run build",
31
32
  "typecheck": "tsc --noEmit && svelte-check",
32
33
  "test:unit": "vitest"
@@ -87,12 +88,20 @@
87
88
  }
88
89
  },
89
90
  "peerDependencies": {
91
+ "eslint": "^9.0.0",
92
+ "eslint-plugin-svelte": "^2.0.0",
90
93
  "express": "^4",
91
94
  "playwright": "^1.40.0",
92
95
  "svelte": "^5.28.2",
93
96
  "tsx": "^4.0.0"
94
97
  },
95
98
  "peerDependenciesMeta": {
99
+ "eslint": {
100
+ "optional": true
101
+ },
102
+ "eslint-plugin-svelte": {
103
+ "optional": true
104
+ },
96
105
  "playwright": {
97
106
  "optional": true
98
107
  },
@@ -155,6 +164,7 @@
155
164
  "vite-plugin-dts": "^4.5.4"
156
165
  },
157
166
  "devDependencies": {
167
+ "@eslint/js": "^9.39.2",
158
168
  "@rollup/plugin-yaml": "^4.1.2",
159
169
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
160
170
  "@testing-library/dom": "^10.4.0",
@@ -168,8 +178,10 @@
168
178
  "@types/jsdom": "~21.1.7",
169
179
  "@types/minimist": "^1.2.5",
170
180
  "@types/node": "^22.15.3",
171
- "eslint": "^9.23.0",
181
+ "eslint": "^9.39.2",
182
+ "eslint-plugin-svelte": "^3.14.0",
172
183
  "express": "^4",
184
+ "globals": "^17.3.0",
173
185
  "http-proxy-middleware": "^3.0.5",
174
186
  "jest": "^29.7.0",
175
187
  "jsdom": "^26.0.0",
@@ -182,6 +194,7 @@
182
194
  "ts-node": "^10.9.2",
183
195
  "tsx": "^4.19.3",
184
196
  "typescript": "5.3.3",
197
+ "typescript-eslint": "^8.54.0",
185
198
  "typesync": "^0.14.3",
186
199
  "vite": "^6.3.5",
187
200
  "vitest": "3.1.1"