@astrale-os/sdk 0.4.18 → 0.4.19
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/README.md +2 -2
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +22 -1
- package/dist/cli/run.js.map +1 -1
- package/dist/domain/define.d.ts.map +1 -1
- package/dist/domain/define.js +2 -1
- package/dist/domain/define.js.map +1 -1
- package/dist/linter/diagnostic.d.ts +7 -1
- package/dist/linter/diagnostic.d.ts.map +1 -1
- package/dist/linter/diagnostic.js +3 -1
- package/dist/linter/diagnostic.js.map +1 -1
- package/dist/linter/index.d.ts +1 -1
- package/dist/linter/index.d.ts.map +1 -1
- package/dist/linter/index.js.map +1 -1
- package/dist/linter/lint.d.ts +2 -0
- package/dist/linter/lint.d.ts.map +1 -1
- package/dist/linter/lint.js +1 -1
- package/dist/linter/lint.js.map +1 -1
- package/dist/linter/oxlint/config.d.ts +1 -0
- package/dist/linter/oxlint/config.d.ts.map +1 -1
- package/dist/linter/oxlint/config.js +5 -0
- package/dist/linter/oxlint/config.js.map +1 -1
- package/dist/linter/oxlint/ignore-patterns.d.ts +9 -0
- package/dist/linter/oxlint/ignore-patterns.d.ts.map +1 -0
- package/dist/linter/oxlint/ignore-patterns.js +18 -0
- package/dist/linter/oxlint/ignore-patterns.js.map +1 -0
- package/dist/linter/oxlint/process.d.ts +19 -0
- package/dist/linter/oxlint/process.d.ts.map +1 -0
- package/dist/linter/oxlint/process.js +170 -0
- package/dist/linter/oxlint/process.js.map +1 -0
- package/dist/linter/oxlint/run.d.ts +2 -1
- package/dist/linter/oxlint/run.d.ts.map +1 -1
- package/dist/linter/oxlint/run.js +36 -26
- package/dist/linter/oxlint/run.js.map +1 -1
- package/dist/linter/preflight.d.ts.map +1 -1
- package/dist/linter/preflight.js +1 -1
- package/dist/linter/preflight.js.map +1 -1
- package/package.json +12 -5
- package/src/cli/run.ts +21 -1
- package/src/domain/define.ts +2 -1
- package/src/linter/diagnostic.ts +18 -1
- package/src/linter/index.ts +1 -0
- package/src/linter/lint.ts +3 -1
- package/src/linter/oxlint/config.ts +5 -0
- package/src/linter/oxlint/ignore-patterns.ts +17 -0
- package/src/linter/oxlint/process.ts +219 -0
- package/src/linter/oxlint/run.ts +42 -29
- package/src/linter/preflight.ts +1 -0
|
@@ -1,50 +1,48 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
1
|
import { existsSync } from 'node:fs';
|
|
3
2
|
import { createRequire } from 'node:module';
|
|
4
3
|
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
5
4
|
import { fileURLToPath } from 'node:url';
|
|
6
5
|
import { LinterToolError } from '../diagnostic.js';
|
|
7
6
|
import { ruleInfo } from '../rules/catalog.js';
|
|
8
|
-
|
|
7
|
+
import { DOMAIN_OXLINT_IGNORE_PATTERNS } from './ignore-patterns.js';
|
|
8
|
+
import { runOxlintProcess } from './process.js';
|
|
9
|
+
export async function runOxlint(root, fix, options = {}) {
|
|
9
10
|
const packageJson = join(root, 'package.json');
|
|
10
11
|
const projectRequire = createRequire(packageJson);
|
|
11
12
|
const sdkRequire = createRequire(import.meta.url);
|
|
12
13
|
const oxlintPackage = resolvePackage('oxlint/package.json', projectRequire, sdkRequire);
|
|
13
14
|
const bin = join(dirname(oxlintPackage), 'bin', 'oxlint');
|
|
14
15
|
const config = projectConfig(root) ?? internalConfigPath();
|
|
15
|
-
const args = [
|
|
16
|
+
const args = ['.', '--format=json', '--no-error-on-unmatched-pattern', '--config', config];
|
|
17
|
+
// Config-file ignores are rooted at the config's own directory. Enforce the
|
|
18
|
+
// SDK's traversal boundary at the target process as well so the internal
|
|
19
|
+
// fallback config and imported presets cannot discover dependency/build trees.
|
|
20
|
+
for (const pattern of DOMAIN_OXLINT_IGNORE_PATTERNS)
|
|
21
|
+
args.push('--ignore-pattern', pattern);
|
|
16
22
|
if (fix)
|
|
17
23
|
args.push('--fix');
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
child.stderr.setEncoding('utf8');
|
|
27
|
-
child.stdout.on('data', (chunk) => (stdout += chunk));
|
|
28
|
-
child.stderr.on('data', (chunk) => (stderr += chunk));
|
|
29
|
-
const status = await new Promise((resolveStatus, reject) => {
|
|
30
|
-
child.once('error', reject);
|
|
31
|
-
child.once('close', resolveStatus);
|
|
32
|
-
}).catch((error) => {
|
|
33
|
-
throw new LinterToolError(`Could not start Oxlint at ${bin}.`, { cause: error });
|
|
34
|
-
});
|
|
24
|
+
const { status, signal, stdout, stderr } = await runOxlintProcess(bin, args, root, options);
|
|
25
|
+
if (status !== 0 && status !== 1) {
|
|
26
|
+
const outcome = signal ? `signal ${signal}` : `status ${status ?? 'unknown'}`;
|
|
27
|
+
const detail = failureDetail(stderr, stdout);
|
|
28
|
+
throw new LinterToolError(`Oxlint failed with ${outcome}.${detail ? `\n${detail}` : ''}`, {
|
|
29
|
+
code: 'OXLINT_FAILED',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
35
32
|
let output;
|
|
36
33
|
try {
|
|
37
|
-
|
|
34
|
+
const parsed = JSON.parse(stdout);
|
|
35
|
+
if (!isOxlintOutput(parsed))
|
|
36
|
+
throw new TypeError('Unexpected Oxlint report shape.');
|
|
37
|
+
output = parsed;
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
40
|
-
const detail = stderr
|
|
40
|
+
const detail = failureDetail(stderr, stdout) || `Oxlint exited with status ${status}`;
|
|
41
41
|
throw new LinterToolError(`Oxlint did not produce a diagnostic report.\n${detail}`, {
|
|
42
|
+
code: 'OXLINT_INVALID_OUTPUT',
|
|
42
43
|
cause: error,
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
|
-
if (status !== 0 && status !== 1) {
|
|
46
|
-
throw new LinterToolError(`Oxlint failed with status ${status ?? 'unknown'}.${stderr.trim() ? `\n${stderr.trim()}` : ''}`);
|
|
47
|
-
}
|
|
48
46
|
return {
|
|
49
47
|
diagnostics: (output.diagnostics ?? []).map((diagnostic) => normalizeDiagnostic(root, diagnostic)),
|
|
50
48
|
files: output.number_of_files ?? 0,
|
|
@@ -59,10 +57,22 @@ function resolvePackage(id, projectRequire, sdkRequire) {
|
|
|
59
57
|
return sdkRequire.resolve(id);
|
|
60
58
|
}
|
|
61
59
|
catch {
|
|
62
|
-
throw new LinterToolError('Oxlint is not installed. Add the scaffolded Oxlint dev dependency and run your package manager install.', { cause: projectError });
|
|
60
|
+
throw new LinterToolError('Oxlint is not installed. Add the scaffolded Oxlint dev dependency and run your package manager install.', { code: 'OXLINT_NOT_INSTALLED', cause: projectError });
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
}
|
|
64
|
+
function isOxlintOutput(value) {
|
|
65
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
66
|
+
return false;
|
|
67
|
+
const output = value;
|
|
68
|
+
return ((output.diagnostics === undefined || Array.isArray(output.diagnostics)) &&
|
|
69
|
+
(output.number_of_files === undefined || typeof output.number_of_files === 'number'));
|
|
70
|
+
}
|
|
71
|
+
function failureDetail(stderr, stdout) {
|
|
72
|
+
const detail = stderr.trim() || stdout.trim();
|
|
73
|
+
const limit = 4_000;
|
|
74
|
+
return detail.length <= limit ? detail : `…${detail.slice(-limit)}`;
|
|
75
|
+
}
|
|
66
76
|
function projectConfig(root) {
|
|
67
77
|
for (const name of [
|
|
68
78
|
'oxlint.config.ts',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/linter/oxlint/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/linter/oxlint/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/linter/preflight.ts"],"names":[],"mappings":"AA4BA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/linter/preflight.ts"],"names":[],"mappings":"AA4BA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB1E"}
|
package/dist/linter/preflight.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function assertSingleTypeUniverse(root) {
|
|
|
28
28
|
continue;
|
|
29
29
|
const detail = formatResolutions(resolutions);
|
|
30
30
|
throw new LinterToolError(`Multiple physical installations of ${packageName} would create incompatible Astrale types.\n` +
|
|
31
|
-
`${detail}\nReinstall the workspace so every member resolves one compatible package instance
|
|
31
|
+
`${detail}\nReinstall the workspace so every member resolves one compatible package instance.`, { code: 'LINTER_PREFLIGHT_FAILED' });
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
function formatResolutions(resolutions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/linter/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,eAAe,GAAG;IACtB,2BAA2B;IAC3B,yBAAyB;IACzB,wBAAwB;CAChB,CAAA;AAEV,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAc/E,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAY;IACzD,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAA;IACtD,MAAM,SAAS,GAAG;QAChB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE;KAChE,CAAA;IAED,KAAK,MAAM,WAAW,IAAI,eAAe,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAiB,EAAE,CAAA;QACpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;YACrE,IAAI,QAAQ;gBAAE,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC9E,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;QACvE,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC;YAAE,SAAQ;QAC7B,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;QAC7C,MAAM,IAAI,eAAe,CACvB,sCAAsC,WAAW,6CAA6C;YAC5F,GAAG,MAAM,qFAAqF,
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/linter/preflight.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.19",
|
|
4
4
|
"description": "Astrale Remote Domain SDK - Define and deploy domains as standalone Hono servers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astrale",
|
|
@@ -65,11 +65,11 @@
|
|
|
65
65
|
"./package.json": "./package.json"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@astrale-os/kernel-api": ">=0.4.
|
|
69
|
-
"@astrale-os/kernel-client": ">=0.4.
|
|
70
|
-
"@astrale-os/kernel-core": ">=0.7.
|
|
68
|
+
"@astrale-os/kernel-api": ">=0.4.16 <1.0.0",
|
|
69
|
+
"@astrale-os/kernel-client": ">=0.4.11 <1.0.0",
|
|
70
|
+
"@astrale-os/kernel-core": ">=0.7.7 <1.0.0",
|
|
71
71
|
"@astrale-os/kernel-dsl": ">=0.1.4 <1.0.0",
|
|
72
|
-
"@astrale-os/kernel-server": ">=0.4.
|
|
72
|
+
"@astrale-os/kernel-server": ">=0.4.15 <1.0.0",
|
|
73
73
|
"hono": "^4.6.20",
|
|
74
74
|
"jose": "^6.1.3",
|
|
75
75
|
"zod": "^4.3.6"
|
|
@@ -117,6 +117,13 @@
|
|
|
117
117
|
"oxfmt --write"
|
|
118
118
|
]
|
|
119
119
|
},
|
|
120
|
+
"devEngines": {
|
|
121
|
+
"runtime": {
|
|
122
|
+
"name": "node",
|
|
123
|
+
"version": ">=24 <25",
|
|
124
|
+
"onFail": "error"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
120
127
|
"engines": {
|
|
121
128
|
"node": ">=22"
|
|
122
129
|
},
|
package/src/cli/run.ts
CHANGED
|
@@ -105,16 +105,36 @@ export async function run(argv: readonly string[]): Promise<number> {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
if (parsed.command === 'lint') {
|
|
108
|
+
const controller = new AbortController()
|
|
109
|
+
let receivedSignal: NodeJS.Signals | undefined
|
|
110
|
+
const cancel = (signal: NodeJS.Signals) => {
|
|
111
|
+
receivedSignal ??= signal
|
|
112
|
+
controller.abort(new Error(`Received ${signal}.`))
|
|
113
|
+
}
|
|
114
|
+
const onSigint = () => cancel('SIGINT')
|
|
115
|
+
const onSigterm = () => cancel('SIGTERM')
|
|
116
|
+
process.once('SIGINT', onSigint)
|
|
117
|
+
process.once('SIGTERM', onSigterm)
|
|
108
118
|
try {
|
|
109
|
-
const result = await lintDomain({
|
|
119
|
+
const result = await lintDomain({
|
|
120
|
+
root: process.cwd(),
|
|
121
|
+
fix: parsed.fix ?? false,
|
|
122
|
+
signal: controller.signal,
|
|
123
|
+
})
|
|
110
124
|
process.stdout.write(formatLintResult(result, parsed.format))
|
|
111
125
|
return result.exitCode
|
|
112
126
|
} catch (err) {
|
|
113
127
|
if (err instanceof LinterToolError) {
|
|
128
|
+
if (err.code === 'OXLINT_CANCELLED' && receivedSignal) {
|
|
129
|
+
return receivedSignal === 'SIGINT' ? 130 : 143
|
|
130
|
+
}
|
|
114
131
|
error(err.message)
|
|
115
132
|
return err.exitCode
|
|
116
133
|
}
|
|
117
134
|
throw err
|
|
135
|
+
} finally {
|
|
136
|
+
process.off('SIGINT', onSigint)
|
|
137
|
+
process.off('SIGTERM', onSigterm)
|
|
118
138
|
}
|
|
119
139
|
}
|
|
120
140
|
|
package/src/domain/define.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
} from '@astrale-os/kernel-core/domain'
|
|
13
13
|
import type { Core, Schema } from '@astrale-os/kernel-dsl'
|
|
14
14
|
|
|
15
|
-
import { bindMethods, compileDomain } from '@astrale-os/kernel-core/domain'
|
|
15
|
+
import { assertKernel, bindMethods, compileDomain } from '@astrale-os/kernel-core/domain'
|
|
16
16
|
|
|
17
17
|
import type { DomainManifest } from '../config/define-domain.js'
|
|
18
18
|
import type { AnyRemoteFunctionDef, ViewDef } from '../define/index.js'
|
|
@@ -98,6 +98,7 @@ export function defineRemoteDomain<TDeps>() {
|
|
|
98
98
|
undefined,
|
|
99
99
|
config.views ? buildViewDeclarations(config.views) : undefined,
|
|
100
100
|
)
|
|
101
|
+
assertKernel(compiled)
|
|
101
102
|
const methods = bindMethods<AnyRemoteHandler>(
|
|
102
103
|
compiled.$.schema,
|
|
103
104
|
compiled.$.methods,
|
package/src/linter/diagnostic.ts
CHANGED
|
@@ -28,12 +28,29 @@ export type LintResult = {
|
|
|
28
28
|
exitCode: 0 | 1
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export type LinterToolErrorCode =
|
|
32
|
+
| 'LINTER_PREFLIGHT_FAILED'
|
|
33
|
+
| 'LINTER_TOOL_FAILED'
|
|
34
|
+
| 'OXLINT_CANCELLED'
|
|
35
|
+
| 'OXLINT_FAILED'
|
|
36
|
+
| 'OXLINT_INVALID_OUTPUT'
|
|
37
|
+
| 'OXLINT_NOT_INSTALLED'
|
|
38
|
+
| 'OXLINT_OUTPUT_LIMIT'
|
|
39
|
+
| 'OXLINT_START_FAILED'
|
|
40
|
+
| 'OXLINT_TIMEOUT'
|
|
41
|
+
|
|
42
|
+
type LinterToolErrorOptions = ErrorOptions & {
|
|
43
|
+
code?: LinterToolErrorCode
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
export class LinterToolError extends Error {
|
|
32
47
|
readonly exitCode = 2
|
|
48
|
+
readonly code: LinterToolErrorCode
|
|
33
49
|
|
|
34
|
-
constructor(message: string, options
|
|
50
|
+
constructor(message: string, options: LinterToolErrorOptions = {}) {
|
|
35
51
|
super(message, options)
|
|
36
52
|
this.name = 'LinterToolError'
|
|
53
|
+
this.code = options.code ?? 'LINTER_TOOL_FAILED'
|
|
37
54
|
}
|
|
38
55
|
}
|
|
39
56
|
|
package/src/linter/index.ts
CHANGED
package/src/linter/lint.ts
CHANGED
|
@@ -11,6 +11,8 @@ export type LintDomainOptions = {
|
|
|
11
11
|
root?: string
|
|
12
12
|
fix?: boolean
|
|
13
13
|
preflight?: boolean
|
|
14
|
+
/** Cancels the external Oxlint process and rejects the lint operation. */
|
|
15
|
+
signal?: AbortSignal
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export async function lintDomain(options: LintDomainOptions = {}): Promise<LintResult> {
|
|
@@ -19,7 +21,7 @@ export async function lintDomain(options: LintDomainOptions = {}): Promise<LintR
|
|
|
19
21
|
if (options.preflight !== false) await assertSingleTypeUniverse(root)
|
|
20
22
|
const [project, oxlint] = await Promise.all([
|
|
21
23
|
discoverProject(root),
|
|
22
|
-
runOxlint(root, options.fix ?? false),
|
|
24
|
+
runOxlint(root, options.fix ?? false, { signal: options.signal }),
|
|
23
25
|
])
|
|
24
26
|
const diagnostics = dedupeDiagnostics([...oxlint.diagnostics, ...analyzeProject(project)])
|
|
25
27
|
return {
|
|
@@ -3,6 +3,11 @@ import { defineConfig } from 'oxlint'
|
|
|
3
3
|
|
|
4
4
|
export const domainOxlintConfig = defineConfig({
|
|
5
5
|
extends: [base],
|
|
6
|
+
// Oxlint resolves ignore patterns relative to the config object that declares
|
|
7
|
+
// them. Lift the shared preset's traversal boundary onto the project config;
|
|
8
|
+
// leaving it only inside `extends` roots it in the installed preset package
|
|
9
|
+
// and allows a project's dependency tree into discovery.
|
|
10
|
+
ignorePatterns: base.ignorePatterns,
|
|
6
11
|
jsPlugins: [
|
|
7
12
|
{
|
|
8
13
|
name: 'astrale',
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The domain linter's process-level project-discovery boundary.
|
|
3
|
+
*
|
|
4
|
+
* Oxlint roots config-file ignores at that config's directory. The SDK also
|
|
5
|
+
* uses an internal fallback config outside the target project, so invocation
|
|
6
|
+
* must enforce these patterns relative to its working directory as well.
|
|
7
|
+
*/
|
|
8
|
+
export const DOMAIN_OXLINT_IGNORE_PATTERNS = [
|
|
9
|
+
'**/dist/**',
|
|
10
|
+
'**/node_modules/**',
|
|
11
|
+
'**/coverage/**',
|
|
12
|
+
'**/*.js',
|
|
13
|
+
'**/*.mjs',
|
|
14
|
+
'**/*.cjs',
|
|
15
|
+
'**/*.gen.ts',
|
|
16
|
+
'**/*.gen.tsx',
|
|
17
|
+
] as const
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
|
|
3
|
+
import { LinterToolError } from '../diagnostic.js'
|
|
4
|
+
|
|
5
|
+
const DEFAULT_TIMEOUT_MS = 60_000
|
|
6
|
+
const DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024 * 1024
|
|
7
|
+
const DEFAULT_TERMINATION_GRACE_MS = 1_000
|
|
8
|
+
|
|
9
|
+
export type OxlintProcessOptions = {
|
|
10
|
+
signal?: AbortSignal
|
|
11
|
+
timeoutMs?: number
|
|
12
|
+
outputLimitBytes?: number
|
|
13
|
+
terminationGraceMs?: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type OxlintProcessResult = {
|
|
17
|
+
status: number | null
|
|
18
|
+
signal: NodeJS.Signals | null
|
|
19
|
+
stdout: string
|
|
20
|
+
stderr: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type TerminationReason =
|
|
24
|
+
| { kind: 'cancelled'; cause: unknown }
|
|
25
|
+
| { kind: 'output-limit'; limitBytes: number }
|
|
26
|
+
| { kind: 'timeout'; timeoutMs: number }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Run Oxlint under the runtime it declares, independent of the SDK CLI's
|
|
30
|
+
* parent runtime. The published CLI intentionally runs under Bun, while
|
|
31
|
+
* Oxlint's executable is a Node program.
|
|
32
|
+
*/
|
|
33
|
+
export async function runOxlintProcess(
|
|
34
|
+
bin: string,
|
|
35
|
+
args: readonly string[],
|
|
36
|
+
cwd: string,
|
|
37
|
+
options: OxlintProcessOptions = {},
|
|
38
|
+
): Promise<OxlintProcessResult> {
|
|
39
|
+
const timeoutMs = positiveInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, 'timeoutMs')
|
|
40
|
+
const outputLimitBytes = positiveInteger(
|
|
41
|
+
options.outputLimitBytes,
|
|
42
|
+
DEFAULT_OUTPUT_LIMIT_BYTES,
|
|
43
|
+
'outputLimitBytes',
|
|
44
|
+
)
|
|
45
|
+
const terminationGraceMs = nonNegativeInteger(
|
|
46
|
+
options.terminationGraceMs,
|
|
47
|
+
DEFAULT_TERMINATION_GRACE_MS,
|
|
48
|
+
'terminationGraceMs',
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if (options.signal?.aborted) throw cancelledError(options.signal.reason)
|
|
52
|
+
|
|
53
|
+
let child: ReturnType<typeof spawn>
|
|
54
|
+
try {
|
|
55
|
+
child = spawn('node', [bin, ...args], {
|
|
56
|
+
cwd,
|
|
57
|
+
env: process.env,
|
|
58
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
59
|
+
windowsHide: true,
|
|
60
|
+
})
|
|
61
|
+
} catch (cause) {
|
|
62
|
+
throw startError(bin, cause)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return await new Promise<OxlintProcessResult>((resolve, reject) => {
|
|
66
|
+
const stdout: Buffer[] = []
|
|
67
|
+
const stderr: Buffer[] = []
|
|
68
|
+
let capturedBytes = 0
|
|
69
|
+
let settled = false
|
|
70
|
+
let processError: unknown
|
|
71
|
+
let terminationReason: TerminationReason | undefined
|
|
72
|
+
let forceKillTimer: NodeJS.Timeout | undefined
|
|
73
|
+
|
|
74
|
+
const timeout = setTimeout(() => {
|
|
75
|
+
terminate({ kind: 'timeout', timeoutMs })
|
|
76
|
+
}, timeoutMs)
|
|
77
|
+
timeout.unref?.()
|
|
78
|
+
|
|
79
|
+
const onAbort = () => terminate({ kind: 'cancelled', cause: options.signal?.reason })
|
|
80
|
+
options.signal?.addEventListener('abort', onAbort, { once: true })
|
|
81
|
+
|
|
82
|
+
const onStdout = (chunk: Buffer | string) => capture(stdout, chunk)
|
|
83
|
+
const onStderr = (chunk: Buffer | string) => capture(stderr, chunk)
|
|
84
|
+
child.stdout?.on('data', onStdout)
|
|
85
|
+
child.stderr?.on('data', onStderr)
|
|
86
|
+
|
|
87
|
+
// `close` follows both normal exit and spawn errors. Record an error here
|
|
88
|
+
// but settle only after `close`, so the process handle and stdio are always
|
|
89
|
+
// reaped before the caller continues.
|
|
90
|
+
child.once('error', (cause) => {
|
|
91
|
+
processError = cause
|
|
92
|
+
clearTimeout(timeout)
|
|
93
|
+
})
|
|
94
|
+
child.once('close', (status, signal) => {
|
|
95
|
+
finish(() => {
|
|
96
|
+
if (terminationReason) {
|
|
97
|
+
reject(terminationError(terminationReason))
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
if (processError) {
|
|
101
|
+
reject(startError(bin, processError))
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
resolve({
|
|
105
|
+
status,
|
|
106
|
+
signal,
|
|
107
|
+
stdout: Buffer.concat(stdout).toString('utf8'),
|
|
108
|
+
stderr: Buffer.concat(stderr).toString('utf8'),
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Close the race between the pre-spawn check and listener registration.
|
|
114
|
+
if (options.signal?.aborted) onAbort()
|
|
115
|
+
|
|
116
|
+
function capture(target: Buffer[], chunk: Buffer | string): void {
|
|
117
|
+
if (terminationReason) return
|
|
118
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
|
|
119
|
+
const remaining = outputLimitBytes - capturedBytes
|
|
120
|
+
if (remaining > 0) {
|
|
121
|
+
const accepted = Math.min(remaining, buffer.byteLength)
|
|
122
|
+
target.push(buffer.subarray(0, accepted))
|
|
123
|
+
capturedBytes += accepted
|
|
124
|
+
}
|
|
125
|
+
if (buffer.byteLength > remaining) {
|
|
126
|
+
terminate({ kind: 'output-limit', limitBytes: outputLimitBytes })
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function terminate(reason: TerminationReason): void {
|
|
131
|
+
if (settled || terminationReason) return
|
|
132
|
+
terminationReason = reason
|
|
133
|
+
try {
|
|
134
|
+
child.kill('SIGTERM')
|
|
135
|
+
} catch {
|
|
136
|
+
forceKill()
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
forceKillTimer = setTimeout(forceKill, terminationGraceMs)
|
|
140
|
+
forceKillTimer.unref?.()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function forceKill(): void {
|
|
144
|
+
if (settled || child.exitCode !== null || child.signalCode !== null) return
|
|
145
|
+
try {
|
|
146
|
+
child.kill('SIGKILL')
|
|
147
|
+
} catch {
|
|
148
|
+
// The close/error event remains the authoritative process outcome.
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function finish(settle: () => void): void {
|
|
153
|
+
if (settled) return
|
|
154
|
+
settled = true
|
|
155
|
+
clearTimeout(timeout)
|
|
156
|
+
if (forceKillTimer) clearTimeout(forceKillTimer)
|
|
157
|
+
options.signal?.removeEventListener('abort', onAbort)
|
|
158
|
+
child.stdout?.off('data', onStdout)
|
|
159
|
+
child.stderr?.off('data', onStderr)
|
|
160
|
+
settle()
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function startError(bin: string, cause: unknown): LinterToolError {
|
|
166
|
+
return new LinterToolError(`Could not start Oxlint with Node at ${bin}.`, {
|
|
167
|
+
code: 'OXLINT_START_FAILED',
|
|
168
|
+
cause,
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function cancelledError(cause: unknown): LinterToolError {
|
|
173
|
+
return new LinterToolError('Oxlint was cancelled and its process was terminated.', {
|
|
174
|
+
code: 'OXLINT_CANCELLED',
|
|
175
|
+
cause,
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function terminationError(reason: TerminationReason): LinterToolError {
|
|
180
|
+
switch (reason.kind) {
|
|
181
|
+
case 'cancelled':
|
|
182
|
+
return cancelledError(reason.cause)
|
|
183
|
+
case 'output-limit':
|
|
184
|
+
return new LinterToolError(
|
|
185
|
+
`Oxlint exceeded the ${formatBytes(reason.limitBytes)} output limit and was terminated.`,
|
|
186
|
+
{ code: 'OXLINT_OUTPUT_LIMIT' },
|
|
187
|
+
)
|
|
188
|
+
case 'timeout':
|
|
189
|
+
return new LinterToolError(
|
|
190
|
+
`Oxlint exceeded the ${formatDuration(reason.timeoutMs)} timeout and was terminated.`,
|
|
191
|
+
{ code: 'OXLINT_TIMEOUT' },
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function positiveInteger(value: number | undefined, fallback: number, name: string): number {
|
|
197
|
+
const result = value ?? fallback
|
|
198
|
+
if (!Number.isSafeInteger(result) || result <= 0) {
|
|
199
|
+
throw new TypeError(`${name} must be a positive integer.`)
|
|
200
|
+
}
|
|
201
|
+
return result
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function nonNegativeInteger(value: number | undefined, fallback: number, name: string): number {
|
|
205
|
+
const result = value ?? fallback
|
|
206
|
+
if (!Number.isSafeInteger(result) || result < 0) {
|
|
207
|
+
throw new TypeError(`${name} must be a non-negative integer.`)
|
|
208
|
+
}
|
|
209
|
+
return result
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function formatDuration(milliseconds: number): string {
|
|
213
|
+
return milliseconds % 1_000 === 0 ? `${milliseconds / 1_000}s` : `${milliseconds}ms`
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function formatBytes(bytes: number): string {
|
|
217
|
+
const mib = 1024 * 1024
|
|
218
|
+
return bytes % mib === 0 ? `${bytes / mib} MiB` : `${bytes} bytes`
|
|
219
|
+
}
|