pray-cli 1.9.1 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/archive/path-safety.d.ts +2 -0
- package/dist/archive/path-safety.d.ts.map +1 -0
- package/dist/archive/path-safety.js +18 -0
- package/dist/archive/path-safety.js.map +1 -0
- package/dist/archive/praypkg.d.ts.map +1 -1
- package/dist/archive/praypkg.js +35 -9
- package/dist/archive/praypkg.js.map +1 -1
- package/dist/archive/tar.d.ts +3 -0
- package/dist/archive/tar.d.ts.map +1 -0
- package/dist/archive/tar.js +157 -0
- package/dist/archive/tar.js.map +1 -0
- package/dist/auth/session.d.ts +1 -1
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +29 -4
- package/dist/auth/session.js.map +1 -1
- package/dist/http/body.d.ts +2 -0
- package/dist/http/body.d.ts.map +1 -0
- package/dist/http/body.js +32 -0
- package/dist/http/body.js.map +1 -0
- package/dist/http/client.d.ts.map +1 -1
- package/dist/http/client.js +3 -2
- package/dist/http/client.js.map +1 -1
- package/dist/lockfile/types.d.ts +2 -2
- package/dist/lockfile/types.js +1 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +4 -1
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/validate.d.ts +4 -0
- package/dist/manifest/validate.d.ts.map +1 -0
- package/dist/manifest/validate.js +37 -0
- package/dist/manifest/validate.js.map +1 -0
- package/dist/registry/cache.d.ts +2 -0
- package/dist/registry/cache.d.ts.map +1 -0
- package/dist/registry/cache.js +16 -0
- package/dist/registry/cache.js.map +1 -0
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +18 -65
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/install.d.ts +5 -0
- package/dist/registry/install.d.ts.map +1 -0
- package/dist/registry/install.js +55 -0
- package/dist/registry/install.js.map +1 -0
- package/dist/registry/signature.d.ts +4 -0
- package/dist/registry/signature.d.ts.map +1 -0
- package/dist/registry/signature.js +25 -0
- package/dist/registry/signature.js.map +1 -0
- package/dist/render/project.d.ts.map +1 -1
- package/dist/render/project.js +2 -0
- package/dist/render/project.js.map +1 -1
- package/dist/render/provisioned.d.ts.map +1 -1
- package/dist/render/provisioned.js +2 -0
- package/dist/render/provisioned.js.map +1 -1
- package/dist/resource-limits.d.ts +10 -0
- package/dist/resource-limits.d.ts.map +1 -0
- package/dist/resource-limits.js +10 -0
- package/dist/resource-limits.js.map +1 -0
- package/dist/serve/index.d.ts +2 -0
- package/dist/serve/index.d.ts.map +1 -1
- package/dist/serve/index.js +79 -29
- package/dist/serve/index.js.map +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +27 -14
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/path-safety.d.ts +5 -0
- package/dist/sync/path-safety.d.ts.map +1 -0
- package/dist/sync/path-safety.js +48 -0
- package/dist/sync/path-safety.js.map +1 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.9.2 (2026-09-01)
|
|
4
|
+
|
|
5
|
+
- Align package version with the 1.9.2 release.
|
|
6
|
+
- Reject `.praypkg` members that escape the package root or exceed size limits; unpack through staging into cache.
|
|
7
|
+
- Move login sessions to the user Pray home with owner-only permissions and migrate legacy repository sessions.
|
|
8
|
+
- Reject manifest and federation paths outside their roots; require registry hashes and recheck cached package trees.
|
|
9
|
+
- Bound server requests, connections, timeouts, and federation peers; expose readiness and per-request identifiers.
|
|
10
|
+
- Cap registry downloads at 64 MiB; unpack `.praypkg` tar members without system tar; reject absolute artifact URLs and check a present registry signature.
|
|
11
|
+
- Enforce a measured line-coverage floor in CI.
|
|
12
|
+
|
|
3
13
|
## 1.9.1 (2026-08-29)
|
|
4
14
|
|
|
5
15
|
- Rewrite every matching `pray` line when `pray update --latest` moves a package constraint, keeping indent and extra keywords.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-safety.d.ts","sourceRoot":"","sources":["../../src/archive/path-safety.ts"],"names":[],"mappings":"AAGA,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB9D"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isAbsolute, normalize } from "node:path";
|
|
2
|
+
import { PrayError } from "../errors.js";
|
|
3
|
+
export function validateArchiveMemberPath(path) {
|
|
4
|
+
const cleaned = path.replace(/^\.\//, "");
|
|
5
|
+
if (cleaned.length === 0 || isAbsolute(cleaned) || cleaned.startsWith("/")) {
|
|
6
|
+
throw PrayError.integrity(`package path must be relative: ${path}`);
|
|
7
|
+
}
|
|
8
|
+
for (const part of normalize(cleaned).split(/[/\\]/)) {
|
|
9
|
+
if (part === "" || part === ".") {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (part === ".." || part.includes("\0")) {
|
|
13
|
+
throw PrayError.integrity(`package path escapes package root: ${path}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return cleaned;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=path-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-safety.js","sourceRoot":"","sources":["../../src/archive/path-safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3E,MAAM,SAAS,CAAC,SAAS,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,SAAS,CAAC,SAAS,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"praypkg.d.ts","sourceRoot":"","sources":["../../src/archive/praypkg.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"praypkg.d.ts","sourceRoot":"","sources":["../../src/archive/praypkg.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAK3D,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,eAAe,GAC5B,MAAM,CAuBR;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,GACtB,IAAI,CAgBN;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAGR;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,eAAe,EAC7B,UAAU,EAAE,MAAM,GACjB,IAAI,CAIN"}
|
package/dist/archive/praypkg.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { copyFileSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { basename, dirname, join, resolve } from "node:path";
|
|
5
5
|
import { PrayError } from "../errors.js";
|
|
6
6
|
import { findPrayspecFile } from "../package-spec/index.js";
|
|
7
|
+
import { MAX_ARCHIVE_TOTAL_BYTES } from "../resource-limits.js";
|
|
8
|
+
import { validateArchiveMemberPath } from "./path-safety.js";
|
|
9
|
+
import { extractTarArchive } from "./tar.js";
|
|
7
10
|
export function buildPackageArchiveBytes(packageEntry) {
|
|
8
11
|
const prayspecPath = findPrayspecFile(packageEntry.root);
|
|
9
12
|
const staging = mkdtempSync(join(tmpdir(), "pray-package-"));
|
|
@@ -23,14 +26,15 @@ export function buildPackageArchiveBytes(packageEntry) {
|
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
export function unpackPraypkg(artifactBytes, outputDirectory) {
|
|
26
|
-
|
|
29
|
+
if (artifactBytes.byteLength > MAX_ARCHIVE_TOTAL_BYTES) {
|
|
30
|
+
throw PrayError.integrity(`package archive exceeds ${MAX_ARCHIVE_TOTAL_BYTES} bytes`);
|
|
31
|
+
}
|
|
27
32
|
const tarBytes = runCommand("zstd", ["-d", "-q", "-c"], artifactBytes);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
if (result.status !== 0) {
|
|
32
|
-
throw PrayError.integrity("failed to unpack package archive");
|
|
33
|
+
if (tarBytes.byteLength > MAX_ARCHIVE_TOTAL_BYTES) {
|
|
34
|
+
throw PrayError.integrity(`package archive exceeds ${MAX_ARCHIVE_TOTAL_BYTES} decompressed bytes`);
|
|
33
35
|
}
|
|
36
|
+
extractTarArchive(tarBytes, outputDirectory);
|
|
37
|
+
rejectUnsafeExtractedTree(outputDirectory);
|
|
34
38
|
}
|
|
35
39
|
export function packageArchivePath(packageName, version) {
|
|
36
40
|
const slug = packageName.replaceAll("/", "-");
|
|
@@ -49,18 +53,40 @@ function packageMetadataJson(packageEntry) {
|
|
|
49
53
|
exports: packageEntry.selectedExports,
|
|
50
54
|
});
|
|
51
55
|
}
|
|
56
|
+
function rejectUnsafeExtractedTree(outputDirectory) {
|
|
57
|
+
const stack = [outputDirectory];
|
|
58
|
+
while (stack.length > 0) {
|
|
59
|
+
const current = stack.pop();
|
|
60
|
+
if (current === undefined) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
64
|
+
const fullPath = join(current, entry.name);
|
|
65
|
+
if (entry.isDirectory()) {
|
|
66
|
+
stack.push(fullPath);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (lstatSync(fullPath).isSymbolicLink()) {
|
|
70
|
+
throw PrayError.integrity("unsupported package archive entry type");
|
|
71
|
+
}
|
|
72
|
+
const relative = fullPath.slice(outputDirectory.length + 1);
|
|
73
|
+
validateArchiveMemberPath(relative);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
52
77
|
function runCommand(program, argumentsList, input) {
|
|
53
78
|
const result = spawnSync(program, argumentsList, {
|
|
54
79
|
input,
|
|
55
80
|
encoding: "buffer",
|
|
56
|
-
|
|
81
|
+
env: { ...process.env, COPYFILE_DISABLE: "1" },
|
|
82
|
+
maxBuffer: MAX_ARCHIVE_TOTAL_BYTES,
|
|
57
83
|
});
|
|
58
84
|
if (result.error?.code === "ENOENT") {
|
|
59
85
|
throw PrayError.unsupported(`${program} is required to build or unpack package archives`);
|
|
60
86
|
}
|
|
61
87
|
if (result.status !== 0) {
|
|
62
88
|
const message = result.stderr?.toString("utf8").trim();
|
|
63
|
-
throw PrayError.integrity(message.length > 0 ? message : `${program} failed`);
|
|
89
|
+
throw PrayError.integrity(message && message.length > 0 ? message : `${program} failed`);
|
|
64
90
|
}
|
|
65
91
|
return result.stdout;
|
|
66
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"praypkg.js","sourceRoot":"","sources":["../../src/archive/praypkg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,MAAM,EACN,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"praypkg.js","sourceRoot":"","sources":["../../src/archive/praypkg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/archive/tar.ts"],"names":[],"mappings":"AAYA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,IAAI,CAGN"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { PrayError } from "../errors.js";
|
|
4
|
+
import { MAX_ARCHIVE_ENTRIES, MAX_ARCHIVE_ENTRY_BYTES, MAX_ARCHIVE_TOTAL_BYTES, } from "../resource-limits.js";
|
|
5
|
+
import { validateArchiveMemberPath } from "./path-safety.js";
|
|
6
|
+
const TAR_BLOCK_BYTES = 512;
|
|
7
|
+
export function validateTarArchive(bytes) {
|
|
8
|
+
walkTarArchive(bytes);
|
|
9
|
+
}
|
|
10
|
+
export function extractTarArchive(bytes, outputDirectory) {
|
|
11
|
+
mkdirSync(outputDirectory, { recursive: true });
|
|
12
|
+
walkTarArchive(bytes, outputDirectory);
|
|
13
|
+
}
|
|
14
|
+
function walkTarArchive(bytes, outputDirectory) {
|
|
15
|
+
const paths = new Set();
|
|
16
|
+
let offset = 0;
|
|
17
|
+
let entryCount = 0;
|
|
18
|
+
let totalBytes = 0;
|
|
19
|
+
let pendingPath;
|
|
20
|
+
while (offset + TAR_BLOCK_BYTES <= bytes.length) {
|
|
21
|
+
const header = bytes.subarray(offset, offset + TAR_BLOCK_BYTES);
|
|
22
|
+
if (header.every((byte) => byte === 0))
|
|
23
|
+
return;
|
|
24
|
+
verifyChecksum(header);
|
|
25
|
+
const size = parseOctal(header.subarray(124, 136), "entry size");
|
|
26
|
+
const dataStart = offset + TAR_BLOCK_BYTES;
|
|
27
|
+
const dataEnd = dataStart + size;
|
|
28
|
+
if (dataEnd > bytes.length) {
|
|
29
|
+
throw PrayError.integrity("truncated package archive entry");
|
|
30
|
+
}
|
|
31
|
+
const type = String.fromCharCode(header[156] ?? 0);
|
|
32
|
+
const data = bytes.subarray(dataStart, dataEnd);
|
|
33
|
+
if (type === "x") {
|
|
34
|
+
pendingPath = paxPath(data);
|
|
35
|
+
}
|
|
36
|
+
else if (type === "L") {
|
|
37
|
+
pendingPath = cString(data).replace(/\n$/, "");
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const rawPath = pendingPath ?? tarHeaderPath(header);
|
|
41
|
+
pendingPath = undefined;
|
|
42
|
+
if (type === "5" && (rawPath === "." || rawPath === "./")) {
|
|
43
|
+
offset =
|
|
44
|
+
dataStart + Math.ceil(size / TAR_BLOCK_BYTES) * TAR_BLOCK_BYTES;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const path = validateArchiveMemberPath(rawPath);
|
|
48
|
+
if (basenameStartsWithAppleDouble(path)) {
|
|
49
|
+
offset =
|
|
50
|
+
dataStart + Math.ceil(size / TAR_BLOCK_BYTES) * TAR_BLOCK_BYTES;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (type === "5") {
|
|
54
|
+
if (outputDirectory !== undefined) {
|
|
55
|
+
mkdirSync(extractedDestination(outputDirectory, path), {
|
|
56
|
+
recursive: true,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (type !== "0" && type !== "\0") {
|
|
62
|
+
throw PrayError.integrity("unsupported package archive entry type");
|
|
63
|
+
}
|
|
64
|
+
entryCount += 1;
|
|
65
|
+
if (entryCount > MAX_ARCHIVE_ENTRIES) {
|
|
66
|
+
throw PrayError.integrity(`package archive exceeds ${MAX_ARCHIVE_ENTRIES} entries`);
|
|
67
|
+
}
|
|
68
|
+
if (paths.has(path)) {
|
|
69
|
+
throw PrayError.integrity(`duplicate package archive path: ${path}`);
|
|
70
|
+
}
|
|
71
|
+
paths.add(path);
|
|
72
|
+
if (size > MAX_ARCHIVE_ENTRY_BYTES) {
|
|
73
|
+
throw PrayError.integrity(`package archive entry exceeds ${MAX_ARCHIVE_ENTRY_BYTES} bytes: ${path}`);
|
|
74
|
+
}
|
|
75
|
+
totalBytes += size;
|
|
76
|
+
if (totalBytes > MAX_ARCHIVE_TOTAL_BYTES) {
|
|
77
|
+
throw PrayError.integrity(`package archive exceeds ${MAX_ARCHIVE_TOTAL_BYTES} decompressed bytes`);
|
|
78
|
+
}
|
|
79
|
+
if (outputDirectory !== undefined) {
|
|
80
|
+
const destination = extractedDestination(outputDirectory, path);
|
|
81
|
+
mkdirSync(dirname(destination), { recursive: true });
|
|
82
|
+
writeFileSync(destination, data, { flag: "wx" });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
offset = dataStart + Math.ceil(size / TAR_BLOCK_BYTES) * TAR_BLOCK_BYTES;
|
|
87
|
+
}
|
|
88
|
+
throw PrayError.integrity("package archive is missing its end marker");
|
|
89
|
+
}
|
|
90
|
+
function extractedDestination(outputDirectory, path) {
|
|
91
|
+
const destination = join(outputDirectory, path);
|
|
92
|
+
if (destination !== outputDirectory &&
|
|
93
|
+
!destination.startsWith(`${outputDirectory}/`) &&
|
|
94
|
+
!destination.startsWith(`${outputDirectory}\\`)) {
|
|
95
|
+
throw PrayError.integrity(`package path escapes package root: ${path}`);
|
|
96
|
+
}
|
|
97
|
+
return destination;
|
|
98
|
+
}
|
|
99
|
+
function basenameStartsWithAppleDouble(path) {
|
|
100
|
+
const parts = path.split(/[/\\]/);
|
|
101
|
+
const basename = parts[parts.length - 1] ?? "";
|
|
102
|
+
return basename.startsWith("._");
|
|
103
|
+
}
|
|
104
|
+
function verifyChecksum(header) {
|
|
105
|
+
const stored = parseOctal(header.subarray(148, 154), "checksum");
|
|
106
|
+
let sum = 0;
|
|
107
|
+
for (let index = 0; index < header.length; index += 1) {
|
|
108
|
+
sum += index >= 148 && index < 156 ? 32 : (header[index] ?? 0);
|
|
109
|
+
}
|
|
110
|
+
if (sum !== stored) {
|
|
111
|
+
throw PrayError.integrity("invalid package archive checksum");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function tarHeaderPath(header) {
|
|
115
|
+
const name = cString(header.subarray(0, 100));
|
|
116
|
+
const prefix = cString(header.subarray(345, 500));
|
|
117
|
+
return prefix.length > 0 ? `${prefix}/${name}` : name;
|
|
118
|
+
}
|
|
119
|
+
function cString(bytes) {
|
|
120
|
+
const end = bytes.indexOf(0);
|
|
121
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(end >= 0 ? bytes.subarray(0, end) : bytes);
|
|
122
|
+
}
|
|
123
|
+
function parseOctal(bytes, label) {
|
|
124
|
+
const value = cString(bytes).trim();
|
|
125
|
+
if (!/^[0-7]+$/.test(value)) {
|
|
126
|
+
throw PrayError.integrity(`invalid package archive ${label}`);
|
|
127
|
+
}
|
|
128
|
+
const parsed = Number.parseInt(value, 8);
|
|
129
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
130
|
+
throw PrayError.integrity(`invalid package archive ${label}`);
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
133
|
+
}
|
|
134
|
+
function paxPath(data) {
|
|
135
|
+
let cursor = 0;
|
|
136
|
+
let path;
|
|
137
|
+
while (cursor < data.length) {
|
|
138
|
+
const separator = data.indexOf(0x20, cursor);
|
|
139
|
+
const length = Number.parseInt(data.subarray(cursor, separator).toString("ascii"), 10);
|
|
140
|
+
const recordEnd = cursor + length;
|
|
141
|
+
if (separator < 0 ||
|
|
142
|
+
!Number.isSafeInteger(length) ||
|
|
143
|
+
length <= 0 ||
|
|
144
|
+
recordEnd > data.length) {
|
|
145
|
+
throw PrayError.integrity("invalid package archive pax header");
|
|
146
|
+
}
|
|
147
|
+
const record = data.subarray(separator + 1, recordEnd - 1);
|
|
148
|
+
const equals = record.indexOf(0x3d);
|
|
149
|
+
const key = equals < 0 ? "" : record.subarray(0, equals).toString("ascii");
|
|
150
|
+
if (key === "path") {
|
|
151
|
+
path = new TextDecoder("utf-8", { fatal: true }).decode(record.subarray(equals + 1));
|
|
152
|
+
}
|
|
153
|
+
cursor = recordEnd;
|
|
154
|
+
}
|
|
155
|
+
return path;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=tar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tar.js","sourceRoot":"","sources":["../../src/archive/tar.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/session.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface SessionFile {
|
|
|
5
5
|
kind: string;
|
|
6
6
|
signer_fingerprint?: string;
|
|
7
7
|
}
|
|
8
|
-
export declare function sessionFilePath(
|
|
8
|
+
export declare function sessionFilePath(_root: string): string;
|
|
9
9
|
export declare function persistSession(root: string, session: SessionFile): SessionFile;
|
|
10
10
|
export declare function loadSessions(path: string): SessionFile[] | undefined;
|
|
11
11
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAQD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,WAAW,CAiBb;AA2BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,SAAS,CAcpE"}
|
package/dist/auth/session.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { PrayError } from "../errors.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { trustHome } from "../trust/store.js";
|
|
5
|
+
export function sessionFilePath(_root) {
|
|
6
|
+
return join(trustHome(), "session.json");
|
|
6
7
|
}
|
|
7
8
|
export function persistSession(root, session) {
|
|
8
9
|
const path = sessionFilePath(root);
|
|
9
10
|
mkdirSync(join(path, ".."), { recursive: true });
|
|
11
|
+
migrateLegacySession(root, path);
|
|
10
12
|
const sessions = loadSessions(path) ?? [];
|
|
11
13
|
const existingIndex = sessions.findIndex((entry) => entry.server_url === session.server_url);
|
|
12
14
|
if (existingIndex >= 0) {
|
|
@@ -16,9 +18,32 @@ export function persistSession(root, session) {
|
|
|
16
18
|
sessions.push(session);
|
|
17
19
|
}
|
|
18
20
|
const document = sessions.length === 1 ? sessions[0] : { sessions };
|
|
19
|
-
|
|
21
|
+
writeSessionDocument(path, document);
|
|
20
22
|
return session;
|
|
21
23
|
}
|
|
24
|
+
function migrateLegacySession(root, path) {
|
|
25
|
+
const legacyPath = join(root, ".pray", "session.json");
|
|
26
|
+
if (!existsSync(legacyPath) || legacyPath === path)
|
|
27
|
+
return;
|
|
28
|
+
const sessions = loadSessions(path) ?? [];
|
|
29
|
+
for (const legacy of loadSessions(legacyPath) ?? []) {
|
|
30
|
+
if (!sessions.some((entry) => entry.server_url === legacy.server_url)) {
|
|
31
|
+
sessions.push(legacy);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const document = sessions.length === 1 ? sessions[0] : { sessions };
|
|
35
|
+
writeSessionDocument(path, document);
|
|
36
|
+
rmSync(legacyPath);
|
|
37
|
+
}
|
|
38
|
+
function writeSessionDocument(path, document) {
|
|
39
|
+
const temporaryPath = `${path}.tmp-${process.pid}`;
|
|
40
|
+
writeFileSync(temporaryPath, `${JSON.stringify(document, null, 2)}\n`, {
|
|
41
|
+
encoding: "utf8",
|
|
42
|
+
mode: 0o600,
|
|
43
|
+
});
|
|
44
|
+
chmodSync(temporaryPath, 0o600);
|
|
45
|
+
renameSync(temporaryPath, path);
|
|
46
|
+
}
|
|
22
47
|
export function loadSessions(path) {
|
|
23
48
|
if (!existsSync(path)) {
|
|
24
49
|
return undefined;
|
package/dist/auth/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../src/http/body.ts"],"names":[],"mappings":"AAGA,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,MAAgC,GACzC,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { PrayError } from "../errors.js";
|
|
2
|
+
import { MAX_HTTP_RESPONSE_BYTES } from "../resource-limits.js";
|
|
3
|
+
export async function readBoundedHttpBody(response, maxBytes = MAX_HTTP_RESPONSE_BYTES) {
|
|
4
|
+
const declared = response.headers.get("content-length");
|
|
5
|
+
if (declared !== null) {
|
|
6
|
+
const length = Number(declared);
|
|
7
|
+
if (Number.isFinite(length) && length > maxBytes) {
|
|
8
|
+
throw PrayError.resolution(`HTTP response exceeds ${maxBytes} bytes`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
if (response.body === null) {
|
|
12
|
+
return Buffer.alloc(0);
|
|
13
|
+
}
|
|
14
|
+
const reader = response.body.getReader();
|
|
15
|
+
const chunks = [];
|
|
16
|
+
let length = 0;
|
|
17
|
+
for (;;) {
|
|
18
|
+
const { done, value } = await reader.read();
|
|
19
|
+
if (done) {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
const bytes = Buffer.from(value);
|
|
23
|
+
length += bytes.byteLength;
|
|
24
|
+
if (length > maxBytes) {
|
|
25
|
+
await reader.cancel();
|
|
26
|
+
throw PrayError.resolution(`HTTP response exceeds ${maxBytes} bytes`);
|
|
27
|
+
}
|
|
28
|
+
chunks.push(bytes);
|
|
29
|
+
}
|
|
30
|
+
return Buffer.concat(chunks, length);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/http/body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAkB,EAClB,WAAmB,uBAAuB;IAE1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACxD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;YACjD,MAAM,SAAS,CAAC,UAAU,CAAC,yBAAyB,QAAQ,QAAQ,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,SAAS,CAAC;QACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC;QAC3B,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;YACtB,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,SAAS,CAAC,UAAU,CAAC,yBAAyB,QAAQ,QAAQ,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AAGA,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ1D;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE9D;AAED,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D"}
|
package/dist/http/client.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { PrayError } from "../errors.js";
|
|
2
|
+
import { readBoundedHttpBody } from "./body.js";
|
|
2
3
|
export async function httpGet(url) {
|
|
3
4
|
const response = await fetch(url);
|
|
4
5
|
if (!response.ok) {
|
|
5
6
|
throw PrayError.resolution(`HTTP request failed for ${url}: ${response.status}`);
|
|
6
7
|
}
|
|
7
|
-
return
|
|
8
|
+
return readBoundedHttpBody(response);
|
|
8
9
|
}
|
|
9
10
|
export async function httpGetText(url) {
|
|
10
11
|
return (await httpGet(url)).toString("utf8");
|
|
@@ -28,7 +29,7 @@ export async function httpPostJson(url, contentType, body) {
|
|
|
28
29
|
headers: { "Content-Type": contentType },
|
|
29
30
|
body: typeof body === "string" ? body : new Uint8Array(body),
|
|
30
31
|
});
|
|
31
|
-
const responseBody =
|
|
32
|
+
const responseBody = await readBoundedHttpBody(response);
|
|
32
33
|
if (!response.ok) {
|
|
33
34
|
throw PrayError.resolution(`HTTP request failed for ${url}: ${response.status}: ${responseBody.toString("utf8")}`);
|
|
34
35
|
}
|
package/dist/http/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"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"}
|
package/dist/lockfile/types.d.ts
CHANGED
|
@@ -44,6 +44,6 @@ export interface Lockfile {
|
|
|
44
44
|
managed_span: ManagedSpanRecord[];
|
|
45
45
|
}
|
|
46
46
|
export declare function canonicalLockfile(lockfile: Lockfile): Lockfile;
|
|
47
|
-
export declare const PACKAGE_VERSION = "1.9.
|
|
48
|
-
export declare const GENERATED_BY = "pray 1.9.
|
|
47
|
+
export declare const PACKAGE_VERSION = "1.9.2";
|
|
48
|
+
export declare const GENERATED_BY = "pray 1.9.2 (typescript)";
|
|
49
49
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/lockfile/types.js
CHANGED
|
@@ -11,6 +11,6 @@ export function canonicalLockfile(lockfile) {
|
|
|
11
11
|
left.id.localeCompare(right.id)),
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
-
export const PACKAGE_VERSION = "1.9.
|
|
14
|
+
export const PACKAGE_VERSION = "1.9.2";
|
|
15
15
|
export const GENERATED_BY = `pray ${PACKAGE_VERSION} (typescript)`;
|
|
16
16
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAGpB,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAiB7D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAIpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAGvD;AAED,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,CAAC"}
|
package/dist/manifest/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { PrayError } from "../errors.js";
|
|
|
3
3
|
import { sha256Prefixed } from "../hashing.js";
|
|
4
4
|
import { parseManifestText } from "./parser.js";
|
|
5
5
|
import { canonicalManifest, defaultRenderPolicy, manifestToJson, } from "./types.js";
|
|
6
|
+
import { validateManifestPaths } from "./validate.js";
|
|
6
7
|
export function readManifestText(manifestPath) {
|
|
7
8
|
try {
|
|
8
9
|
return readFileSync(manifestPath, "utf8");
|
|
@@ -19,7 +20,9 @@ export function readManifestText(manifestPath) {
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
export function parseManifest(text) {
|
|
22
|
-
|
|
23
|
+
const manifest = parseManifestText(text);
|
|
24
|
+
validateManifestPaths(manifest);
|
|
25
|
+
return manifest;
|
|
23
26
|
}
|
|
24
27
|
export function manifestHash(manifest) {
|
|
25
28
|
const bytes = Buffer.from(JSON.stringify(manifestToJson(manifest)), "utf8");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EAMnB,cAAc,GAEf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EAMnB,cAAc,GAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,MAAM,IAAI,KAAK;YACf,KAAK,CAAC,IAAI,KAAK,QAAQ,EACvB,CAAC;YACD,MAAM,SAAS,CAAC,QAAQ,CACtB,WAAW,YAAY,+BAA+B,CACvD,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAEjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GAOpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/manifest/validate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAgB9D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBjE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { isAbsolute, win32 } from "node:path";
|
|
2
|
+
import { PrayError } from "../errors.js";
|
|
3
|
+
export function validateManifestPaths(manifest) {
|
|
4
|
+
for (const target of manifest.targets) {
|
|
5
|
+
for (const path of [
|
|
6
|
+
...target.outputs,
|
|
7
|
+
...target.skills,
|
|
8
|
+
...target.commands,
|
|
9
|
+
...target.rules,
|
|
10
|
+
]) {
|
|
11
|
+
validateProjectRelativePath(path);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
for (const packageEntry of manifest.packages) {
|
|
15
|
+
if (packageEntry.path)
|
|
16
|
+
validateProjectRelativePath(packageEntry.path);
|
|
17
|
+
if (packageEntry.file)
|
|
18
|
+
validateProjectRelativePath(packageEntry.file);
|
|
19
|
+
}
|
|
20
|
+
for (const local of manifest.local)
|
|
21
|
+
validateProjectRelativePath(local.path);
|
|
22
|
+
}
|
|
23
|
+
export function validateProjectRelativePath(value) {
|
|
24
|
+
const path = value.trim();
|
|
25
|
+
if (path.length === 0 || isAbsolute(path) || win32.isAbsolute(path)) {
|
|
26
|
+
throw PrayError.manifest(`project path must be repository-relative: ${value}`);
|
|
27
|
+
}
|
|
28
|
+
const parts = path.replaceAll("\\", "/").split("/");
|
|
29
|
+
if (parts.includes("..") || path.includes("\0")) {
|
|
30
|
+
throw PrayError.manifest(`project path escapes repository root: ${value}`);
|
|
31
|
+
}
|
|
32
|
+
if (parts.every((part) => part.length === 0 || part === ".")) {
|
|
33
|
+
throw PrayError.manifest(`project path must be repository-relative: ${value}`);
|
|
34
|
+
}
|
|
35
|
+
return path;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/manifest/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,MAAM,UAAU,qBAAqB,CAAC,QAAkB;IACtD,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI;YACjB,GAAG,MAAM,CAAC,OAAO;YACjB,GAAG,MAAM,CAAC,MAAM;YAChB,GAAG,MAAM,CAAC,QAAQ;YAClB,GAAG,MAAM,CAAC,KAAK;SAChB,EAAE,CAAC;YACF,2BAA2B,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,YAAY,CAAC,IAAI;YAAE,2BAA2B,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,YAAY,CAAC,IAAI;YAAE,2BAA2B,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,KAAK;QAAE,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,MAAM,SAAS,CAAC,QAAQ,CACtB,6CAA6C,KAAK,EAAE,CACrD,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,SAAS,CAAC,QAAQ,CAAC,yCAAyC,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,SAAS,CAAC,QAAQ,CACtB,6CAA6C,KAAK,EAAE,CACrD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|