@orkestrel/probe 0.0.15 → 0.0.17
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/src/core/index.cjs +2 -2
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +6 -6
- package/dist/src/core/index.d.ts +6 -6
- package/dist/src/core/index.js +2 -2
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +57 -57
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +12 -12
- package/dist/src/server/index.d.ts +12 -12
- package/dist/src/server/index.js +58 -58
- package/dist/src/server/index.js.map +1 -1
- package/package.json +16 -16
|
@@ -27,9 +27,9 @@ import type * as VitestNode from 'vitest/node';
|
|
|
27
27
|
* ```ts
|
|
28
28
|
* relativeWorkspaceFile(
|
|
29
29
|
* '/srv/checkout',
|
|
30
|
-
* buildRevisionPath('/srv/checkout', 'tmp/
|
|
30
|
+
* buildRevisionPath('/srv/checkout', 'tmp/probes/greeting.test.ts', '4821-9f0c'),
|
|
31
31
|
* )
|
|
32
|
-
* // 'tmp/
|
|
32
|
+
* // 'tmp/probes/greeting.test.probe-4821-9f0c.ts'
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export declare function buildRevisionPath(workspace: string, path: string, revision: string): string;
|
|
@@ -221,7 +221,7 @@ export declare function filterUniqueIssues(issues: readonly Issue[]): readonly I
|
|
|
221
221
|
*
|
|
222
222
|
* @example
|
|
223
223
|
* ```ts
|
|
224
|
-
* const test = { path: 'tmp/
|
|
224
|
+
* const test = { path: 'tmp/probes/greeting.test.ts', text: '' }
|
|
225
225
|
* findRefusedPaths({
|
|
226
226
|
* project: 'tsconfig.json',
|
|
227
227
|
* case: { files: [{ path: '../../etc/hosts', text: '' }], test },
|
|
@@ -274,7 +274,7 @@ export declare function inferDocumentLanguage(path: string): string;
|
|
|
274
274
|
*
|
|
275
275
|
* @example
|
|
276
276
|
* ```ts
|
|
277
|
-
* inferTestProject('tmp/
|
|
277
|
+
* inferTestProject('tmp/probes/greeting.test.ts') // 'probe'
|
|
278
278
|
* inferTestProject('tests/src/server/helpers.test.ts') // 'src:server'
|
|
279
279
|
* inferTestProject('tests/config.test.ts') // undefined
|
|
280
280
|
* ```
|
|
@@ -368,11 +368,11 @@ export declare interface InspectionOptions {
|
|
|
368
368
|
* @example
|
|
369
369
|
* ```ts
|
|
370
370
|
* try {
|
|
371
|
-
* writeFileSync('tmp/
|
|
371
|
+
* writeFileSync('tmp/probes/greeting\0.test.ts', '')
|
|
372
372
|
* } catch (error) {
|
|
373
|
-
* isRefusedName('tmp/
|
|
373
|
+
* isRefusedName('tmp/probes/greeting\0.test.ts', error) // true
|
|
374
374
|
* }
|
|
375
|
-
* isRefusedName('tmp/
|
|
375
|
+
* isRefusedName('tmp/probes/greeting.test.ts', new Error('the runtime stage was destroyed')) // false
|
|
376
376
|
* ```
|
|
377
377
|
*/
|
|
378
378
|
export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
@@ -769,7 +769,7 @@ export declare interface OverlayInterface {
|
|
|
769
769
|
*
|
|
770
770
|
* @example
|
|
771
771
|
* ```ts
|
|
772
|
-
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/
|
|
772
|
+
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/probes/arm-type.ts', true)
|
|
773
773
|
* writeFileSync(file, 'export type Signal = string\n', { encoding: 'utf8', flag: 'wx' })
|
|
774
774
|
* overwriteFile(file, 'export type Signal = number\n')
|
|
775
775
|
* readFileSync(file, 'utf8') // 'export type Signal = number\n'
|
|
@@ -848,7 +848,7 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
848
848
|
* },
|
|
849
849
|
* ],
|
|
850
850
|
* test: {
|
|
851
|
-
* path: 'tmp/
|
|
851
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
852
852
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
853
853
|
* },
|
|
854
854
|
* },
|
|
@@ -860,7 +860,7 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
860
860
|
* },
|
|
861
861
|
* ],
|
|
862
862
|
* test: {
|
|
863
|
-
* path: 'tmp/
|
|
863
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
864
864
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
865
865
|
* },
|
|
866
866
|
* stage: 'type',
|
|
@@ -870,8 +870,8 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
870
870
|
*
|
|
871
871
|
* const probe = new Probe({ workspace: process.cwd() })
|
|
872
872
|
* const verdict = await probe.prove(claim)
|
|
873
|
-
* verdict.digest // '
|
|
874
|
-
* verdict.receipt // 'probe:
|
|
873
|
+
* verdict.digest // 'bdf03e5dfd6bd413ead671c7a2940fcf'
|
|
874
|
+
* verdict.receipt // 'probe:bdf03e5dfd6bd413ead671c7a2940fcf:type:typescript@6.0.3:oxlint@1.86.0:vitest@4.1.11:configs/src/tsconfig.core.json@434f59254d58cf2683d453a26bd0d837'
|
|
875
875
|
* await probe.destroy()
|
|
876
876
|
* ```
|
|
877
877
|
*/
|
|
@@ -27,9 +27,9 @@ import type * as VitestNode from 'vitest/node';
|
|
|
27
27
|
* ```ts
|
|
28
28
|
* relativeWorkspaceFile(
|
|
29
29
|
* '/srv/checkout',
|
|
30
|
-
* buildRevisionPath('/srv/checkout', 'tmp/
|
|
30
|
+
* buildRevisionPath('/srv/checkout', 'tmp/probes/greeting.test.ts', '4821-9f0c'),
|
|
31
31
|
* )
|
|
32
|
-
* // 'tmp/
|
|
32
|
+
* // 'tmp/probes/greeting.test.probe-4821-9f0c.ts'
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export declare function buildRevisionPath(workspace: string, path: string, revision: string): string;
|
|
@@ -221,7 +221,7 @@ export declare function filterUniqueIssues(issues: readonly Issue[]): readonly I
|
|
|
221
221
|
*
|
|
222
222
|
* @example
|
|
223
223
|
* ```ts
|
|
224
|
-
* const test = { path: 'tmp/
|
|
224
|
+
* const test = { path: 'tmp/probes/greeting.test.ts', text: '' }
|
|
225
225
|
* findRefusedPaths({
|
|
226
226
|
* project: 'tsconfig.json',
|
|
227
227
|
* case: { files: [{ path: '../../etc/hosts', text: '' }], test },
|
|
@@ -274,7 +274,7 @@ export declare function inferDocumentLanguage(path: string): string;
|
|
|
274
274
|
*
|
|
275
275
|
* @example
|
|
276
276
|
* ```ts
|
|
277
|
-
* inferTestProject('tmp/
|
|
277
|
+
* inferTestProject('tmp/probes/greeting.test.ts') // 'probe'
|
|
278
278
|
* inferTestProject('tests/src/server/helpers.test.ts') // 'src:server'
|
|
279
279
|
* inferTestProject('tests/config.test.ts') // undefined
|
|
280
280
|
* ```
|
|
@@ -368,11 +368,11 @@ export declare interface InspectionOptions {
|
|
|
368
368
|
* @example
|
|
369
369
|
* ```ts
|
|
370
370
|
* try {
|
|
371
|
-
* writeFileSync('tmp/
|
|
371
|
+
* writeFileSync('tmp/probes/greeting\0.test.ts', '')
|
|
372
372
|
* } catch (error) {
|
|
373
|
-
* isRefusedName('tmp/
|
|
373
|
+
* isRefusedName('tmp/probes/greeting\0.test.ts', error) // true
|
|
374
374
|
* }
|
|
375
|
-
* isRefusedName('tmp/
|
|
375
|
+
* isRefusedName('tmp/probes/greeting.test.ts', new Error('the runtime stage was destroyed')) // false
|
|
376
376
|
* ```
|
|
377
377
|
*/
|
|
378
378
|
export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
@@ -769,7 +769,7 @@ export declare interface OverlayInterface {
|
|
|
769
769
|
*
|
|
770
770
|
* @example
|
|
771
771
|
* ```ts
|
|
772
|
-
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/
|
|
772
|
+
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/probes/arm-type.ts', true)
|
|
773
773
|
* writeFileSync(file, 'export type Signal = string\n', { encoding: 'utf8', flag: 'wx' })
|
|
774
774
|
* overwriteFile(file, 'export type Signal = number\n')
|
|
775
775
|
* readFileSync(file, 'utf8') // 'export type Signal = number\n'
|
|
@@ -848,7 +848,7 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
848
848
|
* },
|
|
849
849
|
* ],
|
|
850
850
|
* test: {
|
|
851
|
-
* path: 'tmp/
|
|
851
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
852
852
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
853
853
|
* },
|
|
854
854
|
* },
|
|
@@ -860,7 +860,7 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
860
860
|
* },
|
|
861
861
|
* ],
|
|
862
862
|
* test: {
|
|
863
|
-
* path: 'tmp/
|
|
863
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
864
864
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
865
865
|
* },
|
|
866
866
|
* stage: 'type',
|
|
@@ -870,8 +870,8 @@ export declare function parseRevisionOwner(revision: string): number | undefined
|
|
|
870
870
|
*
|
|
871
871
|
* const probe = new Probe({ workspace: process.cwd() })
|
|
872
872
|
* const verdict = await probe.prove(claim)
|
|
873
|
-
* verdict.digest // '
|
|
874
|
-
* verdict.receipt // 'probe:
|
|
873
|
+
* verdict.digest // 'bdf03e5dfd6bd413ead671c7a2940fcf'
|
|
874
|
+
* verdict.receipt // 'probe:bdf03e5dfd6bd413ead671c7a2940fcf:type:typescript@6.0.3:oxlint@1.86.0:vitest@4.1.11:configs/src/tsconfig.core.json@434f59254d58cf2683d453a26bd0d837'
|
|
875
875
|
* await probe.destroy()
|
|
876
876
|
* ```
|
|
877
877
|
*/
|
package/dist/src/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { closeSync, constants, existsSync, ftruncateSync, lstatSync, mkdirSync,
|
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
|
-
import { attempt, compileGuard, compileSchema, isArray, isRecord, schemaToParameters } from "@orkestrel/contract";
|
|
6
|
+
import { attempt, compileGuard, compileSchema, isArray, isError, isNumber, isObject, isRecord, isString, parseJSON, schemaToParameters } from "@orkestrel/contract";
|
|
7
7
|
import { CLAIM_SHAPE, LINT_DEADLINE, PROBE_DEADLINE, PROBE_KEYS, PROBE_SPECIFICATIONS, ProbeError, RUNTIME_PLUGIN, TYPE_MIRROR, computeReceipt, createDestroyedError, formatCheck, formatReceipt, formatSpecification, formatVerdict, isClaim, isDraft, isProbeError, isVerdict, matchesSpecification } from "../core/index.js";
|
|
8
8
|
import { Emitter } from "@orkestrel/emitter";
|
|
9
9
|
import { createQueue } from "@orkestrel/queue";
|
|
@@ -60,11 +60,11 @@ function normalizePath(path) {
|
|
|
60
60
|
* ```
|
|
61
61
|
*/
|
|
62
62
|
function readFaultCode(error) {
|
|
63
|
-
if (
|
|
63
|
+
if (!isObject(error)) return void 0;
|
|
64
64
|
const fault = error;
|
|
65
65
|
const reading = attempt(() => "code" in fault ? fault.code : void 0);
|
|
66
66
|
if (!reading.success) return void 0;
|
|
67
|
-
return
|
|
67
|
+
return isString(reading.value) ? reading.value : void 0;
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Reports whether one path resolves outside the root it is read against.
|
|
@@ -151,7 +151,7 @@ function resolveWorkspaceFile(workspace, target, mutate = false) {
|
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
} catch (error) {
|
|
154
|
-
if (error
|
|
154
|
+
if (isProbeError(error)) throw error;
|
|
155
155
|
const code = readFaultCode(error);
|
|
156
156
|
const claimant = code === "ENAMETOOLONG" || code === "ERR_INVALID_ARG_VALUE";
|
|
157
157
|
throw new ProbeError(`The workspace path cannot be inspected: ${target}`, {
|
|
@@ -195,7 +195,7 @@ function resolveWorkspaceFile(workspace, target, mutate = false) {
|
|
|
195
195
|
*
|
|
196
196
|
* @example
|
|
197
197
|
* ```ts
|
|
198
|
-
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/
|
|
198
|
+
* const file = resolveWorkspaceFile('/srv/checkout', 'tmp/probes/arm-type.ts', true)
|
|
199
199
|
* writeFileSync(file, 'export type Signal = string\n', { encoding: 'utf8', flag: 'wx' })
|
|
200
200
|
* overwriteFile(file, 'export type Signal = number\n')
|
|
201
201
|
* readFileSync(file, 'utf8') // 'export type Signal = number\n'
|
|
@@ -238,11 +238,11 @@ function overwriteFile(file, text) {
|
|
|
238
238
|
* @example
|
|
239
239
|
* ```ts
|
|
240
240
|
* try {
|
|
241
|
-
* writeFileSync('tmp/
|
|
241
|
+
* writeFileSync('tmp/probes/greeting\0.test.ts', '')
|
|
242
242
|
* } catch (error) {
|
|
243
|
-
* isRefusedName('tmp/
|
|
243
|
+
* isRefusedName('tmp/probes/greeting\0.test.ts', error) // true
|
|
244
244
|
* }
|
|
245
|
-
* isRefusedName('tmp/
|
|
245
|
+
* isRefusedName('tmp/probes/greeting.test.ts', new Error('the runtime stage was destroyed')) // false
|
|
246
246
|
* ```
|
|
247
247
|
*/
|
|
248
248
|
function isRefusedName(file, error) {
|
|
@@ -459,7 +459,7 @@ function readWorkspaceManifest(workspace, name) {
|
|
|
459
459
|
try {
|
|
460
460
|
path = resolveWorkspaceModule(workspace, `${name}/package.json`);
|
|
461
461
|
} catch (error) {
|
|
462
|
-
if (!(error
|
|
462
|
+
if (!isProbeError(error)) throw error;
|
|
463
463
|
throw new ProbeError(`${name} does not publish a readable manifest`, {
|
|
464
464
|
origin: "workspace",
|
|
465
465
|
code: error.code,
|
|
@@ -536,14 +536,14 @@ function resolveWorkspaceBinary(workspace, name, command = name) {
|
|
|
536
536
|
code: "missing",
|
|
537
537
|
context: { name }
|
|
538
538
|
});
|
|
539
|
-
if (
|
|
539
|
+
if (isString(bin)) return resolve(manifest.path, "..", bin);
|
|
540
540
|
if (!isRecord(bin) || !(command in bin)) throw new ProbeError(`${name} does not publish the ${command} binary`, {
|
|
541
541
|
origin: "workspace",
|
|
542
542
|
code: "missing",
|
|
543
543
|
context: { name }
|
|
544
544
|
});
|
|
545
545
|
const entry = bin[command];
|
|
546
|
-
if (
|
|
546
|
+
if (!isString(entry)) throw new ProbeError(`${name} publishes an invalid ${command} binary`, {
|
|
547
547
|
origin: "workspace",
|
|
548
548
|
code: "malformed",
|
|
549
549
|
context: {
|
|
@@ -589,14 +589,14 @@ function inferTypeProject(path) {
|
|
|
589
589
|
*
|
|
590
590
|
* @example
|
|
591
591
|
* ```ts
|
|
592
|
-
* inferTestProject('tmp/
|
|
592
|
+
* inferTestProject('tmp/probes/greeting.test.ts') // 'probe'
|
|
593
593
|
* inferTestProject('tests/src/server/helpers.test.ts') // 'src:server'
|
|
594
594
|
* inferTestProject('tests/config.test.ts') // undefined
|
|
595
595
|
* ```
|
|
596
596
|
*/
|
|
597
597
|
function inferTestProject(path) {
|
|
598
598
|
const [root, axis, environment] = normalizePath(path).split("/");
|
|
599
|
-
if (root === "tmp" && axis === "
|
|
599
|
+
if (root === "tmp" && axis === "probes") return "probe";
|
|
600
600
|
if (root !== "tests" || axis === void 0 || environment === void 0) return void 0;
|
|
601
601
|
if (axis !== "src" && axis !== "app") return void 0;
|
|
602
602
|
return `${axis}:${environment}`;
|
|
@@ -633,9 +633,9 @@ function inferDocumentLanguage(path) {
|
|
|
633
633
|
* ```ts
|
|
634
634
|
* relativeWorkspaceFile(
|
|
635
635
|
* '/srv/checkout',
|
|
636
|
-
* buildRevisionPath('/srv/checkout', 'tmp/
|
|
636
|
+
* buildRevisionPath('/srv/checkout', 'tmp/probes/greeting.test.ts', '4821-9f0c'),
|
|
637
637
|
* )
|
|
638
|
-
* // 'tmp/
|
|
638
|
+
* // 'tmp/probes/greeting.test.probe-4821-9f0c.ts'
|
|
639
639
|
* ```
|
|
640
640
|
*/
|
|
641
641
|
function buildRevisionPath(workspace, path, revision) {
|
|
@@ -710,7 +710,7 @@ function matchesWorkspaceModule(path) {
|
|
|
710
710
|
* ```
|
|
711
711
|
*/
|
|
712
712
|
function matchesLiveProcess(id) {
|
|
713
|
-
if (!Number.isSafeInteger(id) || id <= 0) return true;
|
|
713
|
+
if (!isNumber(id) || !Number.isSafeInteger(id) || id <= 0) return true;
|
|
714
714
|
try {
|
|
715
715
|
process.kill(id, 0);
|
|
716
716
|
return true;
|
|
@@ -774,8 +774,8 @@ function collectWorkspaceFiles(workspace) {
|
|
|
774
774
|
* ```
|
|
775
775
|
*/
|
|
776
776
|
function describeUnknown(value) {
|
|
777
|
-
if (value
|
|
778
|
-
if (
|
|
777
|
+
if (isError(value)) return value.message;
|
|
778
|
+
if (isObject(value) && "message" in value && isString(value.message)) return value.message;
|
|
779
779
|
return String(value);
|
|
780
780
|
}
|
|
781
781
|
/**
|
|
@@ -795,7 +795,7 @@ async function guardStage(stage, operation) {
|
|
|
795
795
|
try {
|
|
796
796
|
return await operation;
|
|
797
797
|
} catch (error) {
|
|
798
|
-
if (error
|
|
798
|
+
if (isProbeError(error)) throw error;
|
|
799
799
|
throw new ProbeError(`The ${stage} stage could not serve (${describeUnknown(error)})`, {
|
|
800
800
|
origin: "instrument",
|
|
801
801
|
code: "malformed",
|
|
@@ -825,7 +825,7 @@ async function guardStage(stage, operation) {
|
|
|
825
825
|
*
|
|
826
826
|
* @example
|
|
827
827
|
* ```ts
|
|
828
|
-
* const test = { path: 'tmp/
|
|
828
|
+
* const test = { path: 'tmp/probes/greeting.test.ts', text: '' }
|
|
829
829
|
* findRefusedPaths({
|
|
830
830
|
* project: 'tsconfig.json',
|
|
831
831
|
* case: { files: [{ path: '../../etc/hosts', text: '' }], test },
|
|
@@ -872,7 +872,7 @@ function findRefusedPaths(value) {
|
|
|
872
872
|
*/
|
|
873
873
|
function normalizeValue(workspace, value) {
|
|
874
874
|
const root = resolve(workspace);
|
|
875
|
-
if (
|
|
875
|
+
if (isString(value)) {
|
|
876
876
|
if (!isAbsolute(value)) return value;
|
|
877
877
|
const path = relative(root, resolve(value));
|
|
878
878
|
if (path === "") return ".";
|
|
@@ -982,14 +982,14 @@ function releaseListeners(emitter, capture) {
|
|
|
982
982
|
* ```
|
|
983
983
|
*/
|
|
984
984
|
function parseProjectConfig(text) {
|
|
985
|
-
const parsed =
|
|
986
|
-
if (!
|
|
987
|
-
const files = parsed.
|
|
988
|
-
const include = parsed.
|
|
985
|
+
const parsed = parseJSON(text);
|
|
986
|
+
if (!isRecord(parsed)) return void 0;
|
|
987
|
+
const files = parsed.files;
|
|
988
|
+
const include = parsed.include;
|
|
989
989
|
return {
|
|
990
|
-
compilerOptions: parsed.
|
|
991
|
-
...isArray(files) && files.every(
|
|
992
|
-
...isArray(include) && include.every(
|
|
990
|
+
compilerOptions: parsed.compilerOptions,
|
|
991
|
+
...isArray(files) && files.every(isString) ? { files } : {},
|
|
992
|
+
...isArray(include) && include.every(isString) ? { include } : {}
|
|
993
993
|
};
|
|
994
994
|
}
|
|
995
995
|
/**
|
|
@@ -1103,9 +1103,9 @@ var Overlay = class {
|
|
|
1103
1103
|
};
|
|
1104
1104
|
//#endregion
|
|
1105
1105
|
//#region package.json
|
|
1106
|
-
var version = "0.0.
|
|
1106
|
+
var version = "0.0.17";
|
|
1107
1107
|
var peerDependencies = {
|
|
1108
|
-
"oxlint": "^1.
|
|
1108
|
+
"oxlint": "^1.86.0",
|
|
1109
1109
|
"typescript": "^6.0.3",
|
|
1110
1110
|
"vitest": "^4.1.11"
|
|
1111
1111
|
};
|
|
@@ -1278,7 +1278,7 @@ var LintStage = class {
|
|
|
1278
1278
|
if (this.#closing !== void 0) return createDestroyedError("lint stage");
|
|
1279
1279
|
const ending = this.#ending;
|
|
1280
1280
|
if (ending !== void 0) return this.#fault(`The Oxlint language server exited with ${ending}`, error, path);
|
|
1281
|
-
if (error
|
|
1281
|
+
if (isError(error)) return error;
|
|
1282
1282
|
return this.#fault(describeUnknown(error), error, path);
|
|
1283
1283
|
}
|
|
1284
1284
|
#fault(message, cause, path) {
|
|
@@ -1449,7 +1449,7 @@ var RuntimeStage = class {
|
|
|
1449
1449
|
for (const draft of subject.files) overlay.set(resolveWorkspaceFile(this.#workspace, draft.path), draft.text);
|
|
1450
1450
|
this.#revalidate(vitest);
|
|
1451
1451
|
const specification = this.#specification(subject.test);
|
|
1452
|
-
if (
|
|
1452
|
+
if (!isString(specification)) return {
|
|
1453
1453
|
stage: this.stage,
|
|
1454
1454
|
elapsed: Math.round(performance.now() - started),
|
|
1455
1455
|
issues: [specification]
|
|
@@ -1466,7 +1466,7 @@ var RuntimeStage = class {
|
|
|
1466
1466
|
const result = await vitest.runTestSpecifications([task], false);
|
|
1467
1467
|
issues = [...this.#issues(result, file, subject.test.path), ...this.#misses(project, file)];
|
|
1468
1468
|
} catch (error) {
|
|
1469
|
-
if (error
|
|
1469
|
+
if (isProbeError(error)) throw error;
|
|
1470
1470
|
throw new ProbeError(`The runtime stage could not run the generated specification (${describeUnknown(error)})`, {
|
|
1471
1471
|
origin: "instrument",
|
|
1472
1472
|
code: "malformed",
|
|
@@ -1487,7 +1487,7 @@ var RuntimeStage = class {
|
|
|
1487
1487
|
if (existsSync(contained)) unlinkSync(contained);
|
|
1488
1488
|
} catch (error) {
|
|
1489
1489
|
cleanup = [...cleanup, {
|
|
1490
|
-
origin: error
|
|
1490
|
+
origin: isProbeError(error) && error.origin === "workspace" ? "workspace" : "instrument",
|
|
1491
1491
|
path: relativeWorkspaceFile(this.#workspace, file),
|
|
1492
1492
|
message: `The runtime stage could not delete the generated specification (${describeUnknown(error)})`
|
|
1493
1493
|
}];
|
|
@@ -1566,7 +1566,7 @@ var RuntimeStage = class {
|
|
|
1566
1566
|
test.projects = test.projects.map((project) => this.#augment(project));
|
|
1567
1567
|
}
|
|
1568
1568
|
#augment(project) {
|
|
1569
|
-
if (
|
|
1569
|
+
if (isString(project)) return project;
|
|
1570
1570
|
if (typeof project === "function") return this.#wrap(project);
|
|
1571
1571
|
return Promise.resolve(project).then(this.#instrument.bind(this));
|
|
1572
1572
|
}
|
|
@@ -1634,7 +1634,7 @@ var RuntimeStage = class {
|
|
|
1634
1634
|
return file;
|
|
1635
1635
|
});
|
|
1636
1636
|
if (outcome.success) return outcome.value;
|
|
1637
|
-
if (outcome.error
|
|
1637
|
+
if (isProbeError(outcome.error) && outcome.error.origin === "claimant") throw new ProbeError(outcome.error.message, {
|
|
1638
1638
|
origin: outcome.error.origin,
|
|
1639
1639
|
code: outcome.error.code,
|
|
1640
1640
|
context: {
|
|
@@ -1653,7 +1653,7 @@ var RuntimeStage = class {
|
|
|
1653
1653
|
cause: outcome.error
|
|
1654
1654
|
});
|
|
1655
1655
|
return {
|
|
1656
|
-
origin: outcome.error
|
|
1656
|
+
origin: isProbeError(outcome.error) && outcome.error.origin === "workspace" || creating ? "workspace" : "instrument",
|
|
1657
1657
|
path: test.path,
|
|
1658
1658
|
message: `The runtime stage could not write the generated specification (${describeUnknown(outcome.error)})`
|
|
1659
1659
|
};
|
|
@@ -1913,29 +1913,29 @@ var RuntimeStage = class {
|
|
|
1913
1913
|
}
|
|
1914
1914
|
#issue(error, specification, original) {
|
|
1915
1915
|
const message = relativeWorkspaceMessage(this.#workspace, describeUnknown(error)).replaceAll(basename(specification), basename(original));
|
|
1916
|
-
if (
|
|
1916
|
+
if (!isObject(error) || !("stacks" in error)) return {
|
|
1917
1917
|
origin: "claimant",
|
|
1918
1918
|
path: original,
|
|
1919
1919
|
message
|
|
1920
1920
|
};
|
|
1921
1921
|
const stacks = error.stacks;
|
|
1922
|
-
if (!
|
|
1922
|
+
if (!isArray(stacks)) return {
|
|
1923
1923
|
origin: "claimant",
|
|
1924
1924
|
path: original,
|
|
1925
1925
|
message
|
|
1926
1926
|
};
|
|
1927
1927
|
for (const stack of stacks) {
|
|
1928
|
-
if (
|
|
1929
|
-
if (!("file" in stack) ||
|
|
1928
|
+
if (!isObject(stack)) continue;
|
|
1929
|
+
if (!("file" in stack) || !isString(stack.file)) continue;
|
|
1930
1930
|
const declared = stack.file.startsWith("file:") ? fileURLToPath(stack.file) : isAbsolute(stack.file) ? stack.file : resolve(this.#workspace, stack.file);
|
|
1931
1931
|
const reported = this.#real(declared);
|
|
1932
1932
|
const path = reported === specification ? original : relativeWorkspaceFile(this.#real(this.#workspace), reported);
|
|
1933
|
-
if (!("line" in stack) ||
|
|
1933
|
+
if (!("line" in stack) || !isNumber(stack.line)) return {
|
|
1934
1934
|
origin: "claimant",
|
|
1935
1935
|
path,
|
|
1936
1936
|
message
|
|
1937
1937
|
};
|
|
1938
|
-
const character = "column" in stack &&
|
|
1938
|
+
const character = "column" in stack && isNumber(stack.column) ? stack.column - 1 : 0;
|
|
1939
1939
|
const position = {
|
|
1940
1940
|
line: stack.line - 1,
|
|
1941
1941
|
character
|
|
@@ -2461,7 +2461,7 @@ var TypeStage = class {
|
|
|
2461
2461
|
* },
|
|
2462
2462
|
* ],
|
|
2463
2463
|
* test: {
|
|
2464
|
-
* path: 'tmp/
|
|
2464
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
2465
2465
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
2466
2466
|
* },
|
|
2467
2467
|
* },
|
|
@@ -2473,7 +2473,7 @@ var TypeStage = class {
|
|
|
2473
2473
|
* },
|
|
2474
2474
|
* ],
|
|
2475
2475
|
* test: {
|
|
2476
|
-
* path: 'tmp/
|
|
2476
|
+
* path: 'tmp/probes/greeting.test.ts',
|
|
2477
2477
|
* text: "import { expect, test } from 'vitest'\nimport { createGreeting } from '../../src/core/factories.js'\ntest('greets', () => expect(createGreeting()).toBe('hi'))\n",
|
|
2478
2478
|
* },
|
|
2479
2479
|
* stage: 'type',
|
|
@@ -2483,8 +2483,8 @@ var TypeStage = class {
|
|
|
2483
2483
|
*
|
|
2484
2484
|
* const probe = new Probe({ workspace: process.cwd() })
|
|
2485
2485
|
* const verdict = await probe.prove(claim)
|
|
2486
|
-
* verdict.digest // '
|
|
2487
|
-
* verdict.receipt // 'probe:
|
|
2486
|
+
* verdict.digest // 'bdf03e5dfd6bd413ead671c7a2940fcf'
|
|
2487
|
+
* verdict.receipt // 'probe:bdf03e5dfd6bd413ead671c7a2940fcf:type:typescript@6.0.3:oxlint@1.86.0:vitest@4.1.11:configs/src/tsconfig.core.json@434f59254d58cf2683d453a26bd0d837'
|
|
2488
2488
|
* await probe.destroy()
|
|
2489
2489
|
* ```
|
|
2490
2490
|
*/
|
|
@@ -2581,7 +2581,7 @@ var Probe = class {
|
|
|
2581
2581
|
this.#emitter.emit("prove", verdict);
|
|
2582
2582
|
return verdict;
|
|
2583
2583
|
} catch (error) {
|
|
2584
|
-
if (!(error
|
|
2584
|
+
if (!isProbeError(error) || !this.#surfaced.has(error)) this.#emitter.emit("error", error);
|
|
2585
2585
|
throw error;
|
|
2586
2586
|
}
|
|
2587
2587
|
}
|
|
@@ -2626,17 +2626,17 @@ var Probe = class {
|
|
|
2626
2626
|
this.#emitter.emit("arm", this.#toolchain);
|
|
2627
2627
|
}
|
|
2628
2628
|
#surface(error) {
|
|
2629
|
-
if (error
|
|
2629
|
+
if (isProbeError(error)) this.#surfaced.add(error);
|
|
2630
2630
|
this.#emitter.emit("error", error);
|
|
2631
2631
|
}
|
|
2632
2632
|
#workbench() {
|
|
2633
|
-
const path = "tmp/
|
|
2633
|
+
const path = "tmp/probes";
|
|
2634
2634
|
const directory = resolveWorkspaceFile(this.#workspace, path);
|
|
2635
2635
|
const created = !existsSync(directory);
|
|
2636
2636
|
try {
|
|
2637
2637
|
mkdirSync(resolveWorkspaceFile(this.#workspace, path, true), { recursive: true });
|
|
2638
2638
|
} catch (error) {
|
|
2639
|
-
const code = error
|
|
2639
|
+
const code = isProbeError(error) && error.origin === "workspace" ? error.code : "malformed";
|
|
2640
2640
|
throw new ProbeError(`The probe could not create the boot workbench (${describeUnknown(error)})`, {
|
|
2641
2641
|
origin: "workspace",
|
|
2642
2642
|
code,
|
|
@@ -2648,16 +2648,16 @@ var Probe = class {
|
|
|
2648
2648
|
}
|
|
2649
2649
|
async #boot(created) {
|
|
2650
2650
|
const revision = `${process.pid}-${randomUUID()}`;
|
|
2651
|
-
const typeDependency = buildRevisionPath(this.#workspace, "tmp/
|
|
2652
|
-
const runtimeDependency = buildRevisionPath(this.#workspace, "tmp/
|
|
2651
|
+
const typeDependency = buildRevisionPath(this.#workspace, "tmp/probes/arm-type.ts", revision);
|
|
2652
|
+
const runtimeDependency = buildRevisionPath(this.#workspace, "tmp/probes/arm-runtime.ts", revision);
|
|
2653
2653
|
const typeModule = basename(typeDependency, ".ts");
|
|
2654
2654
|
const runtimeModule = basename(runtimeDependency, ".ts");
|
|
2655
2655
|
const typeTest = {
|
|
2656
|
-
path: `tmp/
|
|
2656
|
+
path: `tmp/probes/${typeModule}.test.ts`,
|
|
2657
2657
|
text: `import type { Signal } from './${typeModule}.js'\nimport { expect, test } from 'vitest'\nconst SIGNAL: Signal = 'before'\ntest('revalidates a mutated type', () => {\n\texpect(SIGNAL).toBe('before')\n})\n`
|
|
2658
2658
|
};
|
|
2659
2659
|
const runtimeTest = {
|
|
2660
|
-
path: `tmp/
|
|
2660
|
+
path: `tmp/probes/${runtimeModule}.test.ts`,
|
|
2661
2661
|
text: `import { SIGNAL } from './${runtimeModule}.js'\nimport { expect, test } from 'vitest'\ntest('revalidates a mutated value', () => {\n\texpect(SIGNAL).toBe('before')\n})\n`
|
|
2662
2662
|
};
|
|
2663
2663
|
const typeClaim = {
|
|
@@ -2732,7 +2732,7 @@ var Probe = class {
|
|
|
2732
2732
|
rmSync(resolveWorkspaceFile(this.#workspace, relative(this.#workspace, typeDependency), true), { force: true });
|
|
2733
2733
|
rmSync(resolveWorkspaceFile(this.#workspace, relative(this.#workspace, runtimeDependency), true), { force: true });
|
|
2734
2734
|
if (created) try {
|
|
2735
|
-
rmdirSync(resolveWorkspaceFile(this.#workspace, "tmp/
|
|
2735
|
+
rmdirSync(resolveWorkspaceFile(this.#workspace, "tmp/probes", true));
|
|
2736
2736
|
} catch {}
|
|
2737
2737
|
}
|
|
2738
2738
|
}
|
|
@@ -2872,12 +2872,12 @@ var Probe = class {
|
|
|
2872
2872
|
try {
|
|
2873
2873
|
await this.#bound(() => stage.destroy(), `The ${stage.stage} stage teardown exceeded ${this.#deadline} ms`, stage, stage.progress);
|
|
2874
2874
|
} catch (error) {
|
|
2875
|
-
if (!(error
|
|
2875
|
+
if (!isProbeError(error) || !this.#deadlines.has(error)) throw error;
|
|
2876
2876
|
}
|
|
2877
2877
|
}
|
|
2878
2878
|
#version(name) {
|
|
2879
2879
|
const version = readWorkspaceManifest(this.#workspace, name).contents.version;
|
|
2880
|
-
if (
|
|
2880
|
+
if (!isString(version)) throw new ProbeError(`${name} publishes no readable version`, {
|
|
2881
2881
|
origin: "workspace",
|
|
2882
2882
|
code: "malformed",
|
|
2883
2883
|
context: { name }
|