@packall/core 0.0.1 → 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 (157) 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 +64 -0
  6. package/dist/archive.d.ts.map +1 -0
  7. package/dist/{Bundle.d.ts → bundle.d.ts} +56 -38
  8. package/dist/bundle.d.ts.map +1 -0
  9. package/dist/{DependencyRange.d.ts → dependency-range.d.ts} +2 -2
  10. package/dist/dependency-range.d.ts.map +1 -0
  11. package/dist/{Download.d.ts → download.d.ts} +9 -8
  12. package/dist/download.d.ts.map +1 -0
  13. package/dist/enums/artifact-kind.d.ts +8 -0
  14. package/dist/enums/artifact-kind.d.ts.map +1 -0
  15. package/dist/enums/edge-kind.d.ts +29 -0
  16. package/dist/enums/edge-kind.d.ts.map +1 -0
  17. package/dist/enums/input-file-kind.d.ts +12 -0
  18. package/dist/enums/input-file-kind.d.ts.map +1 -0
  19. package/dist/enums/layout.d.ts +23 -0
  20. package/dist/enums/layout.d.ts.map +1 -0
  21. package/dist/enums/lockfile-format.d.ts +9 -0
  22. package/dist/enums/lockfile-format.d.ts.map +1 -0
  23. package/dist/enums/phase.d.ts +11 -0
  24. package/dist/enums/phase.d.ts.map +1 -0
  25. package/dist/{Errors.d.ts → errors.d.ts} +49 -7
  26. package/dist/errors.d.ts.map +1 -0
  27. package/dist/index.d.ts +46 -28
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +2121 -1060
  30. package/dist/index.js.map +1 -1
  31. package/dist/input-file.d.ts +77 -0
  32. package/dist/input-file.d.ts.map +1 -0
  33. package/dist/integrity.d.ts +80 -0
  34. package/dist/integrity.d.ts.map +1 -0
  35. package/dist/layout.d.ts +87 -0
  36. package/dist/layout.d.ts.map +1 -0
  37. package/dist/locked-resolve.d.ts +47 -0
  38. package/dist/locked-resolve.d.ts.map +1 -0
  39. package/dist/lockfile/bun.d.ts +3 -0
  40. package/dist/lockfile/bun.d.ts.map +1 -0
  41. package/dist/lockfile/detect.d.ts +31 -0
  42. package/dist/lockfile/detect.d.ts.map +1 -0
  43. package/dist/lockfile/json.d.ts +23 -0
  44. package/dist/lockfile/json.d.ts.map +1 -0
  45. package/dist/lockfile/names.d.ts +16 -0
  46. package/dist/lockfile/names.d.ts.map +1 -0
  47. package/dist/lockfile/npm.d.ts +3 -0
  48. package/dist/lockfile/npm.d.ts.map +1 -0
  49. package/dist/lockfile/parse.d.ts +23 -0
  50. package/dist/lockfile/parse.d.ts.map +1 -0
  51. package/dist/lockfile/pnpm.d.ts +20 -0
  52. package/dist/lockfile/pnpm.d.ts.map +1 -0
  53. package/dist/lockfile/tree-builder.d.ts +70 -0
  54. package/dist/lockfile/tree-builder.d.ts.map +1 -0
  55. package/dist/lockfile/types.d.ts +70 -0
  56. package/dist/lockfile/types.d.ts.map +1 -0
  57. package/dist/{Manifest.d.ts → manifest.d.ts} +7 -15
  58. package/dist/manifest.d.ts.map +1 -0
  59. package/dist/node/archiver.d.ts +5 -0
  60. package/dist/node/archiver.d.ts.map +1 -0
  61. package/dist/node/index.d.ts +13 -0
  62. package/dist/node/index.d.ts.map +1 -0
  63. package/dist/node/index.js +55 -0
  64. package/dist/node/index.js.map +1 -0
  65. package/dist/{Options.d.ts → options.d.ts} +12 -30
  66. package/dist/options.d.ts.map +1 -0
  67. package/dist/{Platform.d.ts → platform.d.ts} +14 -19
  68. package/dist/platform.d.ts.map +1 -0
  69. package/dist/{Progress.d.ts → progress.d.ts} +10 -9
  70. package/dist/progress.d.ts.map +1 -0
  71. package/dist/{Registry.d.ts → registry.d.ts} +42 -44
  72. package/dist/registry.d.ts.map +1 -0
  73. package/dist/{Resolve.d.ts → resolve.d.ts} +25 -26
  74. package/dist/resolve.d.ts.map +1 -0
  75. package/dist/schemas/lenient.d.ts +38 -0
  76. package/dist/schemas/lenient.d.ts.map +1 -0
  77. package/dist/schemas/package-json.d.ts +44 -0
  78. package/dist/schemas/package-json.d.ts.map +1 -0
  79. package/dist/{Spec.d.ts → spec.d.ts} +4 -4
  80. package/dist/spec.d.ts.map +1 -0
  81. package/dist/types/value-of.d.ts +9 -0
  82. package/dist/types/value-of.d.ts.map +1 -0
  83. package/dist/utils/is-record.d.ts +8 -0
  84. package/dist/utils/is-record.d.ts.map +1 -0
  85. package/package.json +13 -11
  86. package/src/archive.ts +95 -0
  87. package/src/bundle.ts +736 -0
  88. package/src/dependency-range.ts +121 -0
  89. package/src/download.ts +155 -0
  90. package/src/enums/artifact-kind.ts +9 -0
  91. package/src/enums/edge-kind.ts +32 -0
  92. package/src/enums/input-file-kind.ts +13 -0
  93. package/src/enums/layout.ts +25 -0
  94. package/src/enums/lockfile-format.ts +10 -0
  95. package/src/enums/phase.ts +12 -0
  96. package/src/errors.ts +300 -0
  97. package/src/index.ts +146 -35
  98. package/src/input-file.ts +324 -0
  99. package/src/integrity.ts +165 -0
  100. package/src/layout.ts +137 -0
  101. package/src/locked-resolve.ts +471 -0
  102. package/src/lockfile/bun.ts +214 -0
  103. package/src/lockfile/detect.ts +80 -0
  104. package/src/lockfile/json.ts +131 -0
  105. package/src/lockfile/names.ts +20 -0
  106. package/src/lockfile/npm.ts +328 -0
  107. package/src/lockfile/parse.ts +56 -0
  108. package/src/lockfile/pnpm.ts +230 -0
  109. package/src/lockfile/tree-builder.ts +166 -0
  110. package/src/lockfile/types.ts +74 -0
  111. package/src/manifest.ts +129 -0
  112. package/src/node/archiver.ts +85 -0
  113. package/src/node/index.ts +13 -0
  114. package/src/options.ts +103 -0
  115. package/src/platform.ts +178 -0
  116. package/src/progress.ts +105 -0
  117. package/src/registry.ts +116 -0
  118. package/src/resolve.ts +560 -0
  119. package/src/schemas/lenient.ts +130 -0
  120. package/src/schemas/package-json.ts +28 -0
  121. package/src/spec.ts +182 -0
  122. package/src/types/value-of.ts +8 -0
  123. package/src/utils/is-record.ts +8 -0
  124. package/dist/Archive.d.ts +0 -32
  125. package/dist/Archive.d.ts.map +0 -1
  126. package/dist/Bundle.d.ts.map +0 -1
  127. package/dist/DependencyRange.d.ts.map +0 -1
  128. package/dist/Download.d.ts.map +0 -1
  129. package/dist/Errors.d.ts.map +0 -1
  130. package/dist/InputFile.d.ts +0 -46
  131. package/dist/InputFile.d.ts.map +0 -1
  132. package/dist/Integrity.d.ts +0 -48
  133. package/dist/Integrity.d.ts.map +0 -1
  134. package/dist/Layout.d.ts +0 -53
  135. package/dist/Layout.d.ts.map +0 -1
  136. package/dist/Manifest.d.ts.map +0 -1
  137. package/dist/Options.d.ts.map +0 -1
  138. package/dist/Platform.d.ts.map +0 -1
  139. package/dist/Progress.d.ts.map +0 -1
  140. package/dist/Registry.d.ts.map +0 -1
  141. package/dist/Resolve.d.ts.map +0 -1
  142. package/dist/Spec.d.ts.map +0 -1
  143. package/src/Archive.ts +0 -92
  144. package/src/Bundle.ts +0 -570
  145. package/src/DependencyRange.ts +0 -115
  146. package/src/Download.ts +0 -132
  147. package/src/Errors.ts +0 -216
  148. package/src/InputFile.ts +0 -229
  149. package/src/Integrity.ts +0 -122
  150. package/src/Layout.ts +0 -103
  151. package/src/Manifest.ts +0 -133
  152. package/src/Options.ts +0 -123
  153. package/src/Platform.ts +0 -182
  154. package/src/Progress.ts +0 -106
  155. package/src/Registry.ts +0 -121
  156. package/src/Resolve.ts +0 -528
  157. package/src/Spec.ts +0 -186
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 YL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @packall/core
2
+
3
+ The registry-agnostic engine behind packall. It resolves package specs, walks their
4
+ dependency closures, verifies downloads, and writes registry-shaped bundle artifacts.
5
+ The engine does not know how a registry speaks HTTP: that boundary is the `Registry`
6
+ service.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install @packall/core effect
12
+ ```
13
+
14
+ `effect` is a peer dependency. The default entry point is browser-safe. Node-specific
15
+ archive support is available explicitly from `@packall/core/node`.
16
+
17
+ ## Registry service
18
+
19
+ Implement or provide `Registry` when embedding the engine. A registry backend supplies
20
+ three operations:
21
+
22
+ - `preflight` checks that the registry is reachable.
23
+ - `packument(name)` reads package metadata and published versions.
24
+ - `download(manifest)` returns the tarball bytes for a resolved package.
25
+
26
+ The engine then handles resolution, lockfile pinning, platform filtering, integrity
27
+ verification, progress reporting, manifests, layouts, and archive planning.
28
+
29
+ ## Bundle from code
30
+
31
+ ```ts
32
+ import * as Effect from "effect/Effect";
33
+ import { bundle, defaultBundleOptions, parseSpec, Registry } from "@packall/core";
34
+
35
+ const program = Effect.gen(function* () {
36
+ // The surrounding Effect runtime provides Registry, Progress, filesystem,
37
+ // crypto, and the Node archive layer.
38
+ yield* Registry;
39
+ return yield* bundle([parseSpec("react@18.2.0")], {
40
+ ...defaultBundleOptions,
41
+ outDir: "./bundles",
42
+ toolVersion: "example",
43
+ });
44
+ });
45
+ ```
46
+
47
+ In practice, compose the program with an Effect layer that provides `Registry`,
48
+ `Progress`, and the archive backend. The public API also exposes `plan`, `resolve`,
49
+ `resolveLocked`, `bundleLocked`, input-file parsing, lockfile parsing, and manifest
50
+ helpers for applications that need more control than `bundle` provides.
51
+
52
+ See the [packall documentation](https://packall.localhost/docs) and the
53
+ [`@packall/core` API reference](https://packall.localhost/docs/api/core) for the full
54
+ typed surface.
55
+
56
+ ## License
57
+
58
+ MIT
@@ -0,0 +1,274 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Context from "effect/Context";
3
+ import * as Layer from "effect/Layer";
4
+ import * as Ref from "effect/Ref";
5
+
6
+ //#region src/errors.ts
7
+ var BundlerErrorBase = class extends Error {
8
+ constructor(message, options) {
9
+ super(message, options);
10
+ this.name = new.target.name;
11
+ }
12
+ };
13
+ /** A package spec on the command line or in an input file could not be parsed. */
14
+ var InvalidSpecError = class extends BundlerErrorBase {
15
+ _tag = "InvalidSpecError";
16
+ spec;
17
+ reason;
18
+ constructor(spec, reason) {
19
+ super(`Invalid package spec ${JSON.stringify(spec)}: ${reason}`);
20
+ this.spec = spec;
21
+ this.reason = reason;
22
+ }
23
+ };
24
+ /** `--file` pointed at something that is neither a usable package.json nor a spec list. */
25
+ var InvalidInputFileError = class extends BundlerErrorBase {
26
+ _tag = "InvalidInputFileError";
27
+ path;
28
+ reason;
29
+ constructor(path, reason, options) {
30
+ super(`Cannot read specs from ${path}: ${reason}`, options);
31
+ this.path = path;
32
+ this.reason = reason;
33
+ }
34
+ };
35
+ /** A lockfile could not be read, or is in a format we do not support. */
36
+ var LockfileError = class extends BundlerErrorBase {
37
+ _tag = "LockfileError";
38
+ path;
39
+ reason;
40
+ constructor(path, reason, options) {
41
+ super(`Lockfile ${path}: ${reason}`, options);
42
+ this.path = path;
43
+ this.reason = reason;
44
+ }
45
+ };
46
+ /**
47
+ * The lockfile parsed, but does not pin everything the bundle needs.
48
+ *
49
+ * Falling back to a range here would defeat the entire point of reading a
50
+ * lockfile — you would get a bundle that is *mostly* what CI installed, with no
51
+ * indication of which parts were guessed. So this is fatal, and it names every
52
+ * gap at once so one `npm install` fixes all of them.
53
+ */
54
+ var LockfileIncompleteError = class extends BundlerErrorBase {
55
+ _tag = "LockfileIncompleteError";
56
+ path;
57
+ missing;
58
+ constructor(path, missing, detail, remedy) {
59
+ const shown = missing.slice(0, 10).map((entry) => ` ${entry}`).join("\n");
60
+ const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : "";
61
+ super(`${path} is incomplete — ${detail}:\n${shown}${rest}\n ${remedy}\n Or pass --lockfile off to resolve version ranges fresh instead.`);
62
+ this.path = path;
63
+ this.missing = missing;
64
+ }
65
+ };
66
+ /**
67
+ * The lockfile pins versions the registry no longer serves.
68
+ *
69
+ * Unpublished, or never mirrored into a private registry. Either way the
70
+ * bundle cannot be built as specified, and quietly substituting a nearby
71
+ * version would produce exactly the mismatch this feature exists to prevent.
72
+ */
73
+ var LockfileOutOfDateError = class extends BundlerErrorBase {
74
+ _tag = "LockfileOutOfDateError";
75
+ path;
76
+ registry;
77
+ missing;
78
+ constructor(path, registry, missing) {
79
+ const shown = missing.slice(0, 10).map((entry) => ` ${entry.name}@${entry.version} — ${entry.detail}`).join("\n");
80
+ const rest = missing.length > 10 ? `\n … and ${missing.length - 10} more` : "";
81
+ super(`${path} pins ${missing.length} version${missing.length === 1 ? "" : "s"} that ${registry} does not serve:\n${shown}${rest}\n Refresh the lockfile against this registry, or pass --lockfile off to\n resolve version ranges fresh instead.`);
82
+ this.path = path;
83
+ this.registry = registry;
84
+ this.missing = missing.map(({ name, version }) => ({
85
+ name,
86
+ version
87
+ }));
88
+ }
89
+ };
90
+ /**
91
+ * The registry could not be reached at all — DNS failure, refused connection,
92
+ * proxy blackhole, or a preflight that timed out.
93
+ *
94
+ * This is the error that fixes "hangs forever with no network": we surface it
95
+ * quickly and say which host we could not reach.
96
+ */
97
+ var RegistryUnreachableError = class extends BundlerErrorBase {
98
+ _tag = "RegistryUnreachableError";
99
+ registry;
100
+ timeoutMs;
101
+ constructor(registry, detail, options) {
102
+ super(`Cannot reach registry ${registry}: ${detail}.\n Check your network connection, VPN, and the proxy settings in your .npmrc.`, options);
103
+ this.registry = registry;
104
+ this.timeoutMs = options?.timeoutMs;
105
+ }
106
+ };
107
+ /** The registry answered, but has never heard of this package. */
108
+ var PackageNotFoundError = class extends BundlerErrorBase {
109
+ _tag = "PackageNotFoundError";
110
+ packageName;
111
+ registry;
112
+ constructor(packageName, registry) {
113
+ super(`Package "${packageName}" was not found on ${registry}`);
114
+ this.packageName = packageName;
115
+ this.registry = registry;
116
+ }
117
+ };
118
+ /** The package exists but the exact version requested does not. */
119
+ var VersionNotFoundError = class extends BundlerErrorBase {
120
+ _tag = "VersionNotFoundError";
121
+ packageName;
122
+ version;
123
+ available;
124
+ constructor(packageName, version, available) {
125
+ const tail = available.slice(-5).join(", ");
126
+ super(`${packageName}@${version} does not exist.` + (tail.length > 0 ? ` Most recent published versions: ${tail}` : ""));
127
+ this.packageName = packageName;
128
+ this.version = version;
129
+ this.available = available;
130
+ }
131
+ };
132
+ /** A range (or dist-tag) matched nothing that is actually published. */
133
+ var NoMatchingVersionsError = class extends BundlerErrorBase {
134
+ _tag = "NoMatchingVersionsError";
135
+ packageName;
136
+ selector;
137
+ available;
138
+ constructor(packageName, selector, available) {
139
+ const tail = available.slice(-5).join(", ");
140
+ super(`No published version of ${packageName} satisfies "${selector}".` + (tail.length > 0 ? ` Most recent published versions: ${tail}` : ""));
141
+ this.packageName = packageName;
142
+ this.selector = selector;
143
+ this.available = available;
144
+ }
145
+ };
146
+ /** The registry responded, but with something we cannot use. */
147
+ var RegistryResponseError = class extends BundlerErrorBase {
148
+ _tag = "RegistryResponseError";
149
+ url;
150
+ status;
151
+ constructor(url, detail, options) {
152
+ super(`Unexpected response from ${url}: ${detail}`, options);
153
+ this.url = url;
154
+ this.status = options?.status;
155
+ }
156
+ };
157
+ /** 401/403 — almost always a missing or stale token in `.npmrc`. */
158
+ var AuthenticationError = class extends BundlerErrorBase {
159
+ _tag = "AuthenticationError";
160
+ registry;
161
+ status;
162
+ constructor(registry, status, packageName) {
163
+ super(`Registry ${registry} rejected the request with HTTP ${status}` + (packageName ? ` while fetching "${packageName}"` : "") + `.\n Add credentials to your .npmrc, e.g.\n //${safeHost(registry)}/:_authToken=\${NPM_TOKEN}`);
164
+ this.registry = registry;
165
+ this.status = status;
166
+ }
167
+ };
168
+ /**
169
+ * A downloaded tarball did not match the checksum the registry advertised.
170
+ *
171
+ * Never soft-fail this: a bundle is a supply-chain artifact and a corrupt or
172
+ * substituted tarball is exactly what integrity checking exists to catch.
173
+ */
174
+ var IntegrityError = class extends BundlerErrorBase {
175
+ _tag = "IntegrityError";
176
+ packageName;
177
+ version;
178
+ expected;
179
+ actual;
180
+ constructor(packageName, version, expected, actual) {
181
+ super(`Integrity check failed for ${packageName}@${version}.\n expected: ${expected}\n actual: ${actual}\n The download was discarded. This is either corruption in transit or a tampered artifact.`);
182
+ this.packageName = packageName;
183
+ this.version = version;
184
+ this.expected = expected;
185
+ this.actual = actual;
186
+ }
187
+ };
188
+ /** Something went wrong writing the `.tgz`. */
189
+ var ArchiveError = class extends BundlerErrorBase {
190
+ _tag = "ArchiveError";
191
+ path;
192
+ constructor(path, detail, options) {
193
+ super(`Failed to create archive ${path}: ${detail}`, options);
194
+ this.path = path;
195
+ }
196
+ };
197
+ /** Something went wrong preparing or writing to the output directory. */
198
+ var OutputError = class extends BundlerErrorBase {
199
+ _tag = "OutputError";
200
+ path;
201
+ constructor(path, detail, options) {
202
+ super(`Output error at ${path}: ${detail}`, options);
203
+ this.path = path;
204
+ }
205
+ };
206
+ const safeHost = (registry) => {
207
+ try {
208
+ const url = new URL(registry);
209
+ return url.host + url.pathname.replace(/\/+$/, "");
210
+ } catch {
211
+ return registry;
212
+ }
213
+ };
214
+
215
+ //#endregion
216
+ //#region src/progress.ts
217
+ /** Service tag for progress reporting. */
218
+ var Progress = class extends Context.Service()("@packall/core/Progress") {};
219
+ /** Emits an event to whichever reporter is installed. */
220
+ const emit = (event) => Effect.gen(function* () {
221
+ yield* (yield* Progress).emit(event);
222
+ });
223
+ /**
224
+ * Discards every event.
225
+ *
226
+ * The default for library consumers and for tests that do not care about
227
+ * progress — silence should never require ceremony.
228
+ */
229
+ const layerSilent = Layer.succeed(Progress)({ emit: () => Effect.void });
230
+ /** Sends every event to a callback. Used by the CLI renderer. */
231
+ const layerCallback = (onEvent) => Layer.succeed(Progress)({ emit: (event) => Effect.sync(() => onEvent(event)) });
232
+ /**
233
+ * Accumulates every event into a `Ref`, for assertions.
234
+ *
235
+ * Returned as `{ layer, events }` so a test can provide the layer and then read
236
+ * the transcript afterwards.
237
+ */
238
+ const makeCollector = Effect.gen(function* () {
239
+ const ref = yield* Ref.make([]);
240
+ return {
241
+ layer: Layer.succeed(Progress)({ emit: (event) => Ref.update(ref, (events) => [...events, event]) }),
242
+ events: Ref.get(ref)
243
+ };
244
+ });
245
+
246
+ //#endregion
247
+ //#region src/archive.ts
248
+ /** Service tag for archive creation. */
249
+ var Archiver = class extends Context.Service()("@packall/core/Archiver") {};
250
+ /**
251
+ * Packs an archive with whichever backend is installed.
252
+ *
253
+ * The progress events are emitted here rather than inside the backends, so
254
+ * every implementation reports identically and a new one cannot forget to.
255
+ */
256
+ const createArchive = (options) => Effect.gen(function* () {
257
+ const archiver = yield* Archiver;
258
+ yield* emit({
259
+ _tag: "ArchiveStarted",
260
+ path: options.outPath,
261
+ entryCount: options.entries.length
262
+ });
263
+ const result = yield* archiver.create(options);
264
+ yield* emit({
265
+ _tag: "ArchiveCompleted",
266
+ path: result.path,
267
+ bytes: result.bytes
268
+ });
269
+ return result;
270
+ });
271
+
272
+ //#endregion
273
+ export { OutputError as _, layerCallback as a, RegistryUnreachableError as b, ArchiveError as c, InvalidInputFileError as d, InvalidSpecError as f, NoMatchingVersionsError as g, LockfileOutOfDateError as h, emit as i, AuthenticationError as l, LockfileIncompleteError as m, createArchive as n, layerSilent as o, LockfileError as p, Progress as r, makeCollector as s, Archiver as t, IntegrityError as u, PackageNotFoundError as v, VersionNotFoundError as x, RegistryResponseError as y };
274
+ //# sourceMappingURL=archive-6sqTn1C4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-6sqTn1C4.js","names":["layerSilent: Layer.Layer<Progress>","Progress.emit"],"sources":["../src/errors.ts","../src/progress.ts","../src/archive.ts"],"sourcesContent":["/**\n * Failure types for the bundler.\n *\n * These are deliberately plain classes carrying a literal `_tag` rather than\n * `Data.TaggedError`. They work with `Effect.catchTag` / `Effect.catchTags`\n * exactly the same way, and they keep the public error surface independent of\n * any single Effect release — useful while Effect v4 is still in beta.\n *\n * Every error carries enough context to be actionable without a stack trace,\n * because the primary consumer is somebody staring at a terminal on a\n * locked-down network trying to work out why a download did not happen.\n */\n\n/** Discriminant union of every failure the bundler can produce. */\nexport type BundlerError =\n\t| InvalidSpecError\n\t| InvalidInputFileError\n\t| LockfileError\n\t| LockfileIncompleteError\n\t| LockfileOutOfDateError\n\t| RegistryUnreachableError\n\t| PackageNotFoundError\n\t| VersionNotFoundError\n\t| NoMatchingVersionsError\n\t| RegistryResponseError\n\t| AuthenticationError\n\t| IntegrityError\n\t| ArchiveError\n\t| OutputError;\n\nabstract class BundlerErrorBase extends Error {\n\tabstract readonly _tag: string;\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** A package spec on the command line or in an input file could not be parsed. */\nexport class InvalidSpecError extends BundlerErrorBase {\n\treadonly _tag = \"InvalidSpecError\" as const;\n\treadonly spec: string;\n\treadonly reason: string;\n\tconstructor(spec: string, reason: string) {\n\t\tsuper(`Invalid package spec ${JSON.stringify(spec)}: ${reason}`);\n\t\tthis.spec = spec;\n\t\tthis.reason = reason;\n\t}\n}\n\n/** `--file` pointed at something that is neither a usable package.json nor a spec list. */\nexport class InvalidInputFileError extends BundlerErrorBase {\n\treadonly _tag = \"InvalidInputFileError\" as const;\n\treadonly path: string;\n\treadonly reason: string;\n\tconstructor(path: string, reason: string, options?: { cause?: unknown }) {\n\t\tsuper(`Cannot read specs from ${path}: ${reason}`, options);\n\t\tthis.path = path;\n\t\tthis.reason = reason;\n\t}\n}\n\n/** A lockfile could not be read, or is in a format we do not support. */\nexport class LockfileError extends BundlerErrorBase {\n\treadonly _tag = \"LockfileError\" as const;\n\treadonly path: string;\n\treadonly reason: string;\n\tconstructor(path: string, reason: string, options?: { cause?: unknown }) {\n\t\t// Opens with \"Lockfile\" so the renderer's tag prefix does not stutter, and\n\t\t// because not every reason is a read failure — \"does not cover this\n\t\t// package\" is about a file that read perfectly well.\n\t\tsuper(`Lockfile ${path}: ${reason}`, options);\n\t\tthis.path = path;\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * The lockfile parsed, but does not pin everything the bundle needs.\n *\n * Falling back to a range here would defeat the entire point of reading a\n * lockfile — you would get a bundle that is *mostly* what CI installed, with no\n * indication of which parts were guessed. So this is fatal, and it names every\n * gap at once so one `npm install` fixes all of them.\n */\nexport class LockfileIncompleteError extends BundlerErrorBase {\n\treadonly _tag = \"LockfileIncompleteError\" as const;\n\treadonly path: string;\n\treadonly missing: ReadonlyArray<string>;\n\tconstructor(path: string, missing: ReadonlyArray<string>, detail: string, remedy: string) {\n\t\tconst shown = missing\n\t\t\t.slice(0, 10)\n\t\t\t.map((entry) => ` ${entry}`)\n\t\t\t.join(\"\\n\");\n\t\tconst rest = missing.length > 10 ? `\\n … and ${missing.length - 10} more` : \"\";\n\t\tsuper(\n\t\t\t`${path} is incomplete — ${detail}:\\n${shown}${rest}\\n` +\n\t\t\t\t` ${remedy}\\n` +\n\t\t\t\t` Or pass --lockfile off to resolve version ranges fresh instead.`,\n\t\t);\n\t\tthis.path = path;\n\t\tthis.missing = missing;\n\t}\n}\n\n/**\n * The lockfile pins versions the registry no longer serves.\n *\n * Unpublished, or never mirrored into a private registry. Either way the\n * bundle cannot be built as specified, and quietly substituting a nearby\n * version would produce exactly the mismatch this feature exists to prevent.\n */\nexport class LockfileOutOfDateError extends BundlerErrorBase {\n\treadonly _tag = \"LockfileOutOfDateError\" as const;\n\treadonly path: string;\n\treadonly registry: string;\n\treadonly missing: ReadonlyArray<{ readonly name: string; readonly version: string }>;\n\tconstructor(\n\t\tpath: string,\n\t\tregistry: string,\n\t\tmissing: ReadonlyArray<{\n\t\t\treadonly name: string;\n\t\t\treadonly version: string;\n\t\t\treadonly detail: string;\n\t\t}>,\n\t) {\n\t\tconst shown = missing\n\t\t\t.slice(0, 10)\n\t\t\t.map((entry) => ` ${entry.name}@${entry.version} — ${entry.detail}`)\n\t\t\t.join(\"\\n\");\n\t\tconst rest = missing.length > 10 ? `\\n … and ${missing.length - 10} more` : \"\";\n\t\tsuper(\n\t\t\t`${path} pins ${missing.length} version${missing.length === 1 ? \"\" : \"s\"} ` +\n\t\t\t\t`that ${registry} does not serve:\\n${shown}${rest}\\n` +\n\t\t\t\t` Refresh the lockfile against this registry, or pass --lockfile off to\\n` +\n\t\t\t\t` resolve version ranges fresh instead.`,\n\t\t);\n\t\tthis.path = path;\n\t\tthis.registry = registry;\n\t\tthis.missing = missing.map(({ name, version }) => ({ name, version }));\n\t}\n}\n\n/**\n * The registry could not be reached at all — DNS failure, refused connection,\n * proxy blackhole, or a preflight that timed out.\n *\n * This is the error that fixes \"hangs forever with no network\": we surface it\n * quickly and say which host we could not reach.\n */\nexport class RegistryUnreachableError extends BundlerErrorBase {\n\treadonly _tag = \"RegistryUnreachableError\" as const;\n\treadonly registry: string;\n\treadonly timeoutMs: number | undefined;\n\tconstructor(\n\t\tregistry: string,\n\t\tdetail: string,\n\t\toptions?: { cause?: unknown; timeoutMs?: number },\n\t) {\n\t\tsuper(\n\t\t\t`Cannot reach registry ${registry}: ${detail}.\\n` +\n\t\t\t\t` Check your network connection, VPN, and the proxy settings in your .npmrc.`,\n\t\t\toptions,\n\t\t);\n\t\tthis.registry = registry;\n\t\tthis.timeoutMs = options?.timeoutMs;\n\t}\n}\n\n/** The registry answered, but has never heard of this package. */\nexport class PackageNotFoundError extends BundlerErrorBase {\n\treadonly _tag = \"PackageNotFoundError\" as const;\n\treadonly packageName: string;\n\treadonly registry: string;\n\tconstructor(packageName: string, registry: string) {\n\t\tsuper(`Package \"${packageName}\" was not found on ${registry}`);\n\t\tthis.packageName = packageName;\n\t\tthis.registry = registry;\n\t}\n}\n\n/** The package exists but the exact version requested does not. */\nexport class VersionNotFoundError extends BundlerErrorBase {\n\treadonly _tag = \"VersionNotFoundError\" as const;\n\treadonly packageName: string;\n\treadonly version: string;\n\treadonly available: ReadonlyArray<string>;\n\tconstructor(packageName: string, version: string, available: ReadonlyArray<string>) {\n\t\tconst tail = available.slice(-5).join(\", \");\n\t\tsuper(\n\t\t\t`${packageName}@${version} does not exist.` +\n\t\t\t\t(tail.length > 0 ? ` Most recent published versions: ${tail}` : \"\"),\n\t\t);\n\t\tthis.packageName = packageName;\n\t\tthis.version = version;\n\t\tthis.available = available;\n\t}\n}\n\n/** A range (or dist-tag) matched nothing that is actually published. */\nexport class NoMatchingVersionsError extends BundlerErrorBase {\n\treadonly _tag = \"NoMatchingVersionsError\" as const;\n\treadonly packageName: string;\n\treadonly selector: string;\n\treadonly available: ReadonlyArray<string>;\n\tconstructor(packageName: string, selector: string, available: ReadonlyArray<string>) {\n\t\tconst tail = available.slice(-5).join(\", \");\n\t\tsuper(\n\t\t\t`No published version of ${packageName} satisfies \"${selector}\".` +\n\t\t\t\t(tail.length > 0 ? ` Most recent published versions: ${tail}` : \"\"),\n\t\t);\n\t\tthis.packageName = packageName;\n\t\tthis.selector = selector;\n\t\tthis.available = available;\n\t}\n}\n\n/** The registry responded, but with something we cannot use. */\nexport class RegistryResponseError extends BundlerErrorBase {\n\treadonly _tag = \"RegistryResponseError\" as const;\n\treadonly url: string;\n\treadonly status: number | undefined;\n\tconstructor(url: string, detail: string, options?: { cause?: unknown; status?: number }) {\n\t\tsuper(`Unexpected response from ${url}: ${detail}`, options);\n\t\tthis.url = url;\n\t\tthis.status = options?.status;\n\t}\n}\n\n/** 401/403 — almost always a missing or stale token in `.npmrc`. */\nexport class AuthenticationError extends BundlerErrorBase {\n\treadonly _tag = \"AuthenticationError\" as const;\n\treadonly registry: string;\n\treadonly status: number;\n\tconstructor(registry: string, status: number, packageName?: string) {\n\t\tsuper(\n\t\t\t`Registry ${registry} rejected the request with HTTP ${status}` +\n\t\t\t\t(packageName ? ` while fetching \"${packageName}\"` : \"\") +\n\t\t\t\t`.\\n Add credentials to your .npmrc, e.g.\\n` +\n\t\t\t\t` //${safeHost(registry)}/:_authToken=\\${NPM_TOKEN}`,\n\t\t);\n\t\tthis.registry = registry;\n\t\tthis.status = status;\n\t}\n}\n\n/**\n * A downloaded tarball did not match the checksum the registry advertised.\n *\n * Never soft-fail this: a bundle is a supply-chain artifact and a corrupt or\n * substituted tarball is exactly what integrity checking exists to catch.\n */\nexport class IntegrityError extends BundlerErrorBase {\n\treadonly _tag = \"IntegrityError\" as const;\n\treadonly packageName: string;\n\treadonly version: string;\n\treadonly expected: string;\n\treadonly actual: string;\n\tconstructor(packageName: string, version: string, expected: string, actual: string) {\n\t\tsuper(\n\t\t\t`Integrity check failed for ${packageName}@${version}.\\n` +\n\t\t\t\t` expected: ${expected}\\n` +\n\t\t\t\t` actual: ${actual}\\n` +\n\t\t\t\t` The download was discarded. This is either corruption in transit or a tampered artifact.`,\n\t\t);\n\t\tthis.packageName = packageName;\n\t\tthis.version = version;\n\t\tthis.expected = expected;\n\t\tthis.actual = actual;\n\t}\n}\n\n/** Something went wrong writing the `.tgz`. */\nexport class ArchiveError extends BundlerErrorBase {\n\treadonly _tag = \"ArchiveError\" as const;\n\treadonly path: string;\n\tconstructor(path: string, detail: string, options?: { cause?: unknown }) {\n\t\tsuper(`Failed to create archive ${path}: ${detail}`, options);\n\t\tthis.path = path;\n\t}\n}\n\n/** Something went wrong preparing or writing to the output directory. */\nexport class OutputError extends BundlerErrorBase {\n\treadonly _tag = \"OutputError\" as const;\n\treadonly path: string;\n\tconstructor(path: string, detail: string, options?: { cause?: unknown }) {\n\t\tsuper(`Output error at ${path}: ${detail}`, options);\n\t\tthis.path = path;\n\t}\n}\n\nconst safeHost = (registry: string): string => {\n\ttry {\n\t\tconst url = new URL(registry);\n\t\treturn url.host + url.pathname.replace(/\\/+$/, \"\");\n\t} catch {\n\t\treturn registry;\n\t}\n};\n","/**\n * Progress reporting.\n *\n * The engine emits structured events; it never writes to a terminal. That\n * separation is what lets the CLI draw a live TTY view, CI print plain lines,\n * and the test suite assert on an array of events without any of them\n * interfering with each other.\n */\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Ref from \"effect/Ref\";\n\nimport type { Phase } from \"./enums/phase.js\";\n\n/** A structured progress event. */\nexport type ProgressEvent =\n\t/** A phase began. `total` is set only when it is known up front. */\n\t| { readonly _tag: \"PhaseStarted\"; readonly phase: Phase; readonly total?: number | undefined }\n\t/** A phase finished. */\n\t| { readonly _tag: \"PhaseCompleted\"; readonly phase: Phase }\n\t/** The resolver discovered a package that has to be included. */\n\t| {\n\t\t\treadonly _tag: \"PackageResolved\";\n\t\t\treadonly name: string;\n\t\t\treadonly version: string;\n\t\t\t/** Running count of resolved packages, for a live counter. */\n\t\t\treadonly resolvedCount: number;\n\t\t\t/** Packages still queued for resolution. */\n\t\t\treadonly pendingCount: number;\n\t }\n\t/** A tarball download started. */\n\t| { readonly _tag: \"DownloadStarted\"; readonly name: string; readonly version: string }\n\t/** A tarball download finished. */\n\t| {\n\t\t\treadonly _tag: \"DownloadCompleted\";\n\t\t\treadonly name: string;\n\t\t\treadonly version: string;\n\t\t\treadonly bytes: number;\n\t\t\treadonly completedCount: number;\n\t\t\treadonly totalCount: number;\n\t }\n\t/** A download failed and will be retried. */\n\t| {\n\t\t\treadonly _tag: \"DownloadRetrying\";\n\t\t\treadonly name: string;\n\t\t\treadonly version: string;\n\t\t\treadonly attempt: number;\n\t\t\treadonly reason: string;\n\t }\n\t/** An archive is being written. */\n\t| { readonly _tag: \"ArchiveStarted\"; readonly path: string; readonly entryCount: number }\n\t/** An archive finished. */\n\t| { readonly _tag: \"ArchiveCompleted\"; readonly path: string; readonly bytes: number }\n\t/** Something noteworthy but non-fatal, e.g. a deprecated package. */\n\t| { readonly _tag: \"Warning\"; readonly message: string };\n\nexport declare namespace Progress {\n\t/** The reporting sink. */\n\texport type Service = {\n\t\treadonly emit: (event: ProgressEvent) => Effect.Effect<void>;\n\t};\n}\n\n/** Service tag for progress reporting. */\nexport class Progress extends Context.Service<Progress, Progress.Service>()(\n\t\"@packall/core/Progress\",\n) {}\n\n/** Emits an event to whichever reporter is installed. */\nexport const emit = (event: ProgressEvent): Effect.Effect<void, never, Progress> =>\n\tEffect.gen(function* () {\n\t\tconst progress = yield* Progress;\n\t\tyield* progress.emit(event);\n\t});\n\n/**\n * Discards every event.\n *\n * The default for library consumers and for tests that do not care about\n * progress — silence should never require ceremony.\n */\nexport const layerSilent: Layer.Layer<Progress> = Layer.succeed(Progress)({\n\temit: () => Effect.void,\n});\n\n/** Sends every event to a callback. Used by the CLI renderer. */\nexport const layerCallback = (onEvent: (event: ProgressEvent) => void): Layer.Layer<Progress> =>\n\tLayer.succeed(Progress)({\n\t\temit: (event) => Effect.sync(() => onEvent(event)),\n\t});\n\n/**\n * Accumulates every event into a `Ref`, for assertions.\n *\n * Returned as `{ layer, events }` so a test can provide the layer and then read\n * the transcript afterwards.\n */\nexport const makeCollector = Effect.gen(function* () {\n\tconst ref = yield* Ref.make<ReadonlyArray<ProgressEvent>>([]);\n\tconst layer = Layer.succeed(Progress)({\n\t\temit: (event: ProgressEvent) => Ref.update(ref, (events) => [...events, event]),\n\t});\n\treturn { layer, events: Ref.get(ref) } as const;\n});\n","/**\n * Turning a staged directory tree into a gzipped tarball.\n *\n * A service rather than a function, because packing is the one step that has\n * to be implemented differently per platform. Everywhere else the engine\n * reaches the disk through `effect/FileSystem`, which is what lets an in-memory\n * filesystem carry the whole pipeline — but a tar writer is not filesystem\n * access, it is a format, and `node-tar` reads the paths it is given with\n * Node's own `fs` rather than through the injected service. Left as a direct\n * call, packing would quietly bypass the abstraction the rest of the engine\n * depends on, which stays invisible until something other than Node provides\n * the filesystem.\n *\n * The implementations live outside this module — `@packall/core/node` for\n * Node, a Web Streams writer in the browser — so nothing platform-specific is\n * reachable from the engine's own graph.\n */\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport type * as FileSystem from \"effect/FileSystem\";\nimport type { PlatformError } from \"effect/PlatformError\";\n\nimport type { ArchiveError } from \"./errors.js\";\nimport * as Progress from \"./progress.js\";\n\n/** A finished archive. */\nexport type ArchiveResult = {\n\treadonly path: string;\n\treadonly bytes: number;\n};\n\n/** What to pack, and where to put it. */\nexport type CreateArchiveOptions = {\n\treadonly cwd: string;\n\t/** Entry paths, relative to `cwd`. */\n\treadonly entries: ReadonlyArray<string>;\n\treadonly outPath: string;\n\treadonly gzipLevel?: number | undefined;\n};\n\nexport declare namespace Archiver {\n\t/** The packing backend. */\n\texport type Service = {\n\t\t/**\n\t\t * Packs `entries` (paths relative to `cwd`) into a gzipped tar at\n\t\t * `outPath`.\n\t\t *\n\t\t * Implementations must produce byte-identical output for identical inputs —\n\t\t * normalised uid/gid/mtime, entries in a stable order — because a security\n\t\t * team diffing two bundles, or re-deriving one from its manifest, is a\n\t\t * thing that actually happens.\n\t\t */\n\t\treadonly create: (\n\t\t\toptions: CreateArchiveOptions,\n\t\t) => Effect.Effect<ArchiveResult, ArchiveError | PlatformError, FileSystem.FileSystem>;\n\t};\n}\n\n/** Service tag for archive creation. */\nexport class Archiver extends Context.Service<Archiver, Archiver.Service>()(\n\t\"@packall/core/Archiver\",\n) {}\n\n/**\n * Packs an archive with whichever backend is installed.\n *\n * The progress events are emitted here rather than inside the backends, so\n * every implementation reports identically and a new one cannot forget to.\n */\nexport const createArchive = (\n\toptions: CreateArchiveOptions,\n): Effect.Effect<\n\tArchiveResult,\n\tArchiveError | PlatformError,\n\tArchiver | FileSystem.FileSystem | Progress.Progress\n> =>\n\tEffect.gen(function* () {\n\t\tconst archiver = yield* Archiver;\n\n\t\tyield* Progress.emit({\n\t\t\t_tag: \"ArchiveStarted\",\n\t\t\tpath: options.outPath,\n\t\t\tentryCount: options.entries.length,\n\t\t});\n\n\t\tconst result = yield* archiver.create(options);\n\n\t\tyield* Progress.emit({\n\t\t\t_tag: \"ArchiveCompleted\",\n\t\t\tpath: result.path,\n\t\t\tbytes: result.bytes,\n\t\t});\n\n\t\treturn result;\n\t});\n"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Turning a staged directory tree into a gzipped tarball.
3
+ *
4
+ * A service rather than a function, because packing is the one step that has
5
+ * to be implemented differently per platform. Everywhere else the engine
6
+ * reaches the disk through `effect/FileSystem`, which is what lets an in-memory
7
+ * filesystem carry the whole pipeline — but a tar writer is not filesystem
8
+ * access, it is a format, and `node-tar` reads the paths it is given with
9
+ * Node's own `fs` rather than through the injected service. Left as a direct
10
+ * call, packing would quietly bypass the abstraction the rest of the engine
11
+ * depends on, which stays invisible until something other than Node provides
12
+ * the filesystem.
13
+ *
14
+ * The implementations live outside this module — `@packall/core/node` for
15
+ * Node, a Web Streams writer in the browser — so nothing platform-specific is
16
+ * reachable from the engine's own graph.
17
+ */
18
+ import * as Context from "effect/Context";
19
+ import * as Effect from "effect/Effect";
20
+ import type * as FileSystem from "effect/FileSystem";
21
+ import type { PlatformError } from "effect/PlatformError";
22
+ import type { ArchiveError } from "./errors.js";
23
+ import * as Progress from "./progress.js";
24
+ /** A finished archive. */
25
+ export type ArchiveResult = {
26
+ readonly path: string;
27
+ readonly bytes: number;
28
+ };
29
+ /** What to pack, and where to put it. */
30
+ export type CreateArchiveOptions = {
31
+ readonly cwd: string;
32
+ /** Entry paths, relative to `cwd`. */
33
+ readonly entries: ReadonlyArray<string>;
34
+ readonly outPath: string;
35
+ readonly gzipLevel?: number | undefined;
36
+ };
37
+ export declare namespace Archiver {
38
+ /** The packing backend. */
39
+ type Service = {
40
+ /**
41
+ * Packs `entries` (paths relative to `cwd`) into a gzipped tar at
42
+ * `outPath`.
43
+ *
44
+ * Implementations must produce byte-identical output for identical inputs —
45
+ * normalised uid/gid/mtime, entries in a stable order — because a security
46
+ * team diffing two bundles, or re-deriving one from its manifest, is a
47
+ * thing that actually happens.
48
+ */
49
+ readonly create: (options: CreateArchiveOptions) => Effect.Effect<ArchiveResult, ArchiveError | PlatformError, FileSystem.FileSystem>;
50
+ };
51
+ }
52
+ declare const Archiver_base: Context.ServiceClass<Archiver, "@packall/core/Archiver", Archiver.Service>;
53
+ /** Service tag for archive creation. */
54
+ export declare class Archiver extends Archiver_base {
55
+ }
56
+ /**
57
+ * Packs an archive with whichever backend is installed.
58
+ *
59
+ * The progress events are emitted here rather than inside the backends, so
60
+ * every implementation reports identically and a new one cannot forget to.
61
+ */
62
+ export declare const createArchive: (options: CreateArchiveOptions) => Effect.Effect<ArchiveResult, ArchiveError | PlatformError, Archiver | FileSystem.FileSystem | Progress.Progress>;
63
+ export {};
64
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,UAAU,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,0BAA0B;AAC1B,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IACjC,2BAA2B;IAC3B,KAAY,OAAO,GAAG;QACrB;;;;;;;;WAQG;QACH,QAAQ,CAAC,MAAM,EAAE,CAChB,OAAO,EAAE,oBAAoB,KACzB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,GAAG,aAAa,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;KACvF,CAAC;CACF;;AAED,wCAAwC;AACxC,qBAAa,QAAS,SAAQ,aAE7B;CAAG;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,aAAa,YAChB,oBAAoB,KAC3B,MAAM,CAAC,MAAM,CACf,aAAa,EACb,YAAY,GAAG,aAAa,EAC5B,QAAQ,GAAG,UAAU,CAAC,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAoBlD,CAAC"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * End-to-end orchestration: specs in, tarballs out.
3
3
  *
4
- * Two properties this module is responsible for, both of them fixes for how
5
- * the original tool behaved:
4
+ * Two properties this module is responsible for see `notes/requirements.md`
5
+ * § FR-5 and § NFR-9 for why they are requirements, and the mechanisms below
6
+ * for why the code reads as it does:
6
7
  *
7
8
  * 1. **Nothing is written outside the output directory.** Every intermediate
8
9
  * file lives in a scoped temp directory obtained from
@@ -15,28 +16,34 @@
15
16
  * shared download tree, so `per-spec` costs extra disk in the *output*, not
16
17
  * extra network.
17
18
  */
19
+ import type * as Crypto from "effect/Crypto";
18
20
  import * as Effect from "effect/Effect";
19
21
  import * as FileSystem from "effect/FileSystem";
20
22
  import * as Path from "effect/Path";
21
23
  import type { PlatformError } from "effect/PlatformError";
22
- import type { BundlerError } from "./Errors.js";
23
- import type { BundleOptions, Layout } from "./Options.js";
24
- import * as Progress from "./Progress.js";
25
- import { Registry } from "./Registry.js";
26
- import type { Resolution } from "./Resolve.js";
27
- import type { PackageSpec } from "./Spec.js";
24
+ import type { Archiver } from "./archive.js";
25
+ import { ArtifactKind } from "./enums/artifact-kind.js";
26
+ import { Layout } from "./enums/layout.js";
27
+ import type { BundlerError } from "./errors.js";
28
+ import type { LockedResolveOptions } from "./locked-resolve.js";
29
+ import type { LockedTree } from "./lockfile/types.js";
30
+ import type { BundleOptions } from "./options.js";
31
+ import * as Progress from "./progress.js";
32
+ import { Registry } from "./registry.js";
33
+ import type { Resolution } from "./resolve.js";
34
+ import type { PackageSpec } from "./spec.js";
28
35
  /** One thing written to the output directory. */
29
- export interface BundleArtifact {
30
- readonly kind: "archive" | "directory";
36
+ export type BundleArtifact = {
37
+ readonly kind: ArtifactKind;
31
38
  readonly path: string;
32
39
  readonly bytes: number;
33
40
  readonly packageCount: number;
34
41
  /** Which spec this artifact covers. Absent for `single` and `dir`. */
35
42
  readonly spec?: string | undefined;
36
43
  readonly version?: string | undefined;
37
- }
44
+ };
38
45
  /** The outcome of a bundle run. */
39
- export interface BundleResult {
46
+ export type BundleResult = {
40
47
  readonly resolution: Resolution;
41
48
  readonly artifacts: ReadonlyArray<BundleArtifact>;
42
49
  /** Total bytes downloaded from the registry. */
@@ -44,17 +51,17 @@ export interface BundleResult {
44
51
  /** Packages the registry advertised no usable checksum for. */
45
52
  readonly unverified: ReadonlyArray<string>;
46
53
  readonly dryRun: boolean;
47
- }
54
+ };
48
55
  /** Everything `bundle` needs beyond the user-facing options. */
49
- export interface BundleContext extends BundleOptions {
56
+ export type BundleContext = BundleOptions & {
50
57
  /** Recorded in the manifest so a bundle can be traced to the tool that built it. */
51
58
  readonly toolVersion: string;
52
- }
59
+ };
53
60
  /**
54
61
  * A summary of what a resolution would produce, for deciding whether the
55
62
  * chosen layout is still the right one.
56
63
  */
57
- export interface PlanSummary {
64
+ export type PlanSummary = {
58
65
  /** Distinct packages in the deduplicated union. */
59
66
  readonly uniquePackages: number;
60
67
  /** How many archives `per-spec` layout would emit. */
@@ -65,12 +72,27 @@ export interface PlanSummary {
65
72
  * `uniquePackages` is exactly what `single` layout would save.
66
73
  */
67
74
  readonly perSpecEntries: number;
68
- }
75
+ };
76
+ /**
77
+ * The files a run will write, known before anything is downloaded.
78
+ *
79
+ * `dir` layout is the odd one: it merges a package tree into `outDir`, and
80
+ * package paths are `name/-/name-version.tgz` — the same package at the same
81
+ * version is the same bytes, so an overlap there is idempotent rather than
82
+ * destructive. Only the two summary files are genuinely replaced, and those are
83
+ * the ones worth guarding.
84
+ */
85
+ export type PlannedOutput = {
86
+ readonly file: string;
87
+ /** The root this file belongs to, when one file corresponds to one spec. */
88
+ readonly name?: string | undefined;
89
+ readonly version?: string | undefined;
90
+ };
91
+ type BundleEnv = Registry | Progress.Progress | FileSystem.FileSystem | Path.Path | Crypto.Crypto | Archiver;
69
92
  /** Computes the plan summary for a resolution. */
70
93
  export declare const summarize: (resolution: Resolution) => PlanSummary;
71
94
  /** Replaces the layout on a set of options. */
72
95
  export declare const withLayout: <T extends BundleOptions>(options: T, layout: Layout) => T;
73
- type BundleEnv = Registry | Progress.Progress | FileSystem.FileSystem | Path.Path;
74
96
  /**
75
97
  * Checks the registry is reachable, then resolves every spec.
76
98
  *
@@ -80,6 +102,16 @@ type BundleEnv = Registry | Progress.Progress | FileSystem.FileSystem | Path.Pat
80
102
  * expected.
81
103
  */
82
104
  export declare const plan: (specs: ReadonlyArray<PackageSpec>, options: BundleOptions) => Effect.Effect<Resolution, BundlerError, Registry | Progress.Progress>;
105
+ /**
106
+ * The lockfile counterpart of `plan`.
107
+ *
108
+ * Same preflight, same `Resolution` out; the difference is entirely in how the
109
+ * package set is arrived at. Kept as a separate entry point rather than an
110
+ * option on `plan` because the two take genuinely different inputs — a set of
111
+ * specs to satisfy versus a graph to reproduce — and blurring that is how a
112
+ * "pinned" run quietly starts resolving ranges again.
113
+ */
114
+ export declare const planLocked: (lockfile: LockedTree, options: BundleOptions & LockedResolveOptions) => Effect.Effect<Resolution, BundlerError, Registry | Progress.Progress>;
83
115
  /**
84
116
  * Resolves, downloads and packages a set of specs.
85
117
  *
@@ -88,6 +120,8 @@ export declare const plan: (specs: ReadonlyArray<PackageSpec>, options: BundleOp
88
120
  * download over a slow VPN.
89
121
  */
90
122
  export declare const bundle: (specs: ReadonlyArray<PackageSpec>, options: BundleContext) => Effect.Effect<BundleResult, BundlerError | PlatformError, BundleEnv>;
123
+ /** `bundle`, pinned to a lockfile. */
124
+ export declare const bundleLocked: (lockfile: LockedTree, options: BundleContext & LockedResolveOptions) => Effect.Effect<BundleResult, BundlerError | PlatformError, BundleEnv>;
91
125
  /**
92
126
  * Downloads and packages an already-computed resolution.
93
127
  *
@@ -97,27 +131,11 @@ export declare const bundle: (specs: ReadonlyArray<PackageSpec>, options: Bundle
97
131
  */
98
132
  export declare const bundleResolved: (resolution: Resolution, options: BundleContext) => Effect.Effect<BundleResult, BundlerError | PlatformError, BundleEnv>;
99
133
  /**
100
- * Creates the output directory, refusing to clobber an existing non-empty one
101
- * unless `--force` was passed.
134
+ * The files a run will write.
102
135
  *
103
- * Silently overwriting somebody's previous bundle is the kind of thing a tool
104
- * only gets forgiven for once.
105
- */
106
- /**
107
- * The files a run will write, known before anything is downloaded.
108
- *
109
- * `dir` layout is the odd one: it merges a package tree into `outDir`, and
110
- * package paths are `name/-/name-version.tgz` — the same package at the same
111
- * version is the same bytes, so an overlap there is idempotent rather than
112
- * destructive. Only the two summary files are genuinely replaced, and those are
113
- * the ones worth guarding.
136
+ * Computed before anything is downloaded, so a collision is reported in the
137
+ * first second rather than after a twenty-minute transfer.
114
138
  */
115
- export interface PlannedOutput {
116
- readonly file: string;
117
- /** The root this file belongs to, when one file corresponds to one spec. */
118
- readonly name?: string | undefined;
119
- readonly version?: string | undefined;
120
- }
121
139
  export declare const plannedOutputs: (resolution: Resolution, options: BundleContext) => ReadonlyArray<PlannedOutput>;
122
140
  export {};
123
- //# sourceMappingURL=Bundle.d.ts.map
141
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { Selector } from "./Spec.js";
1
+ import type { Selector } from "./spec.js";
2
2
  /** What a dependency edge points at. */
3
3
  export type DependencyTarget =
4
4
  /** A normal registry dependency. `name` may differ from the key under an alias. */
@@ -23,4 +23,4 @@ export type DependencyTarget =
23
23
  * treats them interchangeably and so do we.
24
24
  */
25
25
  export declare const parseDependencyTarget: (name: string, raw: string) => DependencyTarget;
26
- //# sourceMappingURL=DependencyRange.d.ts.map
26
+ //# sourceMappingURL=dependency-range.d.ts.map