@valbuild/shared 0.148.6 → 0.149.7
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/CHANGELOG.md +17 -0
- package/client/dist/valbuild-shared-client.cjs.dev.js +2 -1
- package/client/dist/valbuild-shared-client.cjs.prod.js +2 -1
- package/client/dist/valbuild-shared-client.esm.js +2 -1
- package/dist/acquireTypes-50960f2c.esm.js +1801 -0
- package/dist/acquireTypes-de10005d.cjs.dev.js +1815 -0
- package/dist/acquireTypes-e9467a2a.cjs.prod.js +1815 -0
- package/dist/createForOfIteratorHelper-3db5d737.esm.js +121 -0
- package/dist/createForOfIteratorHelper-90e6a8b6.cjs.prod.js +129 -0
- package/dist/createForOfIteratorHelper-d86bb352.cjs.dev.js +129 -0
- package/dist/declarations/src/internal/ApiRoutes.d.ts +3 -3
- package/dist/declarations/src/internal/index.d.ts +1 -0
- package/dist/declarations/src/internal/selfCheck.d.ts +51 -0
- package/dist/declarations/src/publish/buildProposal.d.ts +106 -0
- package/dist/declarations/src/publish/builder.d.ts +22 -0
- package/dist/declarations/src/publish/callJson.d.ts +21 -0
- package/dist/declarations/src/publish/index.d.ts +23 -0
- package/dist/declarations/src/publish/jobClient.d.ts +96 -0
- package/dist/declarations/src/publish/loadedLayer.d.ts +50 -0
- package/dist/declarations/src/publish/proposalProject.d.ts +2 -0
- package/dist/declarations/src/publish/publishClient.d.ts +95 -0
- package/dist/declarations/src/publish/runStudioDeploy.d.ts +244 -0
- package/dist/declarations/src/publish/runStudioJob.d.ts +102 -0
- package/dist/declarations/src/publish/runStudioPublish.d.ts +80 -0
- package/dist/declarations/src/typecheck/acquireTypes.d.ts +109 -0
- package/dist/declarations/src/typecheck/adeptSources.d.ts +9 -0
- package/dist/declarations/src/typecheck/index.d.ts +20 -0
- package/dist/declarations/src/typecheck/linkedFileSystem.d.ts +53 -0
- package/dist/declarations/src/typecheck/lockedVersions.d.ts +14 -0
- package/dist/declarations/src/typecheck/pnpmLayout.d.ts +95 -0
- package/dist/declarations/src/typecheck/pnpmLockfile.d.ts +57 -0
- package/dist/declarations/src/typecheck/proposalTypecheck.d.ts +76 -0
- package/dist/declarations/src/typecheck/testing/index.d.ts +6 -0
- package/dist/declarations/src/typecheck/testing/nodeModulesSources.d.ts +5 -0
- package/dist/declarations/src/typecheck/typecheckProject.d.ts +89 -0
- package/dist/declarations/src/typecheck/typescriptCompiler.d.ts +52 -0
- package/dist/{getSitemapTree-40d76bf8.cjs.prod.js → getSitemapTree-0fa0569c.cjs.dev.js} +5 -131
- package/dist/{getSitemapTree-cd006a36.esm.js → getSitemapTree-5afbc3ac.esm.js} +2 -121
- package/dist/{getSitemapTree-a7f2cc6d.cjs.dev.js → getSitemapTree-667bcb3c.cjs.prod.js} +5 -131
- package/dist/proposalProject-28550146.cjs.prod.js +18 -0
- package/dist/proposalProject-a3d3ad76.esm.js +16 -0
- package/dist/proposalProject-cdc53711.cjs.dev.js +18 -0
- package/dist/protocol-1c13de0d.cjs.prod.js +433 -0
- package/dist/protocol-3b9ef786.esm.js +413 -0
- package/dist/protocol-d8a6efda.cjs.dev.js +433 -0
- package/dist/slicedToArray-62e428df.cjs.dev.js +309 -0
- package/dist/slicedToArray-6cd80315.esm.js +299 -0
- package/dist/slicedToArray-af50e684.cjs.prod.js +309 -0
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +419 -888
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +419 -888
- package/internal/dist/valbuild-shared-internal.esm.js +236 -707
- package/package.json +28 -5
- package/publish/dist/valbuild-shared-publish.cjs.d.ts +2 -0
- package/publish/dist/valbuild-shared-publish.cjs.dev.js +2466 -0
- package/publish/dist/valbuild-shared-publish.cjs.js +7 -0
- package/publish/dist/valbuild-shared-publish.cjs.prod.js +2466 -0
- package/publish/dist/valbuild-shared-publish.esm.js +2428 -0
- package/publish/package.json +4 -0
- package/typecheck/dist/valbuild-shared-typecheck.cjs.d.ts +2 -0
- package/typecheck/dist/valbuild-shared-typecheck.cjs.dev.js +1173 -0
- package/typecheck/dist/valbuild-shared-typecheck.cjs.js +7 -0
- package/typecheck/dist/valbuild-shared-typecheck.cjs.prod.js +1173 -0
- package/typecheck/dist/valbuild-shared-typecheck.esm.js +1152 -0
- package/typecheck/package.json +4 -0
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.d.ts +2 -0
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.dev.js +202 -0
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.js +7 -0
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.prod.js +202 -0
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.esm.js +177 -0
- package/typecheck/testing/package.json +4 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { LinkedFileSystem } from "./linkedFileSystem.js";
|
|
2
|
+
import type { LayoutPackage, PnpmLayout } from "./pnpmLayout.js";
|
|
3
|
+
import type { CompilerBundle, TypeScript } from "./typescriptCompiler.js";
|
|
4
|
+
/**
|
|
5
|
+
* adept's `/types/<partition>/<name>@<version>`: a package version's
|
|
6
|
+
* declaration files and every `package.json`, by path relative to the
|
|
7
|
+
* package's root, and the names of its JavaScript files.
|
|
8
|
+
*/
|
|
9
|
+
export type TypesBundle = {
|
|
10
|
+
files: Record<string, string>;
|
|
11
|
+
stubs: string[];
|
|
12
|
+
};
|
|
13
|
+
export type PackageRef = {
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
integrity: string | null;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Where bundles and compilers come from. In the Studio that is adept,
|
|
20
|
+
* through the Studio's server (`adeptSources.ts`); tests and Node scripts
|
|
21
|
+
* give their own.
|
|
22
|
+
*/
|
|
23
|
+
export type TypecheckSources = {
|
|
24
|
+
types(pkg: PackageRef): Promise<TypesBundle>;
|
|
25
|
+
compiler(version: string): Promise<CompilerBundle>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A failed request for a bundle or a compiler, by what can be done about it.
|
|
29
|
+
* `status` 401 means signed out, and stops the whole check: every other
|
|
30
|
+
* request would fail the same way.
|
|
31
|
+
*/
|
|
32
|
+
export declare class SourceError extends Error {
|
|
33
|
+
readonly code: string;
|
|
34
|
+
readonly retryable: boolean;
|
|
35
|
+
readonly status: number | null;
|
|
36
|
+
constructor(message: string, code: string, retryable: boolean, status?: number | null);
|
|
37
|
+
}
|
|
38
|
+
/** A package whose types could not be had, so the check that follows is incomplete. */
|
|
39
|
+
export type MissingTypes = PackageRef & {
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
retryable: boolean;
|
|
43
|
+
};
|
|
44
|
+
export type AcquisitionStats = {
|
|
45
|
+
/** Bundles fetched because an import or a type reference named them. */
|
|
46
|
+
scanned: number;
|
|
47
|
+
/** Bundles fetched because TypeScript went looking in them while resolving. */
|
|
48
|
+
resolved: number;
|
|
49
|
+
files: number;
|
|
50
|
+
stubs: number;
|
|
51
|
+
/** Characters of declaration text, about the bytes once unpacked. */
|
|
52
|
+
bytes: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The package a bare specifier names: `react` of `react/jsx-runtime`,
|
|
56
|
+
* `@tanstack/react-router` of itself. `null` for anything that is not looked
|
|
57
|
+
* up in `node_modules`: relative and absolute paths, `#subpath` imports and
|
|
58
|
+
* `node:` and other schemes.
|
|
59
|
+
*/
|
|
60
|
+
export declare function packageNameOf(specifier: string): string | null;
|
|
61
|
+
/** `@types/node` for `node`, `@types/scope__name` for `@scope/name`. */
|
|
62
|
+
export declare function typesPackageOf(name: string): string;
|
|
63
|
+
/** The package directory a real path is in: up to the name after its last `node_modules`. */
|
|
64
|
+
export declare function packageDirOf(realPath: string): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Fetches the types a project's imports reach, and only those, and writes
|
|
67
|
+
* each bundle at its snapshot's directory in the virtual store, so that the
|
|
68
|
+
* layout's links make it visible wherever pnpm would.
|
|
69
|
+
*
|
|
70
|
+
* {@link wantImportsOf} scans a file's imports and type references; each
|
|
71
|
+
* bare one is looked for as Node looks for it, from the file's directory up
|
|
72
|
+
* through each `node_modules` (and its `@types` twin), and the nearest level
|
|
73
|
+
* that has it is fetched. A fetched bundle's declaration files are scanned in
|
|
74
|
+
* turn, so type dependencies are followed transitively. {@link wantPackage}
|
|
75
|
+
* fetches a package by directory, for when TypeScript itself went looking in
|
|
76
|
+
* one.
|
|
77
|
+
*/
|
|
78
|
+
export declare class TypeAcquisition {
|
|
79
|
+
private readonly ts;
|
|
80
|
+
private readonly fs;
|
|
81
|
+
private readonly layout;
|
|
82
|
+
private readonly sources;
|
|
83
|
+
private readonly concurrency;
|
|
84
|
+
private readonly started;
|
|
85
|
+
private readonly running;
|
|
86
|
+
private readonly queue;
|
|
87
|
+
private fatal;
|
|
88
|
+
readonly missing: MissingTypes[];
|
|
89
|
+
readonly stats: AcquisitionStats;
|
|
90
|
+
constructor(ts: TypeScript, fs: LinkedFileSystem, layout: PnpmLayout, sources: TypecheckSources, concurrency?: number);
|
|
91
|
+
/** Whether `dir` is a package this has fetched, or tried to. */
|
|
92
|
+
has(dir: string): boolean;
|
|
93
|
+
/** The installed package at a real directory, if it is one. */
|
|
94
|
+
packageAt(dir: string): LayoutPackage | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* The packages a bare name reaches from `fromDir`: at the nearest
|
|
97
|
+
* `node_modules` that has the package or its `@types`, both.
|
|
98
|
+
*/
|
|
99
|
+
findPackages(fromDir: string, name: string): string[];
|
|
100
|
+
/** Wants what a bare specifier names, from a file in `fromDir`. */
|
|
101
|
+
wantSpecifier(fromDir: string, specifier: string): void;
|
|
102
|
+
/** Wants every package a file's imports and type references reach. */
|
|
103
|
+
wantImportsOf(realPath: string, text: string): void;
|
|
104
|
+
wantPackage(dir: string, via: "scanned" | "resolved"): void;
|
|
105
|
+
private pump;
|
|
106
|
+
/** Resolves when everything wanted so far, and everything that wanted, is fetched. */
|
|
107
|
+
settle(): Promise<void>;
|
|
108
|
+
private fetch;
|
|
109
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TypecheckSources } from "./acquireTypes.js";
|
|
2
|
+
export declare function adeptSources(options: {
|
|
3
|
+
base: string;
|
|
4
|
+
fetch?: typeof fetch;
|
|
5
|
+
/** A credential to send, where the caller has one to (`Authorization`). */
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
/** Whether cookies go too: `same-origin` (the default) for the Studio's own server. */
|
|
8
|
+
credentials?: RequestInit["credentials"];
|
|
9
|
+
}): TypecheckSources;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type errors a project would have after `pnpm install`, computed in
|
|
3
|
+
* memory: the layout from the lockfile, the types its imports reach from
|
|
4
|
+
* adept, and the project's own TypeScript over both (valbuild/home
|
|
5
|
+
* `docs/adept.md`, step 4).
|
|
6
|
+
*
|
|
7
|
+
* Here rather than in the Studio because two callers run it: the Studio, for
|
|
8
|
+
* a proposal that changes dependencies, and home's upgrade page, which pins
|
|
9
|
+
* this package at an exact version so that a site's own Val never reaches
|
|
10
|
+
* its upgrade (valbuild/home `docs/plans/upgrades-v2.md`, piece E). It runs
|
|
11
|
+
* anywhere a module runs; each caller puts it in a worker of its own.
|
|
12
|
+
*/
|
|
13
|
+
export { typecheckProject, newErrors, layoutOf, PROJECT_ROOT, type TypecheckInput, type TypecheckProgress, type TypecheckResult, type TypeErrorEntry, type ProgramSummary, } from "./typecheckProject.js";
|
|
14
|
+
export { SourceError, packageNameOf, typesPackageOf, type PackageRef, type TypesBundle, type TypecheckSources, type MissingTypes, type AcquisitionStats, } from "./acquireTypes.js";
|
|
15
|
+
export { adeptSources } from "./adeptSources.js";
|
|
16
|
+
export { lockedPackages, typescriptVersion, type Locked, } from "./lockedVersions.js";
|
|
17
|
+
export { LockfileError } from "./pnpmLockfile.js";
|
|
18
|
+
export { UnsupportedLayoutError } from "./pnpmLayout.js";
|
|
19
|
+
export { BUNDLED_TYPESCRIPT, CompilerError, chooseCompiler, type CompilerBundle, type CompilerChoice, } from "./typescriptCompiler.js";
|
|
20
|
+
export { MAX_REPORTED_ERRORS, errorsByFile, reportedError, runProposalTypecheck, type ProposalTypeError, type ProposalTypecheckClient, type ProposalTypecheckDeps, type ProposalTypecheckOutcome, type ProposalTypecheckStep, } from "./proposalTypecheck.js";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files in memory, with directory symlinks: enough of a disk for
|
|
3
|
+
* TypeScript's module resolution to see `node_modules` as pnpm leaves it.
|
|
4
|
+
*
|
|
5
|
+
* Files are written at their real paths. A link maps a path to the directory
|
|
6
|
+
* it points at, and every read goes through `realpath` first, so
|
|
7
|
+
* `/project/node_modules/react/index.d.ts` reads the file written at
|
|
8
|
+
* `/project/node_modules/.pnpm/react@19.3.0/node_modules/react/index.d.ts`.
|
|
9
|
+
*
|
|
10
|
+
* The directory index is what makes resolution work, and it needs two things
|
|
11
|
+
* a list of files does not give: every directory a file is in (TypeScript
|
|
12
|
+
* asks `directoryExists` before it looks inside), and every linked directory
|
|
13
|
+
* -- a link's own name is listed in its parent, and the directory it points
|
|
14
|
+
* at exists even before anything has been written into it. Without the
|
|
15
|
+
* first, packages are reported missing; without the second, so are packages
|
|
16
|
+
* whose files have not been fetched, and `node_modules/@types` cannot be
|
|
17
|
+
* listed.
|
|
18
|
+
*
|
|
19
|
+
* Every lookup of a path is also reported to `onLookup`, with the real path
|
|
20
|
+
* it resolved to, so that a caller can tell which packages TypeScript went
|
|
21
|
+
* looking in.
|
|
22
|
+
*/
|
|
23
|
+
export declare class LinkedFileSystem {
|
|
24
|
+
private readonly files;
|
|
25
|
+
/** Real directory → the names of its entries, files and directories (links included). */
|
|
26
|
+
private readonly directories;
|
|
27
|
+
private readonly links;
|
|
28
|
+
/** The links never change, so neither does a path's real path. */
|
|
29
|
+
private readonly realpaths;
|
|
30
|
+
onLookup: ((realPath: string) => void) | null;
|
|
31
|
+
constructor(links: Map<string, string>);
|
|
32
|
+
private entriesOf;
|
|
33
|
+
/** `dir` and every directory above it. */
|
|
34
|
+
private addDirectory;
|
|
35
|
+
/** Lists `path` in its parent; the parent's real path, as `path` may sit under a link. */
|
|
36
|
+
private addEntry;
|
|
37
|
+
/** Resolves every link along `path`, as `fs.realpathSync` does. */
|
|
38
|
+
realpath(path: string): string;
|
|
39
|
+
private resolveLinks;
|
|
40
|
+
writeFile(realPath: string, text: string): void;
|
|
41
|
+
private lookup;
|
|
42
|
+
readFile(path: string): string | undefined;
|
|
43
|
+
fileExists(path: string): boolean;
|
|
44
|
+
directoryExists(path: string): boolean;
|
|
45
|
+
/** The directories in `path`, links to directories included. */
|
|
46
|
+
getDirectories(path: string): string[];
|
|
47
|
+
/** The files in `path`. */
|
|
48
|
+
getFiles(path: string): string[];
|
|
49
|
+
/** Every file written, by real path. */
|
|
50
|
+
allFiles(): IterableIterator<string>;
|
|
51
|
+
}
|
|
52
|
+
export declare function parentOf(path: string): string;
|
|
53
|
+
export declare function baseName(path: string): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read straight from a pnpm lockfile's text, with no YAML parser: what
|
|
3
|
+
* `/val/adept` lists, and which TypeScript the typecheck loads.
|
|
4
|
+
* `pnpmLockfile.ts` is the full reader.
|
|
5
|
+
*/
|
|
6
|
+
export type Locked = {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
integrity?: string;
|
|
10
|
+
};
|
|
11
|
+
/** The registry packages a pnpm 9 lockfile's `packages:` section names. */
|
|
12
|
+
export declare function lockedPackages(lockfile: string): Locked[];
|
|
13
|
+
/** The version the root importer's lockfile entry gives `typescript`. */
|
|
14
|
+
export declare function typescriptVersion(lockfile: string): string | null;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type PnpmLockfile } from "./pnpmLockfile.js";
|
|
2
|
+
/**
|
|
3
|
+
* What `pnpm install --frozen-lockfile` puts in `node_modules`, computed from
|
|
4
|
+
* the lockfile alone, as a table of symlinks.
|
|
5
|
+
*
|
|
6
|
+
* Ported from pnpm's own crates (valbuild/pnpm, pacquet 12.13.0):
|
|
7
|
+
* `deps-path/src/dep_path_to_filename.rs` names each snapshot's directory in
|
|
8
|
+
* the virtual store, and `deps-restorer/src/hoist.rs` decides which
|
|
9
|
+
* transitive dependencies are also linked into the private hoist
|
|
10
|
+
* (`node_modules/.pnpm/node_modules`). The defaults are pnpm 12's: hoist
|
|
11
|
+
* `["*"]` privately, nothing publicly, virtual store names at most 120 bytes,
|
|
12
|
+
* no global virtual store. `pnpmLayout.test.ts` compares the result with
|
|
13
|
+
* what a real install left on disk.
|
|
14
|
+
*
|
|
15
|
+
* Every path is absolute, under `root` (default `/project`), with `/`
|
|
16
|
+
* separators.
|
|
17
|
+
*/
|
|
18
|
+
export type PnpmLayout = {
|
|
19
|
+
root: string;
|
|
20
|
+
/** `<root>/node_modules/.pnpm` */
|
|
21
|
+
virtualStore: string;
|
|
22
|
+
/** Every symlink: its own path, to the absolute directory it points at. */
|
|
23
|
+
links: Map<string, string>;
|
|
24
|
+
/** Every installed snapshot, by the directory its package's files are in. */
|
|
25
|
+
packages: Map<string, LayoutPackage>;
|
|
26
|
+
/** Each importer's directory, by its id (`.` is the root project). */
|
|
27
|
+
importers: Map<string, string>;
|
|
28
|
+
/** Snapshots `pnpm install` would skip: optional, and not for this platform. */
|
|
29
|
+
skipped: Set<string>;
|
|
30
|
+
};
|
|
31
|
+
export type LayoutPackage = {
|
|
32
|
+
/** The snapshot key: `name@version(peers)`. */
|
|
33
|
+
snapshot: string;
|
|
34
|
+
name: string;
|
|
35
|
+
version: string;
|
|
36
|
+
/** `null` for a package the lockfile does not give an integrity for (a tarball URL, git). */
|
|
37
|
+
integrity: string | null;
|
|
38
|
+
/** Whether it comes from a registry by name and version, so its types can be asked for. */
|
|
39
|
+
fromRegistry: boolean;
|
|
40
|
+
};
|
|
41
|
+
/** What `pnpm install` checks optional packages' `os`, `cpu` and `libc` against. */
|
|
42
|
+
export type Platform = {
|
|
43
|
+
os: string;
|
|
44
|
+
cpu: string;
|
|
45
|
+
libc: string | null;
|
|
46
|
+
};
|
|
47
|
+
export type LayoutOptions = {
|
|
48
|
+
root?: string;
|
|
49
|
+
/** `null` installs every optional package, whatever it is built for. */
|
|
50
|
+
platform?: Platform | null;
|
|
51
|
+
hoistPattern?: string[];
|
|
52
|
+
publicHoistPattern?: string[];
|
|
53
|
+
virtualStoreDirMaxLength?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Each workspace project's `name`, by importer id, from its package.json.
|
|
56
|
+
* The lockfile does not carry them, and pnpm links every named project
|
|
57
|
+
* into the hoist as well (`hoist-workspace-packages`).
|
|
58
|
+
*/
|
|
59
|
+
workspaceNames?: Record<string, string>;
|
|
60
|
+
/** `hoistWorkspacePackages`, on unless the workspace turns it off. */
|
|
61
|
+
hoistWorkspacePackages?: boolean;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Linux on x64 with glibc: what a CI runner and the build are, and so the
|
|
65
|
+
* install the typecheck is compared with. It only decides which optional,
|
|
66
|
+
* platform-specific packages exist, which hardly ever carry types.
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEFAULT_PLATFORM: Platform;
|
|
69
|
+
/**
|
|
70
|
+
* The directory name of a snapshot in the virtual store: pnpm's
|
|
71
|
+
* `dep_path_to_filename`. `@scope/foo@1.0.0(bar@2.0.0)` is
|
|
72
|
+
* `@scope+foo@1.0.0_bar@2.0.0`; a name longer than `maxLength` bytes, or with
|
|
73
|
+
* upper case letters, is cut and given a hash of the whole.
|
|
74
|
+
*/
|
|
75
|
+
export declare function depPathToFilename(depPath: string, maxLength?: number): string;
|
|
76
|
+
/**
|
|
77
|
+
* pnpm's `WildcardMatcher` lists: `*` is any run of characters, `?` one, a
|
|
78
|
+
* leading `!` excludes, and a later exclude cancels an earlier include.
|
|
79
|
+
*/
|
|
80
|
+
export declare function createMatcher(patterns: string[]): (input: string) => boolean;
|
|
81
|
+
/** `a/b/../c` → `a/c`, for absolute `/`-separated paths. */
|
|
82
|
+
export declare function normalizePath(path: string): string;
|
|
83
|
+
/** A setting in `pnpm-workspace.yaml` the layout cannot follow. */
|
|
84
|
+
export declare class UnsupportedLayoutError extends Error {
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The settings in `pnpm-workspace.yaml` that change the layout: `hoist`,
|
|
88
|
+
* `hoistPattern`, `publicHoistPattern`, `shamefullyHoist` and
|
|
89
|
+
* `virtualStoreDirMaxLength`. pnpm 11 and later read these from there and not
|
|
90
|
+
* from `.npmrc`. `nodeLinker` other than `isolated` is a different layout
|
|
91
|
+
* altogether, and refused.
|
|
92
|
+
*/
|
|
93
|
+
export declare function layoutOptionsOfWorkspace(workspace: Record<string, unknown>): LayoutOptions;
|
|
94
|
+
/** What `pnpm install` would put in `node_modules` for this lockfile. */
|
|
95
|
+
export declare function computePnpmLayout(lockfile: PnpmLockfile, options?: LayoutOptions): PnpmLayout;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts of a `pnpm-lock.yaml` (lockfile version 9) that decide what
|
|
3
|
+
* `pnpm install` puts in `node_modules`.
|
|
4
|
+
*
|
|
5
|
+
* Only what the layout needs is kept: each importer's direct dependencies,
|
|
6
|
+
* each package's integrity and platform constraints, and each snapshot's own
|
|
7
|
+
* dependencies. Everything is a plain string as pnpm wrote it -- a reference
|
|
8
|
+
* such as `19.3.0(react@19.3.0)` is turned into a snapshot key by
|
|
9
|
+
* {@link snapshotKeyOf}, as pnpm's lockfile crate does.
|
|
10
|
+
*/
|
|
11
|
+
export type PnpmLockfile = {
|
|
12
|
+
importers: Record<string, ImporterSnapshot>;
|
|
13
|
+
/** Keyed `<name>@<version>`, without peers. */
|
|
14
|
+
packages: Record<string, PackageInfo>;
|
|
15
|
+
/** Keyed `<name>@<version>(<peer>)…`: one per installed copy. */
|
|
16
|
+
snapshots: Record<string, SnapshotInfo>;
|
|
17
|
+
};
|
|
18
|
+
/** An importer's dependencies, alias to the reference pnpm locked it at. */
|
|
19
|
+
export type ImporterSnapshot = {
|
|
20
|
+
dependencies: Record<string, string>;
|
|
21
|
+
devDependencies: Record<string, string>;
|
|
22
|
+
optionalDependencies: Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
export type PackageInfo = {
|
|
25
|
+
integrity: string | null;
|
|
26
|
+
/** `resolution.tarball`, for a package that is not at its registry's standard place. */
|
|
27
|
+
tarball: string | null;
|
|
28
|
+
os: string[] | null;
|
|
29
|
+
cpu: string[] | null;
|
|
30
|
+
libc: string[] | null;
|
|
31
|
+
hasBin: boolean;
|
|
32
|
+
};
|
|
33
|
+
export type SnapshotInfo = {
|
|
34
|
+
dependencies: Record<string, string>;
|
|
35
|
+
optionalDependencies: Record<string, string>;
|
|
36
|
+
optional: boolean;
|
|
37
|
+
};
|
|
38
|
+
/** A lockfile this cannot read: not YAML, or not pnpm's version 9 shape. */
|
|
39
|
+
export declare class LockfileError extends Error {
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reads a pnpm 9 lockfile. pnpm 11 and later may put a document of their own
|
|
43
|
+
* (the package manager's dependencies) before the project's, so the document
|
|
44
|
+
* read is the one that has `importers`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parsePnpmLockfile(text: string): PnpmLockfile;
|
|
47
|
+
/** `@scope/name` of `@scope/name@1.0.0(peer@2.0.0)`. */
|
|
48
|
+
export declare function nameOfKey(key: string): string;
|
|
49
|
+
/** `1.0.0` of `@scope/name@1.0.0(peer@2.0.0)`: the version, without peers. */
|
|
50
|
+
export declare function versionOfKey(key: string): string;
|
|
51
|
+
/** The `packages:` key a snapshot key's metadata is under: the key without its peers. */
|
|
52
|
+
export declare function packageKeyOf(snapshotKey: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* The snapshot a dependency reference points at, or `null` for a `link:` to
|
|
55
|
+
* a directory (a workspace sibling), which is not in the virtual store.
|
|
56
|
+
*/
|
|
57
|
+
export declare function snapshotKeyOf(alias: string, reference: string): string | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { TypecheckProgress, TypecheckResult } from "./typecheckProject.js";
|
|
2
|
+
import { type TypeErrorEntry } from "./typecheckProject.js";
|
|
3
|
+
/** At most this many of the new errors are sent; the count says how many. */
|
|
4
|
+
export declare const MAX_REPORTED_ERRORS = 200;
|
|
5
|
+
/** What the typecheck is doing, as it says so. */
|
|
6
|
+
export type ProposalTypecheckStep = {
|
|
7
|
+
step: "reading";
|
|
8
|
+
} | {
|
|
9
|
+
step: "lockfile";
|
|
10
|
+
} | {
|
|
11
|
+
step: "checking";
|
|
12
|
+
which: "site" | "proposal";
|
|
13
|
+
detail: string;
|
|
14
|
+
};
|
|
15
|
+
/** A new type error as content keeps it: a file always, a position always. */
|
|
16
|
+
export type ProposalTypeError = {
|
|
17
|
+
file: string;
|
|
18
|
+
line: number;
|
|
19
|
+
column: number;
|
|
20
|
+
code: number;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The calls a proposal's typecheck makes: the Studio's through its origin,
|
|
25
|
+
* home's upgrade page to content directly. `T` is the report as content
|
|
26
|
+
* answers it.
|
|
27
|
+
*/
|
|
28
|
+
export type ProposalTypecheckClient<T> = {
|
|
29
|
+
files(name: string): Promise<{
|
|
30
|
+
files: Record<string, string | null>;
|
|
31
|
+
staged: {
|
|
32
|
+
inputs: string | null;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
reportTypecheck(name: string, report: {
|
|
36
|
+
inputs: string;
|
|
37
|
+
newErrors: ProposalTypeError[];
|
|
38
|
+
count?: number;
|
|
39
|
+
}): Promise<T>;
|
|
40
|
+
};
|
|
41
|
+
export type ProposalTypecheckDeps<T> = {
|
|
42
|
+
name: string;
|
|
43
|
+
client: ProposalTypecheckClient<T>;
|
|
44
|
+
/** The site's code, as its live build has it; `null` when nothing is live. */
|
|
45
|
+
siteSource: () => Promise<Record<string, string> | null>;
|
|
46
|
+
/** The site's recorded `pnpm-lock.yaml` and `pnpm-workspace.yaml`. */
|
|
47
|
+
siteDependencyFiles: () => Promise<Record<string, string>>;
|
|
48
|
+
/** A lockfile for `packageJson`, for a site that has none on record. */
|
|
49
|
+
computeLockfile: (packageJson: string, signal: AbortSignal) => Promise<string>;
|
|
50
|
+
check: (input: {
|
|
51
|
+
files: Record<string, string>;
|
|
52
|
+
lockfile: string;
|
|
53
|
+
workspace: string | null;
|
|
54
|
+
}, options: {
|
|
55
|
+
onProgress: (progress: TypecheckProgress) => void;
|
|
56
|
+
signal: AbortSignal;
|
|
57
|
+
}) => Promise<TypecheckResult>;
|
|
58
|
+
onStep?: (step: ProposalTypecheckStep) => void;
|
|
59
|
+
signal: AbortSignal;
|
|
60
|
+
};
|
|
61
|
+
export type ProposalTypecheckOutcome<T> =
|
|
62
|
+
/** Nothing staged: there is nothing of the proposal's to check. */
|
|
63
|
+
{
|
|
64
|
+
status: "nothing-staged";
|
|
65
|
+
} | {
|
|
66
|
+
status: "checked";
|
|
67
|
+
inputs: string;
|
|
68
|
+
/** Every new error, not only the ones sent. */
|
|
69
|
+
errors: ProposalTypeError[];
|
|
70
|
+
typecheck: T;
|
|
71
|
+
};
|
|
72
|
+
/** A type error as content keeps it: a file always, a position always. */
|
|
73
|
+
export declare function reportedError(error: TypeErrorEntry): ProposalTypeError;
|
|
74
|
+
export declare function runProposalTypecheck<T>(deps: ProposalTypecheckDeps<T>): Promise<ProposalTypecheckOutcome<T>>;
|
|
75
|
+
/** New errors by file, each file's in order: how the dialog lists them. */
|
|
76
|
+
export declare function errorsByFile(errors: ProposalTypeError[]): [string, ProposalTypeError[]][];
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type AcquisitionStats, type MissingTypes, type TypecheckSources } from "./acquireTypes.js";
|
|
2
|
+
import { type PnpmLayout } from "./pnpmLayout.js";
|
|
3
|
+
import { type PnpmLockfile } from "./pnpmLockfile.js";
|
|
4
|
+
import { type CompilerChoice } from "./typescriptCompiler.js";
|
|
5
|
+
/**
|
|
6
|
+
* The type errors a project would have after `pnpm install`, computed in
|
|
7
|
+
* memory: the layout from the lockfile, the types its imports reach from
|
|
8
|
+
* adept, and the project's own TypeScript over both. See `docs` in
|
|
9
|
+
* valbuild/home's `adept.md`, step 4.
|
|
10
|
+
*/
|
|
11
|
+
export type TypecheckInput = {
|
|
12
|
+
/** The project's files, by `/`-separated path relative to its root. */
|
|
13
|
+
files: Record<string, string>;
|
|
14
|
+
lockfile: string;
|
|
15
|
+
/** `pnpm-workspace.yaml`, when the project has one: it can change the layout. */
|
|
16
|
+
workspace?: string | null;
|
|
17
|
+
sources: TypecheckSources;
|
|
18
|
+
onProgress?: (progress: TypecheckProgress) => void;
|
|
19
|
+
/** Also return every file in each program, as `tsc --listFiles` prints them. */
|
|
20
|
+
listFiles?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type TypecheckProgress = {
|
|
23
|
+
step: "layout";
|
|
24
|
+
} | {
|
|
25
|
+
step: "compiler";
|
|
26
|
+
version: string;
|
|
27
|
+
} | {
|
|
28
|
+
step: "types";
|
|
29
|
+
fetched: number;
|
|
30
|
+
} | {
|
|
31
|
+
step: "check";
|
|
32
|
+
tsconfig: string;
|
|
33
|
+
};
|
|
34
|
+
export type TypeErrorEntry = {
|
|
35
|
+
/** Relative to the project's root; `null` for an error of no file (an option, a missing lib). */
|
|
36
|
+
file: string | null;
|
|
37
|
+
/** 1-based. */
|
|
38
|
+
line: number | null;
|
|
39
|
+
column: number | null;
|
|
40
|
+
code: number;
|
|
41
|
+
message: string;
|
|
42
|
+
/** The tsconfig whose program reported it. */
|
|
43
|
+
tsconfig: string;
|
|
44
|
+
};
|
|
45
|
+
export type ProgramSummary = {
|
|
46
|
+
tsconfig: string;
|
|
47
|
+
/** Files in the program, the project's and the declarations it reached. */
|
|
48
|
+
files: number;
|
|
49
|
+
errors: number;
|
|
50
|
+
/** With `listFiles`: each file's path, relative to the project's root when it is under it. */
|
|
51
|
+
fileNames?: string[];
|
|
52
|
+
};
|
|
53
|
+
export type TypecheckResult = {
|
|
54
|
+
errors: TypeErrorEntry[];
|
|
55
|
+
programs: ProgramSummary[];
|
|
56
|
+
typescript: CompilerChoice;
|
|
57
|
+
bundles: AcquisitionStats & {
|
|
58
|
+
count: number;
|
|
59
|
+
rounds: number;
|
|
60
|
+
};
|
|
61
|
+
/** Packages whose types could not be fetched: errors about them may be wrong. */
|
|
62
|
+
missing: MissingTypes[];
|
|
63
|
+
timings: {
|
|
64
|
+
layoutMs: number;
|
|
65
|
+
compilerMs: number;
|
|
66
|
+
typesMs: number;
|
|
67
|
+
checkMs: number;
|
|
68
|
+
totalMs: number;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
/** The project's root in the file system the checker builds. */
|
|
72
|
+
export declare const PROJECT_ROOT = "/project";
|
|
73
|
+
export declare function layoutOf(input: {
|
|
74
|
+
lockfile: string;
|
|
75
|
+
workspace?: string | null;
|
|
76
|
+
files: Record<string, string>;
|
|
77
|
+
}): {
|
|
78
|
+
lockfile: PnpmLockfile;
|
|
79
|
+
layout: PnpmLayout;
|
|
80
|
+
};
|
|
81
|
+
/** Typechecks a project as it would be after `pnpm install`. */
|
|
82
|
+
export declare function typecheckProject(input: TypecheckInput): Promise<TypecheckResult>;
|
|
83
|
+
/**
|
|
84
|
+
* The errors of `next` that `base` does not have (decision 20): an upgrade
|
|
85
|
+
* is judged only by the errors it adds. Errors are matched by file, code and
|
|
86
|
+
* message, not by position, so that an error which only moved is not new;
|
|
87
|
+
* and counted, so that a second copy of an error the base has once is.
|
|
88
|
+
*/
|
|
89
|
+
export declare function newErrors(base: TypeErrorEntry[], next: TypeErrorEntry[]): TypeErrorEntry[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
/** The TypeScript API, from whichever `typescript.js` was loaded. */
|
|
3
|
+
export type TypeScript = typeof TS;
|
|
4
|
+
/** adept's `/compiler/<version>`: `lib/typescript.js` and every `lib/lib.*.d.ts`. */
|
|
5
|
+
export type CompilerBundle = {
|
|
6
|
+
version: string;
|
|
7
|
+
files: Record<string, string>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The TypeScript a project gets when its own cannot run here.
|
|
11
|
+
*
|
|
12
|
+
* TypeScript 7 and later are a native compiler with no JavaScript one
|
|
13
|
+
* (`lib/typescript.js`), so they cannot run in a browser; a project with no
|
|
14
|
+
* `typescript` at all has none to choose. Both are checked with this 6.x,
|
|
15
|
+
* the one the Studio itself is built and tested with
|
|
16
|
+
* (`typescriptCompiler.test.ts` keeps the two the same). It is fetched from
|
|
17
|
+
* adept like any other, rather than shipped in the Studio's bundle, which is
|
|
18
|
+
* embedded in every Val server.
|
|
19
|
+
*/
|
|
20
|
+
export declare const BUNDLED_TYPESCRIPT = "6.0.3";
|
|
21
|
+
/** Which TypeScript checks a project, and why that one. */
|
|
22
|
+
export type CompilerChoice = {
|
|
23
|
+
version: string;
|
|
24
|
+
/** What the root importer's lockfile entry gives, if anything. */
|
|
25
|
+
wanted: string | null;
|
|
26
|
+
reason: "project" | "no-typescript" | "no-js-compiler";
|
|
27
|
+
};
|
|
28
|
+
export declare function chooseCompiler(wanted: string | null): CompilerChoice;
|
|
29
|
+
/** A TypeScript that does not have what a typecheck needs. */
|
|
30
|
+
export declare class CompilerError extends Error {
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Evaluates `lib/typescript.js` and returns its API.
|
|
34
|
+
*
|
|
35
|
+
* It is a CommonJS module that also runs as a plain script, so it is given a
|
|
36
|
+
* `module` to assign to. `require` and `process` are given as `undefined`,
|
|
37
|
+
* as they are in a worker, so that it does not build a Node `ts.sys` when it
|
|
38
|
+
* runs under Node: everything it reads goes through the host this
|
|
39
|
+
* typechecker gives it.
|
|
40
|
+
*/
|
|
41
|
+
export declare function evaluateTypeScript(source: string): TypeScript;
|
|
42
|
+
/**
|
|
43
|
+
* `ts.matchFiles`, which is how `tsc` expands a tsconfig's `include` and
|
|
44
|
+
* `exclude`. It is internal, but every `typescript.js` since 2.x has it on
|
|
45
|
+
* its API object, and using it is the only way to agree with `tsc` on hidden
|
|
46
|
+
* files, `node_modules` and implicit directory globs.
|
|
47
|
+
*/
|
|
48
|
+
export type MatchFiles = (path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => {
|
|
49
|
+
files: readonly string[];
|
|
50
|
+
directories: readonly string[];
|
|
51
|
+
}, realpath: (path: string) => string) => string[];
|
|
52
|
+
export declare function matchFilesOf(ts: TypeScript): MatchFiles;
|