@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 +18 -2
- package/dist/lint/cli.d.ts +9 -0
- package/dist/lint/cli.js +228 -0
- package/dist/lint/cli.js.map +1 -0
- package/dist/lint/config.d.ts +6 -0
- package/dist/lint/config.js +49 -0
- package/dist/lint/config.js.map +1 -0
- package/dist/lint/dependency_collector.d.ts +39 -0
- package/dist/lint/dependency_collector.js +205 -0
- package/dist/lint/dependency_collector.js.map +1 -0
- package/dist/lint/errors.d.ts +4 -0
- package/dist/lint/errors.js +10 -0
- package/dist/lint/errors.js.map +1 -0
- package/dist/lint/eslint_loader.d.ts +3 -0
- package/dist/lint/eslint_loader.js +11 -0
- package/dist/lint/eslint_loader.js.map +1 -0
- package/dist/lint/route_parser.d.ts +2 -0
- package/dist/lint/route_parser.js +236 -0
- package/dist/lint/route_parser.js.map +1 -0
- package/dist/lint/tests/dependency_collector.test.d.ts +1 -0
- package/dist/lint/tests/dependency_collector.test.js +220 -0
- package/dist/lint/tests/dependency_collector.test.js.map +1 -0
- package/dist/lint/tests/fixtures/svelte/mixed/utils/format.d.ts +2 -0
- package/dist/lint/tests/fixtures/svelte/mixed/utils/format.js +7 -0
- package/dist/lint/tests/fixtures/svelte/mixed/utils/format.js.map +1 -0
- package/dist/lint/tests/fixtures/svelte/typescript/helper.d.ts +7 -0
- package/dist/lint/tests/fixtures/svelte/typescript/helper.js +7 -0
- package/dist/lint/tests/fixtures/svelte/typescript/helper.js.map +1 -0
- package/package.json +16 -3
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('
|
|
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"');
|
package/dist/lint/cli.js
ADDED
|
@@ -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,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":"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"}
|
|
@@ -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,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,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":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAEzD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,SAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAC1C,CAAC;YAEF,0DAA0D;YAC1D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAE5C,sBAAsB;YACtB,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAC/B,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,CAAC,OAAQ,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,OAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,4CAA4C;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAE7D,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,wBAAwB;YACxB,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CACjC,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;YAErD,uBAAuB;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAChC,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YAEzD,4BAA4B;YAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAChD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CACrC,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,UAAW,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,qBAAqB,GAAG,IAAI,mBAAmB,CAAC;gBACpD,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,0BAA0B;YAC1B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CACzC,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,4DAA4D;YAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACpF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACpF,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,mDAAmD;YACnD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CACzC,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAExC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1C,wCAAwC;YACxC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CACzC,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACnD,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACnD,CAAC;YAEF,4DAA4D;YAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC7B,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;YAChC,MAAM,CAAC,SAAU,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CACxC,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CACxC,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC9B,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,+BAA+B,CAAC,CACrD,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrD,gDAAgD;YAChD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,+BAA+B,CAAC,CACrD,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAC7C,CAAC;YAEF,8BAA8B;YAC9B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAChD,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAE7D,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CACpC,CAAC;YACF,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,QAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACnD,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAChD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CACvC,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,UAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAC3C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAC/B,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,MAAM,CACV,SAAS,CAAC,OAAO,CAAC,6BAA6B,CAAC,CACjD,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,kBAAkB,GAAG,IAAI,mBAAmB,CAAC;gBACjD,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACnD,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACjE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,kBAAkB,GAAG,IAAI,mBAAmB,CAAC;gBACjD,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACnD,CAAC;YAEF,6DAA6D;YAC7D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,+CAA+C;YAC/C,yBAAyB;YACzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAC1C,CAAC;YAEF,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAC/B,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,iDAAiD;YACjD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,mBAAmB;YACnB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CACrC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CACzC,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAEzC,wCAAwC;YACxC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CACrC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC5C,CAAC;YAEF,kDAAkD;YAClD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -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 @@
|
|
|
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.
|
|
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.
|
|
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"
|