@packall/core 0.1.0 → 0.2.0

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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/archive-6sqTn1C4.js +274 -0
  4. package/dist/archive-6sqTn1C4.js.map +1 -0
  5. package/dist/archive.d.ts +47 -15
  6. package/dist/archive.d.ts.map +1 -1
  7. package/dist/bundle.d.ts +6 -3
  8. package/dist/bundle.d.ts.map +1 -1
  9. package/dist/dependency-range.d.ts.map +1 -1
  10. package/dist/download.d.ts +2 -1
  11. package/dist/download.d.ts.map +1 -1
  12. package/dist/enums/artifact-kind.d.ts.map +1 -1
  13. package/dist/enums/edge-kind.d.ts.map +1 -1
  14. package/dist/enums/input-file-kind.d.ts.map +1 -1
  15. package/dist/enums/layout.d.ts.map +1 -1
  16. package/dist/enums/lockfile-format.d.ts.map +1 -1
  17. package/dist/enums/phase.d.ts.map +1 -1
  18. package/dist/errors.d.ts.map +1 -1
  19. package/dist/index.d.ts +12 -10
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +169 -344
  22. package/dist/index.js.map +1 -1
  23. package/dist/input-file.d.ts.map +1 -1
  24. package/dist/integrity.d.ts +37 -5
  25. package/dist/integrity.d.ts.map +1 -1
  26. package/dist/layout.d.ts +41 -7
  27. package/dist/layout.d.ts.map +1 -1
  28. package/dist/locked-resolve.d.ts.map +1 -1
  29. package/dist/lockfile/bun.d.ts.map +1 -1
  30. package/dist/lockfile/detect.d.ts.map +1 -1
  31. package/dist/lockfile/json.d.ts.map +1 -1
  32. package/dist/lockfile/names.d.ts.map +1 -1
  33. package/dist/lockfile/npm.d.ts.map +1 -1
  34. package/dist/lockfile/parse.d.ts.map +1 -1
  35. package/dist/lockfile/pnpm.d.ts.map +1 -1
  36. package/dist/lockfile/tree-builder.d.ts.map +1 -1
  37. package/dist/lockfile/types.d.ts.map +1 -1
  38. package/dist/manifest.d.ts.map +1 -1
  39. package/dist/node/archiver.d.ts +5 -0
  40. package/dist/node/archiver.d.ts.map +1 -0
  41. package/dist/node/index.d.ts +13 -0
  42. package/dist/node/index.d.ts.map +1 -0
  43. package/dist/node/index.js +55 -0
  44. package/dist/node/index.js.map +1 -0
  45. package/dist/options.d.ts +3 -3
  46. package/dist/options.d.ts.map +1 -1
  47. package/dist/platform.d.ts +5 -10
  48. package/dist/platform.d.ts.map +1 -1
  49. package/dist/progress.d.ts.map +1 -1
  50. package/dist/registry.d.ts.map +1 -1
  51. package/dist/resolve.d.ts.map +1 -1
  52. package/dist/schemas/lenient.d.ts.map +1 -1
  53. package/dist/schemas/package-json.d.ts.map +1 -1
  54. package/dist/spec.d.ts.map +1 -1
  55. package/dist/types/value-of.d.ts.map +1 -1
  56. package/dist/utils/is-record.d.ts.map +1 -1
  57. package/package.json +11 -10
  58. package/src/archive.ts +95 -92
  59. package/src/bundle.ts +736 -616
  60. package/src/dependency-range.ts +121 -115
  61. package/src/download.ts +155 -133
  62. package/src/enums/artifact-kind.ts +5 -5
  63. package/src/enums/edge-kind.ts +13 -13
  64. package/src/enums/input-file-kind.ts +9 -9
  65. package/src/enums/layout.ts +20 -20
  66. package/src/enums/lockfile-format.ts +6 -6
  67. package/src/enums/phase.ts +8 -8
  68. package/src/errors.ts +200 -198
  69. package/src/index.ts +126 -113
  70. package/src/input-file.ts +246 -234
  71. package/src/integrity.ts +165 -121
  72. package/src/layout.ts +63 -29
  73. package/src/locked-resolve.ts +471 -461
  74. package/src/lockfile/bun.ts +214 -207
  75. package/src/lockfile/detect.ts +80 -80
  76. package/src/lockfile/json.ts +91 -92
  77. package/src/lockfile/names.ts +9 -9
  78. package/src/lockfile/npm.ts +328 -308
  79. package/src/lockfile/parse.ts +32 -32
  80. package/src/lockfile/pnpm.ts +230 -225
  81. package/src/lockfile/tree-builder.ts +116 -116
  82. package/src/lockfile/types.ts +52 -52
  83. package/src/manifest.ts +129 -133
  84. package/src/node/archiver.ts +85 -0
  85. package/src/node/index.ts +13 -0
  86. package/src/options.ts +84 -84
  87. package/src/platform.ts +97 -101
  88. package/src/progress.ts +105 -106
  89. package/src/registry.ts +116 -115
  90. package/src/resolve.ts +560 -537
  91. package/src/schemas/lenient.ts +67 -60
  92. package/src/schemas/package-json.ts +11 -10
  93. package/src/spec.ts +123 -119
  94. package/src/types/value-of.ts +1 -1
  95. package/src/utils/is-record.ts +1 -1
@@ -1,25 +1,25 @@
1
- import type { ValueOf } from "../types/value-of.js"
1
+ import type { ValueOf } from "../types/value-of.js";
2
2
 
3
3
  /** How the resulting tarball(s) are shaped. */
4
4
  export const Layout = {
5
- /**
6
- * One tarball per requested spec, each carrying its own complete dependency
7
- * closure. Shared dependencies repeat across tarballs, so the total is
8
- * larger — but each one imports, rolls back and hands off independently.
9
- */
10
- PerSpec: "per-spec",
11
- /**
12
- * One tarball for everything, with the union of all closures deduplicated.
13
- * Smallest output and a single import step; all-or-nothing to roll back.
14
- */
15
- Single: "single",
16
- /**
17
- * No archive at all — just the npm-layout directory tree, ready for
18
- * `jf rt upload` or rsync.
19
- */
20
- Dir: "dir"
21
- } as const
5
+ /**
6
+ * One tarball per requested spec, each carrying its own complete dependency
7
+ * closure. Shared dependencies repeat across tarballs, so the total is
8
+ * larger — but each one imports, rolls back and hands off independently.
9
+ */
10
+ PerSpec: "per-spec",
11
+ /**
12
+ * One tarball for everything, with the union of all closures deduplicated.
13
+ * Smallest output and a single import step; all-or-nothing to roll back.
14
+ */
15
+ Single: "single",
16
+ /**
17
+ * No archive at all — just the npm-layout directory tree, ready for
18
+ * `jf rt upload` or rsync.
19
+ */
20
+ Dir: "dir",
21
+ } as const;
22
22
 
23
- export type Layout = ValueOf<typeof Layout>
23
+ export type Layout = ValueOf<typeof Layout>;
24
24
 
25
- export const Layouts: ReadonlyArray<Layout> = Object.values(Layout)
25
+ export const Layouts: ReadonlyArray<Layout> = Object.values(Layout);
@@ -1,10 +1,10 @@
1
- import type { ValueOf } from "../types/value-of.js"
1
+ import type { ValueOf } from "../types/value-of.js";
2
2
 
3
3
  /** Which package manager wrote a lockfile. */
4
4
  export const LockfileFormat = {
5
- Npm: "npm",
6
- Pnpm: "pnpm",
7
- Bun: "bun"
8
- } as const
5
+ Npm: "npm",
6
+ Pnpm: "pnpm",
7
+ Bun: "bun",
8
+ } as const;
9
9
 
10
- export type LockfileFormat = ValueOf<typeof LockfileFormat>
10
+ export type LockfileFormat = ValueOf<typeof LockfileFormat>;
@@ -1,12 +1,12 @@
1
- import type { ValueOf } from "../types/value-of.js"
1
+ import type { ValueOf } from "../types/value-of.js";
2
2
 
3
3
  /** The phases a bundle run moves through, in order. */
4
4
  export const Phase = {
5
- Preflight: "preflight",
6
- Resolve: "resolve",
7
- Download: "download",
8
- Archive: "archive",
9
- Done: "done"
10
- } as const
5
+ Preflight: "preflight",
6
+ Resolve: "resolve",
7
+ Download: "download",
8
+ Archive: "archive",
9
+ Done: "done",
10
+ } as const;
11
11
 
12
- export type Phase = ValueOf<typeof Phase>
12
+ export type Phase = ValueOf<typeof Phase>;
package/src/errors.ts CHANGED
@@ -13,66 +13,66 @@
13
13
 
14
14
  /** Discriminant union of every failure the bundler can produce. */
15
15
  export type BundlerError =
16
- | InvalidSpecError
17
- | InvalidInputFileError
18
- | LockfileError
19
- | LockfileIncompleteError
20
- | LockfileOutOfDateError
21
- | RegistryUnreachableError
22
- | PackageNotFoundError
23
- | VersionNotFoundError
24
- | NoMatchingVersionsError
25
- | RegistryResponseError
26
- | AuthenticationError
27
- | IntegrityError
28
- | ArchiveError
29
- | OutputError
16
+ | InvalidSpecError
17
+ | InvalidInputFileError
18
+ | LockfileError
19
+ | LockfileIncompleteError
20
+ | LockfileOutOfDateError
21
+ | RegistryUnreachableError
22
+ | PackageNotFoundError
23
+ | VersionNotFoundError
24
+ | NoMatchingVersionsError
25
+ | RegistryResponseError
26
+ | AuthenticationError
27
+ | IntegrityError
28
+ | ArchiveError
29
+ | OutputError;
30
30
 
31
31
  abstract class BundlerErrorBase extends Error {
32
- abstract readonly _tag: string
33
- constructor(message: string, options?: ErrorOptions) {
34
- super(message, options)
35
- this.name = new.target.name
36
- }
32
+ abstract readonly _tag: string;
33
+ constructor(message: string, options?: ErrorOptions) {
34
+ super(message, options);
35
+ this.name = new.target.name;
36
+ }
37
37
  }
38
38
 
39
39
  /** A package spec on the command line or in an input file could not be parsed. */
40
40
  export class InvalidSpecError extends BundlerErrorBase {
41
- readonly _tag = "InvalidSpecError" as const
42
- readonly spec: string
43
- readonly reason: string
44
- constructor(spec: string, reason: string) {
45
- super(`Invalid package spec ${JSON.stringify(spec)}: ${reason}`)
46
- this.spec = spec
47
- this.reason = reason
48
- }
41
+ readonly _tag = "InvalidSpecError" as const;
42
+ readonly spec: string;
43
+ readonly reason: string;
44
+ constructor(spec: string, reason: string) {
45
+ super(`Invalid package spec ${JSON.stringify(spec)}: ${reason}`);
46
+ this.spec = spec;
47
+ this.reason = reason;
48
+ }
49
49
  }
50
50
 
51
51
  /** `--file` pointed at something that is neither a usable package.json nor a spec list. */
52
52
  export class InvalidInputFileError extends BundlerErrorBase {
53
- readonly _tag = "InvalidInputFileError" as const
54
- readonly path: string
55
- readonly reason: string
56
- constructor(path: string, reason: string, options?: { cause?: unknown }) {
57
- super(`Cannot read specs from ${path}: ${reason}`, options)
58
- this.path = path
59
- this.reason = reason
60
- }
53
+ readonly _tag = "InvalidInputFileError" as const;
54
+ readonly path: string;
55
+ readonly reason: string;
56
+ constructor(path: string, reason: string, options?: { cause?: unknown }) {
57
+ super(`Cannot read specs from ${path}: ${reason}`, options);
58
+ this.path = path;
59
+ this.reason = reason;
60
+ }
61
61
  }
62
62
 
63
63
  /** A lockfile could not be read, or is in a format we do not support. */
64
64
  export class LockfileError extends BundlerErrorBase {
65
- readonly _tag = "LockfileError" as const
66
- readonly path: string
67
- readonly reason: string
68
- constructor(path: string, reason: string, options?: { cause?: unknown }) {
69
- // Opens with "Lockfile" so the renderer's tag prefix does not stutter, and
70
- // because not every reason is a read failure — "does not cover this
71
- // package" is about a file that read perfectly well.
72
- super(`Lockfile ${path}: ${reason}`, options)
73
- this.path = path
74
- this.reason = reason
75
- }
65
+ readonly _tag = "LockfileError" as const;
66
+ readonly path: string;
67
+ readonly reason: string;
68
+ constructor(path: string, reason: string, options?: { cause?: unknown }) {
69
+ // Opens with "Lockfile" so the renderer's tag prefix does not stutter, and
70
+ // because not every reason is a read failure — "does not cover this
71
+ // package" is about a file that read perfectly well.
72
+ super(`Lockfile ${path}: ${reason}`, options);
73
+ this.path = path;
74
+ this.reason = reason;
75
+ }
76
76
  }
77
77
 
78
78
  /**
@@ -84,25 +84,23 @@ export class LockfileError extends BundlerErrorBase {
84
84
  * gap at once so one `npm install` fixes all of them.
85
85
  */
86
86
  export class LockfileIncompleteError extends BundlerErrorBase {
87
- readonly _tag = "LockfileIncompleteError" as const
88
- readonly path: string
89
- readonly missing: ReadonlyArray<string>
90
- constructor(
91
- path: string,
92
- missing: ReadonlyArray<string>,
93
- detail: string,
94
- remedy: string
95
- ) {
96
- const shown = missing.slice(0, 10).map((entry) => ` ${entry}`).join("\n")
97
- const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : ""
98
- super(
99
- `${path} is incomplete ${detail}:\n${shown}${rest}\n` +
100
- ` ${remedy}\n` +
101
- ` Or pass --lockfile off to resolve version ranges fresh instead.`
102
- )
103
- this.path = path
104
- this.missing = missing
105
- }
87
+ readonly _tag = "LockfileIncompleteError" as const;
88
+ readonly path: string;
89
+ readonly missing: ReadonlyArray<string>;
90
+ constructor(path: string, missing: ReadonlyArray<string>, detail: string, remedy: string) {
91
+ const shown = missing
92
+ .slice(0, 10)
93
+ .map((entry) => ` ${entry}`)
94
+ .join("\n");
95
+ const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : "";
96
+ super(
97
+ `${path} is incomplete ${detail}:\n${shown}${rest}\n` +
98
+ ` ${remedy}\n` +
99
+ ` Or pass --lockfile off to resolve version ranges fresh instead.`,
100
+ );
101
+ this.path = path;
102
+ this.missing = missing;
103
+ }
106
104
  }
107
105
 
108
106
  /**
@@ -113,30 +111,34 @@ export class LockfileIncompleteError extends BundlerErrorBase {
113
111
  * version would produce exactly the mismatch this feature exists to prevent.
114
112
  */
115
113
  export class LockfileOutOfDateError extends BundlerErrorBase {
116
- readonly _tag = "LockfileOutOfDateError" as const
117
- readonly path: string
118
- readonly registry: string
119
- readonly missing: ReadonlyArray<{ readonly name: string; readonly version: string }>
120
- constructor(
121
- path: string,
122
- registry: string,
123
- missing: ReadonlyArray<{ readonly name: string; readonly version: string; readonly detail: string }>
124
- ) {
125
- const shown = missing
126
- .slice(0, 10)
127
- .map((entry) => ` ${entry.name}@${entry.version} — ${entry.detail}`)
128
- .join("\n")
129
- const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : ""
130
- super(
131
- `${path} pins ${missing.length} version${missing.length === 1 ? "" : "s"} ` +
132
- `that ${registry} does not serve:\n${shown}${rest}\n` +
133
- ` Refresh the lockfile against this registry, or pass --lockfile off to\n` +
134
- ` resolve version ranges fresh instead.`
135
- )
136
- this.path = path
137
- this.registry = registry
138
- this.missing = missing.map(({ name, version }) => ({ name, version }))
139
- }
114
+ readonly _tag = "LockfileOutOfDateError" as const;
115
+ readonly path: string;
116
+ readonly registry: string;
117
+ readonly missing: ReadonlyArray<{ readonly name: string; readonly version: string }>;
118
+ constructor(
119
+ path: string,
120
+ registry: string,
121
+ missing: ReadonlyArray<{
122
+ readonly name: string;
123
+ readonly version: string;
124
+ readonly detail: string;
125
+ }>,
126
+ ) {
127
+ const shown = missing
128
+ .slice(0, 10)
129
+ .map((entry) => ` ${entry.name}@${entry.version} ${entry.detail}`)
130
+ .join("\n");
131
+ const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : "";
132
+ super(
133
+ `${path} pins ${missing.length} version${missing.length === 1 ? "" : "s"} ` +
134
+ `that ${registry} does not serve:\n${shown}${rest}\n` +
135
+ ` Refresh the lockfile against this registry, or pass --lockfile off to\n` +
136
+ ` resolve version ranges fresh instead.`,
137
+ );
138
+ this.path = path;
139
+ this.registry = registry;
140
+ this.missing = missing.map(({ name, version }) => ({ name, version }));
141
+ }
140
142
  }
141
143
 
142
144
  /**
@@ -147,99 +149,99 @@ export class LockfileOutOfDateError extends BundlerErrorBase {
147
149
  * quickly and say which host we could not reach.
148
150
  */
149
151
  export class RegistryUnreachableError extends BundlerErrorBase {
150
- readonly _tag = "RegistryUnreachableError" as const
151
- readonly registry: string
152
- readonly timeoutMs: number | undefined
153
- constructor(
154
- registry: string,
155
- detail: string,
156
- options?: { cause?: unknown; timeoutMs?: number }
157
- ) {
158
- super(
159
- `Cannot reach registry ${registry}: ${detail}.\n` +
160
- ` Check your network connection, VPN, and the proxy settings in your .npmrc.`,
161
- options
162
- )
163
- this.registry = registry
164
- this.timeoutMs = options?.timeoutMs
165
- }
152
+ readonly _tag = "RegistryUnreachableError" as const;
153
+ readonly registry: string;
154
+ readonly timeoutMs: number | undefined;
155
+ constructor(
156
+ registry: string,
157
+ detail: string,
158
+ options?: { cause?: unknown; timeoutMs?: number },
159
+ ) {
160
+ super(
161
+ `Cannot reach registry ${registry}: ${detail}.\n` +
162
+ ` Check your network connection, VPN, and the proxy settings in your .npmrc.`,
163
+ options,
164
+ );
165
+ this.registry = registry;
166
+ this.timeoutMs = options?.timeoutMs;
167
+ }
166
168
  }
167
169
 
168
170
  /** The registry answered, but has never heard of this package. */
169
171
  export class PackageNotFoundError extends BundlerErrorBase {
170
- readonly _tag = "PackageNotFoundError" as const
171
- readonly packageName: string
172
- readonly registry: string
173
- constructor(packageName: string, registry: string) {
174
- super(`Package "${packageName}" was not found on ${registry}`)
175
- this.packageName = packageName
176
- this.registry = registry
177
- }
172
+ readonly _tag = "PackageNotFoundError" as const;
173
+ readonly packageName: string;
174
+ readonly registry: string;
175
+ constructor(packageName: string, registry: string) {
176
+ super(`Package "${packageName}" was not found on ${registry}`);
177
+ this.packageName = packageName;
178
+ this.registry = registry;
179
+ }
178
180
  }
179
181
 
180
182
  /** The package exists but the exact version requested does not. */
181
183
  export class VersionNotFoundError extends BundlerErrorBase {
182
- readonly _tag = "VersionNotFoundError" as const
183
- readonly packageName: string
184
- readonly version: string
185
- readonly available: ReadonlyArray<string>
186
- constructor(packageName: string, version: string, available: ReadonlyArray<string>) {
187
- const tail = available.slice(-5).join(", ")
188
- super(
189
- `${packageName}@${version} does not exist.` +
190
- (tail.length > 0 ? ` Most recent published versions: ${tail}` : "")
191
- )
192
- this.packageName = packageName
193
- this.version = version
194
- this.available = available
195
- }
184
+ readonly _tag = "VersionNotFoundError" as const;
185
+ readonly packageName: string;
186
+ readonly version: string;
187
+ readonly available: ReadonlyArray<string>;
188
+ constructor(packageName: string, version: string, available: ReadonlyArray<string>) {
189
+ const tail = available.slice(-5).join(", ");
190
+ super(
191
+ `${packageName}@${version} does not exist.` +
192
+ (tail.length > 0 ? ` Most recent published versions: ${tail}` : ""),
193
+ );
194
+ this.packageName = packageName;
195
+ this.version = version;
196
+ this.available = available;
197
+ }
196
198
  }
197
199
 
198
200
  /** A range (or dist-tag) matched nothing that is actually published. */
199
201
  export class NoMatchingVersionsError extends BundlerErrorBase {
200
- readonly _tag = "NoMatchingVersionsError" as const
201
- readonly packageName: string
202
- readonly selector: string
203
- readonly available: ReadonlyArray<string>
204
- constructor(packageName: string, selector: string, available: ReadonlyArray<string>) {
205
- const tail = available.slice(-5).join(", ")
206
- super(
207
- `No published version of ${packageName} satisfies "${selector}".` +
208
- (tail.length > 0 ? ` Most recent published versions: ${tail}` : "")
209
- )
210
- this.packageName = packageName
211
- this.selector = selector
212
- this.available = available
213
- }
202
+ readonly _tag = "NoMatchingVersionsError" as const;
203
+ readonly packageName: string;
204
+ readonly selector: string;
205
+ readonly available: ReadonlyArray<string>;
206
+ constructor(packageName: string, selector: string, available: ReadonlyArray<string>) {
207
+ const tail = available.slice(-5).join(", ");
208
+ super(
209
+ `No published version of ${packageName} satisfies "${selector}".` +
210
+ (tail.length > 0 ? ` Most recent published versions: ${tail}` : ""),
211
+ );
212
+ this.packageName = packageName;
213
+ this.selector = selector;
214
+ this.available = available;
215
+ }
214
216
  }
215
217
 
216
218
  /** The registry responded, but with something we cannot use. */
217
219
  export class RegistryResponseError extends BundlerErrorBase {
218
- readonly _tag = "RegistryResponseError" as const
219
- readonly url: string
220
- readonly status: number | undefined
221
- constructor(url: string, detail: string, options?: { cause?: unknown; status?: number }) {
222
- super(`Unexpected response from ${url}: ${detail}`, options)
223
- this.url = url
224
- this.status = options?.status
225
- }
220
+ readonly _tag = "RegistryResponseError" as const;
221
+ readonly url: string;
222
+ readonly status: number | undefined;
223
+ constructor(url: string, detail: string, options?: { cause?: unknown; status?: number }) {
224
+ super(`Unexpected response from ${url}: ${detail}`, options);
225
+ this.url = url;
226
+ this.status = options?.status;
227
+ }
226
228
  }
227
229
 
228
230
  /** 401/403 — almost always a missing or stale token in `.npmrc`. */
229
231
  export class AuthenticationError extends BundlerErrorBase {
230
- readonly _tag = "AuthenticationError" as const
231
- readonly registry: string
232
- readonly status: number
233
- constructor(registry: string, status: number, packageName?: string) {
234
- super(
235
- `Registry ${registry} rejected the request with HTTP ${status}` +
236
- (packageName ? ` while fetching "${packageName}"` : "") +
237
- `.\n Add credentials to your .npmrc, e.g.\n` +
238
- ` //${safeHost(registry)}/:_authToken=\${NPM_TOKEN}`
239
- )
240
- this.registry = registry
241
- this.status = status
242
- }
232
+ readonly _tag = "AuthenticationError" as const;
233
+ readonly registry: string;
234
+ readonly status: number;
235
+ constructor(registry: string, status: number, packageName?: string) {
236
+ super(
237
+ `Registry ${registry} rejected the request with HTTP ${status}` +
238
+ (packageName ? ` while fetching "${packageName}"` : "") +
239
+ `.\n Add credentials to your .npmrc, e.g.\n` +
240
+ ` //${safeHost(registry)}/:_authToken=\${NPM_TOKEN}`,
241
+ );
242
+ this.registry = registry;
243
+ this.status = status;
244
+ }
243
245
  }
244
246
 
245
247
  /**
@@ -249,50 +251,50 @@ export class AuthenticationError extends BundlerErrorBase {
249
251
  * substituted tarball is exactly what integrity checking exists to catch.
250
252
  */
251
253
  export class IntegrityError extends BundlerErrorBase {
252
- readonly _tag = "IntegrityError" as const
253
- readonly packageName: string
254
- readonly version: string
255
- readonly expected: string
256
- readonly actual: string
257
- constructor(packageName: string, version: string, expected: string, actual: string) {
258
- super(
259
- `Integrity check failed for ${packageName}@${version}.\n` +
260
- ` expected: ${expected}\n` +
261
- ` actual: ${actual}\n` +
262
- ` The download was discarded. This is either corruption in transit or a tampered artifact.`
263
- )
264
- this.packageName = packageName
265
- this.version = version
266
- this.expected = expected
267
- this.actual = actual
268
- }
254
+ readonly _tag = "IntegrityError" as const;
255
+ readonly packageName: string;
256
+ readonly version: string;
257
+ readonly expected: string;
258
+ readonly actual: string;
259
+ constructor(packageName: string, version: string, expected: string, actual: string) {
260
+ super(
261
+ `Integrity check failed for ${packageName}@${version}.\n` +
262
+ ` expected: ${expected}\n` +
263
+ ` actual: ${actual}\n` +
264
+ ` The download was discarded. This is either corruption in transit or a tampered artifact.`,
265
+ );
266
+ this.packageName = packageName;
267
+ this.version = version;
268
+ this.expected = expected;
269
+ this.actual = actual;
270
+ }
269
271
  }
270
272
 
271
273
  /** Something went wrong writing the `.tgz`. */
272
274
  export class ArchiveError extends BundlerErrorBase {
273
- readonly _tag = "ArchiveError" as const
274
- readonly path: string
275
- constructor(path: string, detail: string, options?: { cause?: unknown }) {
276
- super(`Failed to create archive ${path}: ${detail}`, options)
277
- this.path = path
278
- }
275
+ readonly _tag = "ArchiveError" as const;
276
+ readonly path: string;
277
+ constructor(path: string, detail: string, options?: { cause?: unknown }) {
278
+ super(`Failed to create archive ${path}: ${detail}`, options);
279
+ this.path = path;
280
+ }
279
281
  }
280
282
 
281
283
  /** Something went wrong preparing or writing to the output directory. */
282
284
  export class OutputError extends BundlerErrorBase {
283
- readonly _tag = "OutputError" as const
284
- readonly path: string
285
- constructor(path: string, detail: string, options?: { cause?: unknown }) {
286
- super(`Output error at ${path}: ${detail}`, options)
287
- this.path = path
288
- }
285
+ readonly _tag = "OutputError" as const;
286
+ readonly path: string;
287
+ constructor(path: string, detail: string, options?: { cause?: unknown }) {
288
+ super(`Output error at ${path}: ${detail}`, options);
289
+ this.path = path;
290
+ }
289
291
  }
290
292
 
291
293
  const safeHost = (registry: string): string => {
292
- try {
293
- const url = new URL(registry)
294
- return url.host + url.pathname.replace(/\/+$/, "")
295
- } catch {
296
- return registry
297
- }
298
- }
294
+ try {
295
+ const url = new URL(registry);
296
+ return url.host + url.pathname.replace(/\/+$/, "");
297
+ } catch {
298
+ return registry;
299
+ }
300
+ };