@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.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/archive-6sqTn1C4.js +274 -0
- package/dist/archive-6sqTn1C4.js.map +1 -0
- package/dist/archive.d.ts +47 -15
- package/dist/archive.d.ts.map +1 -1
- package/dist/bundle.d.ts +6 -3
- package/dist/bundle.d.ts.map +1 -1
- package/dist/dependency-range.d.ts.map +1 -1
- package/dist/download.d.ts +2 -1
- package/dist/download.d.ts.map +1 -1
- package/dist/enums/artifact-kind.d.ts.map +1 -1
- package/dist/enums/edge-kind.d.ts.map +1 -1
- package/dist/enums/input-file-kind.d.ts.map +1 -1
- package/dist/enums/layout.d.ts.map +1 -1
- package/dist/enums/lockfile-format.d.ts.map +1 -1
- package/dist/enums/phase.d.ts.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -344
- package/dist/index.js.map +1 -1
- package/dist/input-file.d.ts.map +1 -1
- package/dist/integrity.d.ts +37 -5
- package/dist/integrity.d.ts.map +1 -1
- package/dist/layout.d.ts +41 -7
- package/dist/layout.d.ts.map +1 -1
- package/dist/locked-resolve.d.ts.map +1 -1
- package/dist/lockfile/bun.d.ts.map +1 -1
- package/dist/lockfile/detect.d.ts.map +1 -1
- package/dist/lockfile/json.d.ts.map +1 -1
- package/dist/lockfile/names.d.ts.map +1 -1
- package/dist/lockfile/npm.d.ts.map +1 -1
- package/dist/lockfile/parse.d.ts.map +1 -1
- package/dist/lockfile/pnpm.d.ts.map +1 -1
- package/dist/lockfile/tree-builder.d.ts.map +1 -1
- package/dist/lockfile/types.d.ts.map +1 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/node/archiver.d.ts +5 -0
- package/dist/node/archiver.d.ts.map +1 -0
- package/dist/node/index.d.ts +13 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +55 -0
- package/dist/node/index.js.map +1 -0
- package/dist/options.d.ts +3 -3
- package/dist/options.d.ts.map +1 -1
- package/dist/platform.d.ts +5 -10
- package/dist/platform.d.ts.map +1 -1
- package/dist/progress.d.ts.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/schemas/lenient.d.ts.map +1 -1
- package/dist/schemas/package-json.d.ts.map +1 -1
- package/dist/spec.d.ts.map +1 -1
- package/dist/types/value-of.d.ts.map +1 -1
- package/dist/utils/is-record.d.ts.map +1 -1
- package/package.json +11 -10
- package/src/archive.ts +95 -92
- package/src/bundle.ts +736 -616
- package/src/dependency-range.ts +121 -115
- package/src/download.ts +155 -133
- package/src/enums/artifact-kind.ts +5 -5
- package/src/enums/edge-kind.ts +13 -13
- package/src/enums/input-file-kind.ts +9 -9
- package/src/enums/layout.ts +20 -20
- package/src/enums/lockfile-format.ts +6 -6
- package/src/enums/phase.ts +8 -8
- package/src/errors.ts +200 -198
- package/src/index.ts +126 -113
- package/src/input-file.ts +246 -234
- package/src/integrity.ts +165 -121
- package/src/layout.ts +63 -29
- package/src/locked-resolve.ts +471 -461
- package/src/lockfile/bun.ts +214 -207
- package/src/lockfile/detect.ts +80 -80
- package/src/lockfile/json.ts +91 -92
- package/src/lockfile/names.ts +9 -9
- package/src/lockfile/npm.ts +328 -308
- package/src/lockfile/parse.ts +32 -32
- package/src/lockfile/pnpm.ts +230 -225
- package/src/lockfile/tree-builder.ts +116 -116
- package/src/lockfile/types.ts +52 -52
- package/src/manifest.ts +129 -133
- package/src/node/archiver.ts +85 -0
- package/src/node/index.ts +13 -0
- package/src/options.ts +84 -84
- package/src/platform.ts +97 -101
- package/src/progress.ts +105 -106
- package/src/registry.ts +116 -115
- package/src/resolve.ts +560 -537
- package/src/schemas/lenient.ts +67 -60
- package/src/schemas/package-json.ts +11 -10
- package/src/spec.ts +123 -119
- package/src/types/value-of.ts +1 -1
- package/src/utils/is-record.ts +1 -1
package/src/lockfile/json.ts
CHANGED
|
@@ -7,44 +7,43 @@
|
|
|
7
7
|
* response boundary uses — so "tolerated" means one thing across the codebase
|
|
8
8
|
* rather than being re-decided per parser.
|
|
9
9
|
*/
|
|
10
|
-
import * as Option from "effect/Option"
|
|
11
|
-
import * as Schema from "effect/Schema"
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Schema from "effect/Schema";
|
|
12
|
+
|
|
13
|
+
import { LockfileError } from "../errors.js";
|
|
14
|
+
import { OptionalFlagRecordSchema, StringRecordSchema } from "../schemas/lenient.js";
|
|
15
|
+
import { isRecord } from "../utils/is-record.js";
|
|
15
16
|
|
|
16
17
|
export const stringOr = (value: unknown, fallback: string): string =>
|
|
17
|
-
|
|
18
|
+
typeof value === "string" ? value : fallback;
|
|
18
19
|
|
|
19
|
-
const decodeStringRecord = Schema.decodeUnknownOption(StringRecordSchema)
|
|
20
|
+
const decodeStringRecord = Schema.decodeUnknownOption(StringRecordSchema);
|
|
20
21
|
|
|
21
22
|
/** Keeps only the string-valued members of an untyped object. */
|
|
22
23
|
export const stringRecord = (value: unknown): Readonly<Record<string, string>> =>
|
|
23
|
-
|
|
24
|
+
Option.getOrElse(decodeStringRecord(value), (): Record<string, string> => ({}));
|
|
24
25
|
|
|
25
|
-
const decodeOptionalFlags = Schema.decodeUnknownOption(OptionalFlagRecordSchema)
|
|
26
|
+
const decodeOptionalFlags = Schema.decodeUnknownOption(OptionalFlagRecordSchema);
|
|
26
27
|
|
|
27
28
|
/** Names a package marked its peers optional with. */
|
|
28
29
|
export const optionalPeerNames = (value: unknown): ReadonlySet<string> => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
36
|
-
}
|
|
30
|
+
const flags = Option.getOrElse(
|
|
31
|
+
decodeOptionalFlags(value),
|
|
32
|
+
(): Record<string, { readonly optional: boolean }> => ({}),
|
|
33
|
+
);
|
|
34
|
+
return new Set(Object.entries(flags).flatMap(([name, meta]) => (meta.optional ? name : [])));
|
|
35
|
+
};
|
|
37
36
|
|
|
38
37
|
export const parseJsonObject = (path: string, content: string): Record<string, unknown> => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
38
|
+
const parsed = tryParseJsonc(content);
|
|
39
|
+
if (parsed === undefined) {
|
|
40
|
+
throw new LockfileError(path, "not valid JSON");
|
|
41
|
+
}
|
|
42
|
+
if (!isRecord(parsed)) {
|
|
43
|
+
throw new LockfileError(path, "top level is not an object");
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
};
|
|
48
47
|
|
|
49
48
|
/**
|
|
50
49
|
* Parses JSON, tolerating the comments and trailing commas bun writes.
|
|
@@ -54,16 +53,16 @@ export const parseJsonObject = (path: string, content: string): Record<string, u
|
|
|
54
53
|
* throwing so detection can use it as a probe.
|
|
55
54
|
*/
|
|
56
55
|
export const tryParseJsonc = (content: string): unknown => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(content);
|
|
58
|
+
} catch {
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(stripJsonc(content));
|
|
61
|
+
} catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
67
66
|
|
|
68
67
|
/**
|
|
69
68
|
* Removes comments and trailing commas.
|
|
@@ -72,61 +71,61 @@ export const tryParseJsonc = (content: string): unknown => {
|
|
|
72
71
|
* escaped quote does not end a string. Both appear in every real lockfile.
|
|
73
72
|
*/
|
|
74
73
|
export const stripJsonc = (content: string): string => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
74
|
+
let out = "";
|
|
75
|
+
let index = 0;
|
|
76
|
+
let inString = false;
|
|
77
|
+
|
|
78
|
+
while (index < content.length) {
|
|
79
|
+
const char = content[index];
|
|
80
|
+
|
|
81
|
+
if (inString) {
|
|
82
|
+
out += char;
|
|
83
|
+
if (char === "\\") {
|
|
84
|
+
out += content[index + 1] ?? "";
|
|
85
|
+
index += 2;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (char === '"') inString = false;
|
|
89
|
+
index += 1;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (char === '"') {
|
|
94
|
+
inString = true;
|
|
95
|
+
out += char;
|
|
96
|
+
index += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (char === "/" && content[index + 1] === "/") {
|
|
101
|
+
const end = content.indexOf("\n", index);
|
|
102
|
+
index = end === -1 ? content.length : end;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (char === "/" && content[index + 1] === "*") {
|
|
107
|
+
const end = content.indexOf("*/", index + 2);
|
|
108
|
+
index = end === -1 ? content.length : end + 2;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// A comma is trailing when the next thing that is not whitespace closes the
|
|
113
|
+
// structure it sits in.
|
|
114
|
+
if (char === ",") {
|
|
115
|
+
const next = content.slice(index + 1).search(/\S/);
|
|
116
|
+
const following = next === -1 ? "" : content[index + 1 + next];
|
|
117
|
+
if (following === "}" || following === "]") {
|
|
118
|
+
index += 1;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
out += char;
|
|
124
|
+
index += 1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return out;
|
|
128
|
+
};
|
|
130
129
|
|
|
131
130
|
export const describeError = (error: unknown): string =>
|
|
132
|
-
|
|
131
|
+
error instanceof Error ? error.message : String(error);
|
package/src/lockfile/names.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LockfileFormat } from "../enums/lockfile-format.js"
|
|
1
|
+
import { LockfileFormat } from "../enums/lockfile-format.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The file name each supported manager writes, in detection order.
|
|
@@ -7,14 +7,14 @@ import { LockfileFormat } from "../enums/lockfile-format.js"
|
|
|
7
7
|
* bun's, so a directory holding several is searched the way npm itself would.
|
|
8
8
|
*/
|
|
9
9
|
export const formatByLockfileName = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} as const satisfies Record<string, LockfileFormat
|
|
10
|
+
"package-lock.json": LockfileFormat.Npm,
|
|
11
|
+
"npm-shrinkwrap.json": LockfileFormat.Npm,
|
|
12
|
+
"pnpm-lock.yaml": LockfileFormat.Pnpm,
|
|
13
|
+
"bun.lock": LockfileFormat.Bun,
|
|
14
|
+
} as const satisfies Record<string, LockfileFormat>;
|
|
15
15
|
|
|
16
16
|
/** The names a given manager writes. */
|
|
17
17
|
export const lockfileNamesFor = (format: LockfileFormat): ReadonlyArray<string> =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Object.entries(formatByLockfileName).flatMap(([name, candidate]) =>
|
|
19
|
+
candidate === format ? name : [],
|
|
20
|
+
);
|