@packall/core 0.0.1 → 0.1.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 (126) hide show
  1. package/dist/{Archive.d.ts → archive.d.ts} +5 -5
  2. package/dist/archive.d.ts.map +1 -0
  3. package/dist/{Bundle.d.ts → bundle.d.ts} +51 -36
  4. package/dist/bundle.d.ts.map +1 -0
  5. package/dist/{DependencyRange.d.ts → dependency-range.d.ts} +2 -2
  6. package/dist/dependency-range.d.ts.map +1 -0
  7. package/dist/{Download.d.ts → download.d.ts} +7 -7
  8. package/dist/download.d.ts.map +1 -0
  9. package/dist/enums/artifact-kind.d.ts +8 -0
  10. package/dist/enums/artifact-kind.d.ts.map +1 -0
  11. package/dist/enums/edge-kind.d.ts +29 -0
  12. package/dist/enums/edge-kind.d.ts.map +1 -0
  13. package/dist/enums/input-file-kind.d.ts +12 -0
  14. package/dist/enums/input-file-kind.d.ts.map +1 -0
  15. package/dist/enums/layout.d.ts +23 -0
  16. package/dist/enums/layout.d.ts.map +1 -0
  17. package/dist/enums/lockfile-format.d.ts +9 -0
  18. package/dist/enums/lockfile-format.d.ts.map +1 -0
  19. package/dist/enums/phase.d.ts +11 -0
  20. package/dist/enums/phase.d.ts.map +1 -0
  21. package/dist/{Errors.d.ts → errors.d.ts} +49 -7
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/index.d.ts +44 -28
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2416 -1180
  26. package/dist/index.js.map +1 -1
  27. package/dist/input-file.d.ts +77 -0
  28. package/dist/input-file.d.ts.map +1 -0
  29. package/dist/{Integrity.d.ts → integrity.d.ts} +3 -3
  30. package/dist/integrity.d.ts.map +1 -0
  31. package/dist/{Layout.d.ts → layout.d.ts} +1 -1
  32. package/dist/{Layout.d.ts.map → layout.d.ts.map} +1 -1
  33. package/dist/locked-resolve.d.ts +47 -0
  34. package/dist/locked-resolve.d.ts.map +1 -0
  35. package/dist/lockfile/bun.d.ts +3 -0
  36. package/dist/lockfile/bun.d.ts.map +1 -0
  37. package/dist/lockfile/detect.d.ts +31 -0
  38. package/dist/lockfile/detect.d.ts.map +1 -0
  39. package/dist/lockfile/json.d.ts +23 -0
  40. package/dist/lockfile/json.d.ts.map +1 -0
  41. package/dist/lockfile/names.d.ts +16 -0
  42. package/dist/lockfile/names.d.ts.map +1 -0
  43. package/dist/lockfile/npm.d.ts +3 -0
  44. package/dist/lockfile/npm.d.ts.map +1 -0
  45. package/dist/lockfile/parse.d.ts +23 -0
  46. package/dist/lockfile/parse.d.ts.map +1 -0
  47. package/dist/lockfile/pnpm.d.ts +20 -0
  48. package/dist/lockfile/pnpm.d.ts.map +1 -0
  49. package/dist/lockfile/tree-builder.d.ts +70 -0
  50. package/dist/lockfile/tree-builder.d.ts.map +1 -0
  51. package/dist/lockfile/types.d.ts +70 -0
  52. package/dist/lockfile/types.d.ts.map +1 -0
  53. package/dist/{Manifest.d.ts → manifest.d.ts} +7 -15
  54. package/dist/manifest.d.ts.map +1 -0
  55. package/dist/{Options.d.ts → options.d.ts} +9 -27
  56. package/dist/options.d.ts.map +1 -0
  57. package/dist/{Platform.d.ts → platform.d.ts} +9 -9
  58. package/dist/platform.d.ts.map +1 -0
  59. package/dist/{Progress.d.ts → progress.d.ts} +10 -9
  60. package/dist/progress.d.ts.map +1 -0
  61. package/dist/{Registry.d.ts → registry.d.ts} +42 -44
  62. package/dist/registry.d.ts.map +1 -0
  63. package/dist/{Resolve.d.ts → resolve.d.ts} +25 -26
  64. package/dist/resolve.d.ts.map +1 -0
  65. package/dist/schemas/lenient.d.ts +38 -0
  66. package/dist/schemas/lenient.d.ts.map +1 -0
  67. package/dist/schemas/package-json.d.ts +44 -0
  68. package/dist/schemas/package-json.d.ts.map +1 -0
  69. package/dist/{Spec.d.ts → spec.d.ts} +4 -4
  70. package/dist/spec.d.ts.map +1 -0
  71. package/dist/types/value-of.d.ts +9 -0
  72. package/dist/types/value-of.d.ts.map +1 -0
  73. package/dist/utils/is-record.d.ts +8 -0
  74. package/dist/utils/is-record.d.ts.map +1 -0
  75. package/package.json +3 -2
  76. package/src/{Archive.ts → archive.ts} +92 -92
  77. package/src/{Bundle.ts → bundle.ts} +616 -570
  78. package/src/{DependencyRange.ts → dependency-range.ts} +115 -115
  79. package/src/{Download.ts → download.ts} +133 -132
  80. package/src/enums/artifact-kind.ts +9 -0
  81. package/src/enums/edge-kind.ts +32 -0
  82. package/src/enums/input-file-kind.ts +13 -0
  83. package/src/enums/layout.ts +25 -0
  84. package/src/enums/lockfile-format.ts +10 -0
  85. package/src/enums/phase.ts +12 -0
  86. package/src/{Errors.ts → errors.ts} +87 -5
  87. package/src/index.ts +133 -35
  88. package/src/{InputFile.ts → input-file.ts} +127 -44
  89. package/src/{Integrity.ts → integrity.ts} +121 -122
  90. package/src/locked-resolve.ts +461 -0
  91. package/src/lockfile/bun.ts +207 -0
  92. package/src/lockfile/detect.ts +80 -0
  93. package/src/lockfile/json.ts +132 -0
  94. package/src/lockfile/names.ts +20 -0
  95. package/src/lockfile/npm.ts +308 -0
  96. package/src/lockfile/parse.ts +56 -0
  97. package/src/lockfile/pnpm.ts +225 -0
  98. package/src/lockfile/tree-builder.ts +166 -0
  99. package/src/lockfile/types.ts +74 -0
  100. package/src/{Manifest.ts → manifest.ts} +133 -133
  101. package/src/{Options.ts → options.ts} +7 -27
  102. package/src/{Platform.ts → platform.ts} +23 -23
  103. package/src/{Progress.ts → progress.ts} +106 -106
  104. package/src/{Registry.ts → registry.ts} +115 -121
  105. package/src/{Resolve.ts → resolve.ts} +537 -528
  106. package/src/schemas/lenient.ts +123 -0
  107. package/src/schemas/package-json.ts +27 -0
  108. package/src/{Spec.ts → spec.ts} +11 -19
  109. package/src/types/value-of.ts +8 -0
  110. package/src/utils/is-record.ts +8 -0
  111. package/dist/Archive.d.ts.map +0 -1
  112. package/dist/Bundle.d.ts.map +0 -1
  113. package/dist/DependencyRange.d.ts.map +0 -1
  114. package/dist/Download.d.ts.map +0 -1
  115. package/dist/Errors.d.ts.map +0 -1
  116. package/dist/InputFile.d.ts +0 -46
  117. package/dist/InputFile.d.ts.map +0 -1
  118. package/dist/Integrity.d.ts.map +0 -1
  119. package/dist/Manifest.d.ts.map +0 -1
  120. package/dist/Options.d.ts.map +0 -1
  121. package/dist/Platform.d.ts.map +0 -1
  122. package/dist/Progress.d.ts.map +0 -1
  123. package/dist/Registry.d.ts.map +0 -1
  124. package/dist/Resolve.d.ts.map +0 -1
  125. package/dist/Spec.d.ts.map +0 -1
  126. /package/src/{Layout.ts → layout.ts} +0 -0
@@ -1,92 +1,92 @@
1
- /**
2
- * Turning a staged directory tree into a gzipped tarball.
3
- *
4
- * Uses `node-tar`, the same library npm itself packs with. Writing a USTAR
5
- * encoder by hand would be a fun afternoon and a bad idea: scoped package
6
- * paths routinely exceed the 100-byte name field, so correctness depends on
7
- * prefix-splitting and PAX headers that `tar` already gets right.
8
- */
9
- import * as Effect from "effect/Effect"
10
- import * as FileSystem from "effect/FileSystem"
11
- import type { PlatformError } from "effect/PlatformError"
12
- import { create } from "tar"
13
- import { ArchiveError } from "./Errors.js"
14
- import * as Progress from "./Progress.js"
15
-
16
- /** A finished archive. */
17
- export interface ArchiveResult {
18
- readonly path: string
19
- readonly bytes: number
20
- }
21
-
22
- /**
23
- * Packs `entries` (paths relative to `cwd`) into a gzipped tar at `outPath`.
24
- *
25
- * `portable` normalises uid/gid/mtime so the same inputs produce byte-identical
26
- * output — which matters when a security team wants to diff two bundles or
27
- * re-derive one from a manifest.
28
- */
29
- export const createArchive = (options: {
30
- readonly cwd: string
31
- readonly entries: ReadonlyArray<string>
32
- readonly outPath: string
33
- readonly gzipLevel?: number | undefined
34
- }): Effect.Effect<ArchiveResult, ArchiveError | PlatformError, FileSystem.FileSystem | Progress.Progress> =>
35
- Effect.gen(function*() {
36
- const fs = yield* FileSystem.FileSystem
37
-
38
- yield* Progress.emit({
39
- _tag: "ArchiveStarted",
40
- path: options.outPath,
41
- entryCount: options.entries.length
42
- })
43
-
44
- yield* Effect.tryPromise({
45
- try: () =>
46
- create(
47
- {
48
- gzip: options.gzipLevel === undefined ? true : { level: options.gzipLevel },
49
- file: options.outPath,
50
- cwd: options.cwd,
51
- portable: true,
52
- // Undo the `./` added below, so recorded entry names stay exactly
53
- // the registry paths the manifest lists.
54
- onWriteEntry: (entry) => {
55
- entry.path = entry.path.replace(/^\.\//, "")
56
- }
57
- },
58
- // Sorted so archive order is stable across runs and platforms.
59
- [...options.entries].sort().map(dotSlash)
60
- ),
61
- catch: (cause) => new ArchiveError(options.outPath, describe(cause), { cause })
62
- })
63
-
64
- const info = yield* fs.stat(options.outPath)
65
- const bytes = Number(info.size)
66
-
67
- yield* Progress.emit({ _tag: "ArchiveCompleted", path: options.outPath, bytes })
68
-
69
- return { path: options.outPath, bytes }
70
- })
71
-
72
- /**
73
- * Guards every entry against tar's `@` convention.
74
- *
75
- * In a tar file list, a leading `@` means "splice in the entries of this other
76
- * archive" — a GNU convention `node-tar` implements by stripping the `@` and
77
- * looking for what is left. Every scoped package is a top-level entry starting
78
- * with `@`, so this hit the bundler in both possible ways:
79
- *
80
- * - `@oxc-project` became `oxc-project`, which does not exist, and the run died
81
- * with an ENOENT naming a path that appears nowhere in the staging tree.
82
- * - `@esbuild` became `esbuild`, which *does* exist — the unscoped package of
83
- * the same name sitting right next to it. No error, and every scoped tarball
84
- * silently missing from a bundle that reported success. That is the dangerous
85
- * one: you would not find out until the install failed behind the firewall.
86
- *
87
- * `./@scope` is not subject to the convention and resolves identically.
88
- */
89
- const dotSlash = (entry: string): string => (entry.startsWith("./") ? entry : `./${entry}`)
90
-
91
- const describe = (cause: unknown): string =>
92
- cause instanceof Error ? cause.message : String(cause)
1
+ /**
2
+ * Turning a staged directory tree into a gzipped tarball.
3
+ *
4
+ * Uses `node-tar`, the same library npm itself packs with. Writing a USTAR
5
+ * encoder by hand would be a fun afternoon and a bad idea: scoped package
6
+ * paths routinely exceed the 100-byte name field, so correctness depends on
7
+ * prefix-splitting and PAX headers that `tar` already gets right.
8
+ */
9
+ import * as Effect from "effect/Effect"
10
+ import * as FileSystem from "effect/FileSystem"
11
+ import type { PlatformError } from "effect/PlatformError"
12
+ import { create } from "tar"
13
+ import { ArchiveError } from "./errors.js"
14
+ import * as Progress from "./progress.js"
15
+
16
+ /** A finished archive. */
17
+ export type ArchiveResult = {
18
+ readonly path: string
19
+ readonly bytes: number
20
+ }
21
+
22
+ /**
23
+ * Packs `entries` (paths relative to `cwd`) into a gzipped tar at `outPath`.
24
+ *
25
+ * `portable` normalises uid/gid/mtime so the same inputs produce byte-identical
26
+ * output — which matters when a security team wants to diff two bundles or
27
+ * re-derive one from a manifest.
28
+ */
29
+ export const createArchive = (options: {
30
+ readonly cwd: string
31
+ readonly entries: ReadonlyArray<string>
32
+ readonly outPath: string
33
+ readonly gzipLevel?: number | undefined
34
+ }): Effect.Effect<ArchiveResult, ArchiveError | PlatformError, FileSystem.FileSystem | Progress.Progress> =>
35
+ Effect.gen(function*() {
36
+ const fs = yield* FileSystem.FileSystem
37
+
38
+ yield* Progress.emit({
39
+ _tag: "ArchiveStarted",
40
+ path: options.outPath,
41
+ entryCount: options.entries.length
42
+ })
43
+
44
+ yield* Effect.tryPromise({
45
+ try: () =>
46
+ create(
47
+ {
48
+ gzip: options.gzipLevel === undefined ? true : { level: options.gzipLevel },
49
+ file: options.outPath,
50
+ cwd: options.cwd,
51
+ portable: true,
52
+ // Undo the `./` added below, so recorded entry names stay exactly
53
+ // the registry paths the manifest lists.
54
+ onWriteEntry: (entry) => {
55
+ entry.path = entry.path.replace(/^\.\//, "")
56
+ }
57
+ },
58
+ // Sorted so archive order is stable across runs and platforms.
59
+ options.entries.toSorted().map(dotSlash)
60
+ ),
61
+ catch: (cause) => new ArchiveError(options.outPath, describe(cause), { cause })
62
+ })
63
+
64
+ const info = yield* fs.stat(options.outPath)
65
+ const bytes = Number(info.size)
66
+
67
+ yield* Progress.emit({ _tag: "ArchiveCompleted", path: options.outPath, bytes })
68
+
69
+ return { path: options.outPath, bytes }
70
+ })
71
+
72
+ /**
73
+ * Guards every entry against tar's `@` convention.
74
+ *
75
+ * In a tar file list, a leading `@` means "splice in the entries of this other
76
+ * archive" — a GNU convention `node-tar` implements by stripping the `@` and
77
+ * looking for what is left. Every scoped package is a top-level entry starting
78
+ * with `@`, so this hit the bundler in both possible ways:
79
+ *
80
+ * - `@oxc-project` became `oxc-project`, which does not exist, and the run died
81
+ * with an ENOENT naming a path that appears nowhere in the staging tree.
82
+ * - `@esbuild` became `esbuild`, which *does* exist — the unscoped package of
83
+ * the same name sitting right next to it. No error, and every scoped tarball
84
+ * silently missing from a bundle that reported success. That is the dangerous
85
+ * one: you would not find out until the install failed behind the firewall.
86
+ *
87
+ * `./@scope` is not subject to the convention and resolves identically.
88
+ */
89
+ const dotSlash = (entry: string): string => (entry.startsWith("./") ? entry : `./${entry}`)
90
+
91
+ const describe = (cause: unknown): string =>
92
+ cause instanceof Error ? cause.message : String(cause)