@rslint/core 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +39 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +147 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +128 -0
- package/dist/config-loader.d.ts +14 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +107 -0
- package/dist/configs/import.d.ts +6 -0
- package/dist/configs/import.d.ts.map +1 -0
- package/dist/configs/import.js +7 -0
- package/dist/configs/index.d.ts +12 -0
- package/dist/configs/index.d.ts.map +1 -0
- package/dist/configs/index.js +16 -0
- package/dist/configs/javascript.d.ts +6 -0
- package/dist/configs/javascript.d.ts.map +1 -0
- package/dist/configs/javascript.js +73 -0
- package/dist/configs/react.d.ts +6 -0
- package/dist/configs/react.d.ts.map +1 -0
- package/dist/configs/react.js +31 -0
- package/dist/configs/typescript.d.ts +8 -0
- package/dist/configs/typescript.d.ts.map +1 -0
- package/dist/configs/typescript.js +112 -0
- package/dist/define-config.d.ts +21 -0
- package/dist/define-config.d.ts.map +1 -0
- package/dist/define-config.js +6 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/node.d.ts +31 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +116 -0
- package/dist/service.d.ts +30 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +71 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types.d.ts +342 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +112 -0
- package/package.json +8 -8
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { RslintServiceInterface, RSlintOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Browser implementation of RslintService using web workers
|
|
4
|
+
*/
|
|
5
|
+
export declare class BrowserRslintService implements RslintServiceInterface {
|
|
6
|
+
private nextMessageId;
|
|
7
|
+
private pendingMessages;
|
|
8
|
+
private worker!;
|
|
9
|
+
private workerUrl;
|
|
10
|
+
private chunks;
|
|
11
|
+
private chunkSize;
|
|
12
|
+
private expectedSize;
|
|
13
|
+
constructor(options: RSlintOptions & {
|
|
14
|
+
workerUrl: string;
|
|
15
|
+
wasmUrl: string;
|
|
16
|
+
});
|
|
17
|
+
private ensureWorker;
|
|
18
|
+
/**
|
|
19
|
+
* Handle incoming binary data chunks
|
|
20
|
+
*/
|
|
21
|
+
private handlePacket;
|
|
22
|
+
/**
|
|
23
|
+
* Combine multiple Uint8Array chunks into a single Uint8Array
|
|
24
|
+
*/
|
|
25
|
+
private combineChunks;
|
|
26
|
+
/**
|
|
27
|
+
* Send a message to the worker
|
|
28
|
+
*/
|
|
29
|
+
sendMessage(kind: string, data: any): Promise<any>;
|
|
30
|
+
/**
|
|
31
|
+
* Handle messages from the worker
|
|
32
|
+
*/
|
|
33
|
+
private handleResponse;
|
|
34
|
+
/**
|
|
35
|
+
* Terminate the worker
|
|
36
|
+
*/
|
|
37
|
+
terminate(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EAKtB,aAAa,EAGd,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,oBAAqB,YAAW,sBAAsB;IACjE,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAgB;IAEpC,YAAY,OAAO,EAAE,aAAa,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAW1E;YAKa,YAAY;IAwB1B;;OAEG;IACH,OAAO,CAAC,YAAY;IA+CpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAWvD;IAED;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,SAAS,IAAI,IAAI,CAWhB;CACF"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser implementation of RslintService using web workers
|
|
3
|
+
*/
|
|
4
|
+
export class BrowserRslintService {
|
|
5
|
+
nextMessageId;
|
|
6
|
+
pendingMessages;
|
|
7
|
+
worker;
|
|
8
|
+
workerUrl;
|
|
9
|
+
chunks;
|
|
10
|
+
chunkSize;
|
|
11
|
+
expectedSize;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.nextMessageId = 1;
|
|
14
|
+
this.pendingMessages = new Map();
|
|
15
|
+
this.chunks = [];
|
|
16
|
+
this.chunkSize = 0;
|
|
17
|
+
this.expectedSize = null;
|
|
18
|
+
// In browser, we need to use a web worker that can run the rslint binary
|
|
19
|
+
// This would typically be a WASM version or a worker that can spawn processes
|
|
20
|
+
this.workerUrl = options.workerUrl;
|
|
21
|
+
this.ensureWorker(options.wasmUrl);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the web worker
|
|
25
|
+
*/
|
|
26
|
+
async ensureWorker(wasmUrl) {
|
|
27
|
+
if (!this.worker) {
|
|
28
|
+
this.worker = new Worker(this.workerUrl, { name: 'rslint-worker.js' });
|
|
29
|
+
this.worker.onmessage = event => {
|
|
30
|
+
this.handlePacket(event.data);
|
|
31
|
+
};
|
|
32
|
+
this.worker.onerror = error => {
|
|
33
|
+
console.error('Worker error:', error);
|
|
34
|
+
// Reject all pending messages
|
|
35
|
+
for (const [id, pending] of this.pendingMessages) {
|
|
36
|
+
pending.reject(new Error(`Worker error: ${error.message}`));
|
|
37
|
+
}
|
|
38
|
+
this.pendingMessages.clear();
|
|
39
|
+
};
|
|
40
|
+
this.worker.postMessage({
|
|
41
|
+
kind: 'init',
|
|
42
|
+
data: { version: '1.0.0', wasmURL: wasmUrl },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return this.worker;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Handle incoming binary data chunks
|
|
49
|
+
*/
|
|
50
|
+
handlePacket(chunk) {
|
|
51
|
+
this.chunks.push(chunk);
|
|
52
|
+
this.chunkSize += chunk.length;
|
|
53
|
+
// Process complete messages
|
|
54
|
+
while (true) {
|
|
55
|
+
// Read message length if we don't have it yet
|
|
56
|
+
if (this.expectedSize === null) {
|
|
57
|
+
if (this.chunkSize < 4)
|
|
58
|
+
return;
|
|
59
|
+
// Combine chunks to read the message length
|
|
60
|
+
const combined = this.combineChunks();
|
|
61
|
+
const dataView = new DataView(combined.buffer, combined.byteOffset, combined.byteLength);
|
|
62
|
+
this.expectedSize = dataView.getUint32(0, true); // true for little-endian
|
|
63
|
+
// Remove length bytes from buffer
|
|
64
|
+
this.chunks = [combined.slice(4)];
|
|
65
|
+
this.chunkSize -= 4;
|
|
66
|
+
}
|
|
67
|
+
// Check if we have the full message
|
|
68
|
+
if (this.chunkSize < this.expectedSize)
|
|
69
|
+
return;
|
|
70
|
+
// Read the message content
|
|
71
|
+
const combined = this.combineChunks();
|
|
72
|
+
const messageBytes = combined.slice(0, this.expectedSize);
|
|
73
|
+
const message = new TextDecoder().decode(messageBytes);
|
|
74
|
+
// Handle the message
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(message);
|
|
77
|
+
this.handleResponse(parsed);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error('Error parsing message:', err);
|
|
81
|
+
}
|
|
82
|
+
// Reset for next message
|
|
83
|
+
this.chunks = [combined.slice(this.expectedSize)];
|
|
84
|
+
this.chunkSize = this.chunks[0].length;
|
|
85
|
+
this.expectedSize = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Combine multiple Uint8Array chunks into a single Uint8Array
|
|
90
|
+
*/
|
|
91
|
+
combineChunks() {
|
|
92
|
+
if (this.chunks.length === 1) {
|
|
93
|
+
return this.chunks[0];
|
|
94
|
+
}
|
|
95
|
+
const totalLength = this.chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
96
|
+
const combined = new Uint8Array(totalLength);
|
|
97
|
+
let offset = 0;
|
|
98
|
+
for (const chunk of this.chunks) {
|
|
99
|
+
combined.set(chunk, offset);
|
|
100
|
+
offset += chunk.length;
|
|
101
|
+
}
|
|
102
|
+
return combined;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Send a message to the worker
|
|
106
|
+
*/
|
|
107
|
+
async sendMessage(kind, data) {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
const id = this.nextMessageId++;
|
|
110
|
+
const message = { id, kind, data };
|
|
111
|
+
// Register promise callbacks
|
|
112
|
+
this.pendingMessages.set(id, { resolve, reject });
|
|
113
|
+
// Send message to worker
|
|
114
|
+
this.worker.postMessage(message);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Handle messages from the worker
|
|
119
|
+
*/
|
|
120
|
+
handleResponse(message) {
|
|
121
|
+
const { id, kind, data } = message;
|
|
122
|
+
const pending = this.pendingMessages.get(id);
|
|
123
|
+
if (!pending)
|
|
124
|
+
return;
|
|
125
|
+
this.pendingMessages.delete(id);
|
|
126
|
+
if (kind === 'error') {
|
|
127
|
+
pending.reject(new Error(data.message));
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
pending.resolve(data);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Terminate the worker
|
|
135
|
+
*/
|
|
136
|
+
terminate() {
|
|
137
|
+
if (this.worker) {
|
|
138
|
+
// Reject all pending messages
|
|
139
|
+
for (const [id, pending] of this.pendingMessages) {
|
|
140
|
+
pending.reject(new Error('Service terminated'));
|
|
141
|
+
}
|
|
142
|
+
this.pendingMessages.clear();
|
|
143
|
+
this.worker.terminate();
|
|
144
|
+
this.worker = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAsHA,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B1E"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
import { parseArgs as nodeParseArgs } from 'node:util';
|
|
5
|
+
import { loadConfigFile, normalizeConfig, findJSConfig, } from './config-loader.js';
|
|
6
|
+
/**
|
|
7
|
+
* Pass-through execution of the Go binary with stdio inherited.
|
|
8
|
+
*/
|
|
9
|
+
function execBinary(binPath, argv) {
|
|
10
|
+
try {
|
|
11
|
+
execFileSync(binPath, argv, { stdio: 'inherit' });
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (isExecError(error))
|
|
16
|
+
return error.status;
|
|
17
|
+
process.stderr.write(`Failed to execute ${binPath}: ${String(error)}\n`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function isExecError(error) {
|
|
22
|
+
return (typeof error === 'object' &&
|
|
23
|
+
error !== null &&
|
|
24
|
+
'status' in error &&
|
|
25
|
+
typeof error.status === 'number');
|
|
26
|
+
}
|
|
27
|
+
function parseArgs(argv) {
|
|
28
|
+
const { values, tokens } = nodeParseArgs({
|
|
29
|
+
args: argv,
|
|
30
|
+
strict: false,
|
|
31
|
+
tokens: true,
|
|
32
|
+
options: {
|
|
33
|
+
config: { type: 'string' },
|
|
34
|
+
init: { type: 'boolean' },
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
// Collect args that are not --config or --init for pass-through to Go
|
|
38
|
+
const rest = [];
|
|
39
|
+
for (const token of tokens) {
|
|
40
|
+
if (token.kind === 'option') {
|
|
41
|
+
if (token.name === 'config' || token.name === 'init')
|
|
42
|
+
continue;
|
|
43
|
+
rest.push(token.rawName);
|
|
44
|
+
if (token.value != null)
|
|
45
|
+
rest.push(token.value);
|
|
46
|
+
}
|
|
47
|
+
else if (token.kind === 'option-terminator') {
|
|
48
|
+
rest.push('--');
|
|
49
|
+
}
|
|
50
|
+
else if (token.kind === 'positional') {
|
|
51
|
+
rest.push(token.value);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
raw: argv,
|
|
56
|
+
config: values.config ?? null,
|
|
57
|
+
init: values.init ?? false,
|
|
58
|
+
rest,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function isJSConfigFile(filePath) {
|
|
62
|
+
return /\.(ts|mts|js|mjs)$/.test(filePath);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Load JS config, serialize to JSON, and pipe to Go binary via stdin.
|
|
66
|
+
*/
|
|
67
|
+
async function runWithJSConfig(binPath, configPath, restArgs, cwd) {
|
|
68
|
+
let rawConfig;
|
|
69
|
+
try {
|
|
70
|
+
rawConfig = await loadConfigFile(configPath);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
74
|
+
process.stderr.write(`Error: failed to load config ${configPath}: ${msg}\n`);
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
let entries;
|
|
78
|
+
try {
|
|
79
|
+
entries = normalizeConfig(rawConfig);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
83
|
+
process.stderr.write(`Error: invalid config in ${configPath}: ${msg}\n`);
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
const configDir = path.dirname(path.resolve(cwd, configPath));
|
|
87
|
+
const payload = JSON.stringify({ configDirectory: configDir, entries });
|
|
88
|
+
try {
|
|
89
|
+
execFileSync(binPath, ['--config-stdin', ...restArgs], {
|
|
90
|
+
input: payload,
|
|
91
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
92
|
+
cwd,
|
|
93
|
+
});
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (isExecError(error))
|
|
98
|
+
return error.status;
|
|
99
|
+
process.stderr.write(`Failed to execute ${binPath}: ${String(error)}\n`);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function run(binPath, argv) {
|
|
104
|
+
const cwd = process.cwd();
|
|
105
|
+
const args = parseArgs(argv);
|
|
106
|
+
// --init: pass through to Go
|
|
107
|
+
if (args.init) {
|
|
108
|
+
return execBinary(binPath, ['--init']);
|
|
109
|
+
}
|
|
110
|
+
// Determine config file
|
|
111
|
+
let configPath = null;
|
|
112
|
+
if (args.config) {
|
|
113
|
+
configPath = path.resolve(cwd, args.config);
|
|
114
|
+
if (!fs.existsSync(configPath)) {
|
|
115
|
+
process.stderr.write(`Error: config file not found: ${configPath}\n`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
configPath = findJSConfig(cwd);
|
|
121
|
+
}
|
|
122
|
+
// JS config file: load + stdin pipe
|
|
123
|
+
if (configPath && isJSConfigFile(configPath)) {
|
|
124
|
+
return runWithJSConfig(binPath, configPath, args.rest, cwd);
|
|
125
|
+
}
|
|
126
|
+
// Fall back to Go binary (handles JSON config + deprecation warning)
|
|
127
|
+
return execBinary(binPath, args.raw);
|
|
128
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const JS_CONFIG_FILES: string[];
|
|
2
|
+
export declare function findJSConfig(cwd: string): string | null;
|
|
3
|
+
/**
|
|
4
|
+
* Load a JS/TS config file.
|
|
5
|
+
* - .js/.mjs: native import()
|
|
6
|
+
* - .ts/.mts: native import() when Node.js has TypeScript support (>= 22.6),
|
|
7
|
+
* otherwise fall back to jiti
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadConfigFile(configPath: string): Promise<unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Validate and strip non-serializable fields from the config.
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeConfig(config: unknown): Record<string, unknown>[];
|
|
14
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,UAK3B,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqCzE;AAuBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAqC1E"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { pathToFileURL } from 'node:url';
|
|
12
|
+
export const JS_CONFIG_FILES = [
|
|
13
|
+
'rslint.config.js',
|
|
14
|
+
'rslint.config.mjs',
|
|
15
|
+
'rslint.config.ts',
|
|
16
|
+
'rslint.config.mts',
|
|
17
|
+
];
|
|
18
|
+
export function findJSConfig(cwd) {
|
|
19
|
+
for (const name of JS_CONFIG_FILES) {
|
|
20
|
+
const p = path.join(cwd, name);
|
|
21
|
+
if (fs.existsSync(p))
|
|
22
|
+
return p;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load a JS/TS config file.
|
|
28
|
+
* - .js/.mjs: native import()
|
|
29
|
+
* - .ts/.mts: native import() when Node.js has TypeScript support (>= 22.6),
|
|
30
|
+
* otherwise fall back to jiti
|
|
31
|
+
*/
|
|
32
|
+
export async function loadConfigFile(configPath) {
|
|
33
|
+
const ext = path.extname(configPath);
|
|
34
|
+
if (ext === '.js' || ext === '.mjs') {
|
|
35
|
+
const mod = await import(__rewriteRelativeImportExtension(pathToFileURL(configPath).href));
|
|
36
|
+
return mod.default ?? mod;
|
|
37
|
+
}
|
|
38
|
+
if (ext === '.ts' || ext === '.mts') {
|
|
39
|
+
// Use feature detection to decide the loading strategy (same as rsbuild).
|
|
40
|
+
// process.features.typescript is available in Node.js >= 22.6.
|
|
41
|
+
const useNative = Boolean(process.features.typescript);
|
|
42
|
+
if (useNative) {
|
|
43
|
+
const mod = await import(__rewriteRelativeImportExtension(pathToFileURL(configPath).href));
|
|
44
|
+
return mod.default ?? mod;
|
|
45
|
+
}
|
|
46
|
+
const jiti = await loadJiti(configPath);
|
|
47
|
+
if (jiti) {
|
|
48
|
+
const resolved = await jiti.import(configPath);
|
|
49
|
+
return extractDefault(resolved);
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Failed to load TypeScript config file: ${configPath}\n` +
|
|
52
|
+
`To load .ts config files, either:\n` +
|
|
53
|
+
` 1. Use Node.js >= 22.6 (with native TypeScript support)\n` +
|
|
54
|
+
` 2. Install jiti as a dependency: npm install -D jiti`);
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`Unsupported config file extension: ${ext}`);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Try to load jiti (optional peer dependency).
|
|
60
|
+
*/
|
|
61
|
+
async function loadJiti(configPath) {
|
|
62
|
+
try {
|
|
63
|
+
const { createJiti } = await import('jiti');
|
|
64
|
+
return createJiti(path.dirname(configPath), { interopDefault: true });
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function extractDefault(mod) {
|
|
71
|
+
if (typeof mod === 'object' && mod !== null && 'default' in mod) {
|
|
72
|
+
return mod.default;
|
|
73
|
+
}
|
|
74
|
+
return mod;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate and strip non-serializable fields from the config.
|
|
78
|
+
*/
|
|
79
|
+
export function normalizeConfig(config) {
|
|
80
|
+
if (!Array.isArray(config)) {
|
|
81
|
+
throw new Error(`rslint config must export an array (flat config format), got ${typeof config}`);
|
|
82
|
+
}
|
|
83
|
+
return config
|
|
84
|
+
.filter((entry, index) => {
|
|
85
|
+
if (entry == null || typeof entry !== 'object') {
|
|
86
|
+
console.warn(`[rslint] Config entry at index ${index} is not an object (got ${entry === null ? 'null' : typeof entry}), skipping.`);
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
})
|
|
91
|
+
.map((entry, index) => {
|
|
92
|
+
if (entry.files != null && !Array.isArray(entry.files)) {
|
|
93
|
+
throw new Error(`[rslint] Config entry at index ${index}: "files" must be an array, got ${typeof entry.files}`);
|
|
94
|
+
}
|
|
95
|
+
if (entry.ignores != null && !Array.isArray(entry.ignores)) {
|
|
96
|
+
throw new Error(`[rslint] Config entry at index ${index}: "ignores" must be an array, got ${typeof entry.ignores}`);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
files: entry.files,
|
|
100
|
+
ignores: entry.ignores,
|
|
101
|
+
languageOptions: entry.languageOptions,
|
|
102
|
+
rules: entry.rules,
|
|
103
|
+
plugins: entry.plugins,
|
|
104
|
+
settings: entry.settings,
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RslintConfigEntry } from '../define-config.js';
|
|
2
|
+
// Aligned with official eslint-plugin-import recommended.
|
|
3
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
4
|
+
declare const recommended: RslintConfigEntry;
|
|
5
|
+
export { recommended };
|
|
6
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/configs/import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,0DAA0D;AAC1D,+FAA+F;AAC/F,QAAA,MAAM,WAAW,EAAE,iBAclB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RslintConfigEntry } from '../define-config.js';
|
|
2
|
+
interface PluginExport {
|
|
3
|
+
configs: {
|
|
4
|
+
recommended: RslintConfigEntry;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export declare const ts: PluginExport;
|
|
8
|
+
export declare const js: PluginExport;
|
|
9
|
+
export declare const reactPlugin: PluginExport;
|
|
10
|
+
export declare const importPlugin: PluginExport;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,UAAU,YAAY;IACpB,OAAO,EAAE;QAAE,WAAW,EAAE,iBAAiB,CAAA;KAAE,CAAC;CAC7C;AAED,eAAO,MAAM,EAAE,EAAE,YAEhB,CAAC;AAEF,eAAO,MAAM,EAAE,EAAE,YAEhB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAEzB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAE1B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { recommended as tsRecommended } from './typescript.js';
|
|
2
|
+
import { recommended as jsRecommended } from './javascript.js';
|
|
3
|
+
import { recommended as reactRecommended } from './react.js';
|
|
4
|
+
import { recommended as importRecommended } from './import.js';
|
|
5
|
+
export const ts = {
|
|
6
|
+
configs: { recommended: tsRecommended },
|
|
7
|
+
};
|
|
8
|
+
export const js = {
|
|
9
|
+
configs: { recommended: jsRecommended },
|
|
10
|
+
};
|
|
11
|
+
export const reactPlugin = {
|
|
12
|
+
configs: { recommended: reactRecommended },
|
|
13
|
+
};
|
|
14
|
+
export const importPlugin = {
|
|
15
|
+
configs: { recommended: importRecommended },
|
|
16
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RslintConfigEntry } from '../define-config.js';
|
|
2
|
+
// Aligned with official eslint:recommended.
|
|
3
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
4
|
+
declare const recommended: RslintConfigEntry;
|
|
5
|
+
export { recommended };
|
|
6
|
+
//# sourceMappingURL=javascript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/configs/javascript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,4CAA4C;AAC5C,+FAA+F;AAC/F,QAAA,MAAM,WAAW,EAAE,iBAqElB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Aligned with official eslint:recommended.
|
|
2
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
3
|
+
const recommended = {
|
|
4
|
+
files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
|
|
5
|
+
rules: {
|
|
6
|
+
'constructor-super': 'error',
|
|
7
|
+
// 'no-control-regex': 'error', // not implemented
|
|
8
|
+
// 'no-delete-var': 'error', // not implemented
|
|
9
|
+
// 'no-dupe-class-members': 'error', // not implemented
|
|
10
|
+
// 'no-dupe-else-if': 'error', // not implemented
|
|
11
|
+
// 'no-empty-character-class': 'error', // not implemented
|
|
12
|
+
// 'no-empty-static-block': 'error', // not implemented
|
|
13
|
+
// 'no-ex-assign': 'error', // not implemented
|
|
14
|
+
// 'no-extra-boolean-cast': 'error', // not implemented
|
|
15
|
+
// 'no-fallthrough': 'error', // not implemented
|
|
16
|
+
// 'no-func-assign': 'error', // not implemented
|
|
17
|
+
// 'no-global-assign': 'error', // not implemented
|
|
18
|
+
// 'no-import-assign': 'error', // not implemented
|
|
19
|
+
// 'no-invalid-regexp': 'error', // not implemented
|
|
20
|
+
// 'no-irregular-whitespace': 'error', // not implemented
|
|
21
|
+
// 'no-misleading-character-class': 'error', // not implemented
|
|
22
|
+
// 'no-new-native-nonconstructor': 'error', // not implemented
|
|
23
|
+
// 'no-new-symbol': 'error', // not implemented (deprecated, use no-new-native-nonconstructor)
|
|
24
|
+
// 'no-nonoctal-decimal-escape': 'error', // not implemented
|
|
25
|
+
// 'no-obj-calls': 'error', // not implemented
|
|
26
|
+
// 'no-octal': 'error', // not implemented
|
|
27
|
+
// 'no-prototype-builtins': 'error', // not implemented
|
|
28
|
+
// 'no-redeclare': 'error', // not implemented
|
|
29
|
+
// 'no-regex-spaces': 'error', // not implemented
|
|
30
|
+
// 'no-self-assign': 'error', // not implemented
|
|
31
|
+
// 'no-setter-return': 'error', // not implemented
|
|
32
|
+
// 'no-shadow-restricted-names': 'error', // not implemented
|
|
33
|
+
// 'no-this-before-super': 'error', // not implemented
|
|
34
|
+
// 'no-undef': 'error', // not implemented
|
|
35
|
+
// 'no-unexpected-multiline': 'error', // not implemented
|
|
36
|
+
// 'no-unreachable': 'error', // not implemented
|
|
37
|
+
// 'no-unsafe-finally': 'error', // not implemented
|
|
38
|
+
// 'no-unsafe-negation': 'error', // not implemented
|
|
39
|
+
// 'no-unsafe-optional-chaining': 'error', // not implemented
|
|
40
|
+
// 'no-unused-labels': 'error', // not implemented
|
|
41
|
+
// 'no-unused-private-class-members': 'error', // not implemented
|
|
42
|
+
// 'no-unused-vars': 'error', // not implemented
|
|
43
|
+
// 'no-unassigned-vars': 'error', // not implemented
|
|
44
|
+
// 'no-useless-assignment': 'error', // not implemented
|
|
45
|
+
// 'no-useless-backreference': 'error', // not implemented
|
|
46
|
+
// 'no-useless-catch': 'error', // not implemented
|
|
47
|
+
// 'no-useless-escape': 'error', // not implemented
|
|
48
|
+
// 'no-with': 'error', // not implemented
|
|
49
|
+
// 'preserve-caught-error': 'error', // not implemented
|
|
50
|
+
// 'require-yield': 'error', // not implemented
|
|
51
|
+
// 'use-isnan': 'error', // not implemented
|
|
52
|
+
// 'valid-typeof': 'error', // not implemented
|
|
53
|
+
'for-direction': 'error',
|
|
54
|
+
'getter-return': 'error',
|
|
55
|
+
'no-async-promise-executor': 'error',
|
|
56
|
+
'no-case-declarations': 'error',
|
|
57
|
+
'no-class-assign': 'error',
|
|
58
|
+
'no-compare-neg-zero': 'error',
|
|
59
|
+
'no-cond-assign': 'error',
|
|
60
|
+
'no-const-assign': 'error',
|
|
61
|
+
'no-constant-binary-expression': 'error',
|
|
62
|
+
'no-constant-condition': 'error',
|
|
63
|
+
'no-debugger': 'error',
|
|
64
|
+
'no-dupe-args': 'error',
|
|
65
|
+
'no-dupe-keys': 'error',
|
|
66
|
+
'no-duplicate-case': 'error',
|
|
67
|
+
'no-empty': 'error',
|
|
68
|
+
'no-empty-pattern': 'error',
|
|
69
|
+
'no-loss-of-precision': 'error',
|
|
70
|
+
'no-sparse-arrays': 'error',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
export { recommended };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RslintConfigEntry } from '../define-config.js';
|
|
2
|
+
// Aligned with official eslint-plugin-react recommended.
|
|
3
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
4
|
+
declare const recommended: RslintConfigEntry;
|
|
5
|
+
export { recommended };
|
|
6
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/configs/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yDAAyD;AACzD,+FAA+F;AAC/F,QAAA,MAAM,WAAW,EAAE,iBA2BlB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Aligned with official eslint-plugin-react recommended.
|
|
2
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
3
|
+
const recommended = {
|
|
4
|
+
files: ['**/*.jsx', '**/*.tsx'],
|
|
5
|
+
plugins: ['react'],
|
|
6
|
+
rules: {
|
|
7
|
+
// 'react/display-name': 'error', // not implemented
|
|
8
|
+
// 'react/jsx-key': 'error', // not implemented
|
|
9
|
+
// 'react/jsx-no-comment-textnodes': 'error', // not implemented
|
|
10
|
+
// 'react/jsx-no-duplicate-props': 'error', // not implemented
|
|
11
|
+
// 'react/jsx-no-target-blank': 'error', // not implemented
|
|
12
|
+
// 'react/jsx-no-undef': 'error', // not implemented
|
|
13
|
+
'react/jsx-uses-react': 'error',
|
|
14
|
+
'react/jsx-uses-vars': 'error',
|
|
15
|
+
// 'react/no-children-prop': 'error', // not implemented
|
|
16
|
+
// 'react/no-danger-with-children': 'error', // not implemented
|
|
17
|
+
// 'react/no-deprecated': 'error', // not implemented
|
|
18
|
+
// 'react/no-direct-mutation-state': 'error', // not implemented
|
|
19
|
+
// 'react/no-find-dom-node': 'error', // not implemented
|
|
20
|
+
// 'react/no-is-mounted': 'error', // not implemented
|
|
21
|
+
// 'react/no-render-return-value': 'error', // not implemented
|
|
22
|
+
// 'react/no-string-refs': 'error', // not implemented
|
|
23
|
+
// 'react/no-unescaped-entities': 'error', // not implemented
|
|
24
|
+
// 'react/no-unknown-property': 'error', // not implemented
|
|
25
|
+
'react/no-unsafe': 'off',
|
|
26
|
+
// 'react/prop-types': 'error', // not implemented
|
|
27
|
+
'react/react-in-jsx-scope': 'error',
|
|
28
|
+
// 'react/require-render-return': 'error', // not implemented
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export { recommended };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RslintConfigEntry } from '../define-config.js';
|
|
2
|
+
// Aligned with official @typescript-eslint/recommended.
|
|
3
|
+
// Includes the eslint-recommended override layer (disables core rules handled by TS,
|
|
4
|
+
// enables TS-beneficial rules).
|
|
5
|
+
// Rules commented out with "not implemented" are in the official preset but not yet available.
|
|
6
|
+
declare const recommended: RslintConfigEntry;
|
|
7
|
+
export { recommended };
|
|
8
|
+
//# sourceMappingURL=typescript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/configs/typescript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,wDAAwD;AACxD,qFAAqF;AACrF,gCAAgC;AAChC,+FAA+F;AAC/F,QAAA,MAAM,WAAW,EAAE,iBA6GlB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
|