@procedures/archive 0.0.0-stage → 0.3.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/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +95 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +15 -0
- package/dist/errors.js.map +1 -0
- package/dist/format.d.ts +25 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +60 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +34 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +148 -0
- package/dist/module.js.map +1 -0
- package/dist/paths.d.ts +58 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +205 -0
- package/dist/paths.js.map +1 -0
- package/dist/procedures/archive/create.d.ts +14 -0
- package/dist/procedures/archive/create.d.ts.map +1 -0
- package/dist/procedures/archive/create.js +81 -0
- package/dist/procedures/archive/create.js.map +1 -0
- package/dist/procedures/archive/extract.d.ts +17 -0
- package/dist/procedures/archive/extract.d.ts.map +1 -0
- package/dist/procedures/archive/extract.js +101 -0
- package/dist/procedures/archive/extract.js.map +1 -0
- package/dist/procedures/archive/index.d.ts +4 -0
- package/dist/procedures/archive/index.d.ts.map +1 -0
- package/dist/procedures/archive/index.js +4 -0
- package/dist/procedures/archive/index.js.map +1 -0
- package/dist/procedures/archive/list.d.ts +15 -0
- package/dist/procedures/archive/list.d.ts.map +1 -0
- package/dist/procedures/archive/list.js +47 -0
- package/dist/procedures/archive/list.js.map +1 -0
- package/dist/register.d.ts +6 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +8 -0
- package/dist/register.js.map +1 -0
- package/dist/tar.d.ts +38 -0
- package/dist/tar.d.ts.map +1 -0
- package/dist/tar.js +193 -0
- package/dist/tar.js.map +1 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/walk.d.ts +34 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +67 -0
- package/dist/walk.js.map +1 -0
- package/dist/zip.d.ts +57 -0
- package/dist/zip.d.ts.map +1 -0
- package/dist/zip.js +397 -0
- package/dist/zip.js.map +1 -0
- package/package.json +77 -3
- package/src/errors.ts +33 -0
- package/src/format.ts +64 -0
- package/src/index.ts +9 -0
- package/src/module.ts +192 -0
- package/src/paths.ts +230 -0
- package/src/procedures/archive/create.ts +84 -0
- package/src/procedures/archive/extract.ts +103 -0
- package/src/procedures/archive/index.ts +3 -0
- package/src/procedures/archive/list.ts +50 -0
- package/src/register.ts +10 -0
- package/src/tar.ts +198 -0
- package/src/types.ts +101 -0
- package/src/walk.ts +85 -0
- package/src/zip.ts +419 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The errors of the archive procedures.
|
|
3
|
+
*/
|
|
4
|
+
/** The reason of an `ArchiveError`. */
|
|
5
|
+
export type ArchiveErrorCode =
|
|
6
|
+
/** The format is not known, or it is not the format of the file. */
|
|
7
|
+
"BAD_FORMAT"
|
|
8
|
+
/** The archive is damaged, or it uses a feature that the package does not read. */
|
|
9
|
+
| "BAD_ARCHIVE"
|
|
10
|
+
/** A path exists already: the archive of `create`, or a file of `extract` without `overwrite`. */
|
|
11
|
+
| "EXISTS"
|
|
12
|
+
/** A path of the input or an entry of the archive is not safe: `..`, an absolute path, or a way through a link. */
|
|
13
|
+
| "UNSAFE_PATH"
|
|
14
|
+
/** A link of the archive goes out of the target folder, or a hard link names no file of the archive. */
|
|
15
|
+
| "UNSAFE_LINK"
|
|
16
|
+
/** The archive has an entry that the package does not extract: a device, a FIFO or another special file. */
|
|
17
|
+
| "UNSUPPORTED_ENTRY"
|
|
18
|
+
/** The archive has more entries or more bytes than the limits of the module. */
|
|
19
|
+
| "TOO_LARGE";
|
|
20
|
+
/** An error of an archive procedure. `entry` names the entry of the archive, when one is the cause. */
|
|
21
|
+
export declare class ArchiveError extends Error {
|
|
22
|
+
readonly name = "ArchiveError";
|
|
23
|
+
readonly code: ArchiveErrorCode;
|
|
24
|
+
readonly entry: string | undefined;
|
|
25
|
+
constructor(code: ArchiveErrorCode, message: string, entry?: string);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,MAAM,MAAM,gBAAgB;AAC1B,oEAAoE;AAClE,YAAY;AACd,mFAAmF;GACjF,aAAa;AACf,kGAAkG;GAChG,QAAQ;AACV,mHAAmH;GACjH,aAAa;AACf,wGAAwG;GACtG,aAAa;AACf,4GAA4G;GAC1G,mBAAmB;AACrB,gFAAgF;GAC9E,WAAW,CAAC;AAEhB,uGAAuG;AACvG,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAkB,IAAI,kBAAkB;IACxC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC,YAAY,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAIlE;CACF"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The errors of the archive procedures.
|
|
3
|
+
*/
|
|
4
|
+
/** An error of an archive procedure. `entry` names the entry of the archive, when one is the cause. */
|
|
5
|
+
export class ArchiveError extends Error {
|
|
6
|
+
name = "ArchiveError";
|
|
7
|
+
code;
|
|
8
|
+
entry;
|
|
9
|
+
constructor(code, message, entry) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.entry = entry;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,uGAAuG;AACvG,MAAM,OAAO,YAAa,SAAQ,KAAK;IACnB,IAAI,GAAG,cAAc,CAAC;IAC/B,IAAI,CAAmB;IACvB,KAAK,CAAqB;IAEnC,YAAY,IAAsB,EAAE,OAAe,EAAE,KAAc;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The format of an archive: from the name of a new archive, or from the first bytes of a file.
|
|
3
|
+
* And the limits of the module.
|
|
4
|
+
*/
|
|
5
|
+
import type { ArchiveFormat } from "./types.js";
|
|
6
|
+
/** The limits of the procedures of a module. */
|
|
7
|
+
export interface ArchiveSettings {
|
|
8
|
+
/** The most bytes of the files of one archive: `extract` and `create` refuse more. */
|
|
9
|
+
readonly maxBytes: number;
|
|
10
|
+
/** The most entries of one archive. */
|
|
11
|
+
readonly maxEntries: number;
|
|
12
|
+
}
|
|
13
|
+
/** The default most bytes: 1 GiB. */
|
|
14
|
+
export declare const DEFAULT_MAX_BYTES: number;
|
|
15
|
+
/** The default most entries. */
|
|
16
|
+
export declare const DEFAULT_MAX_ENTRIES = 100000;
|
|
17
|
+
/** The settings of the default module. */
|
|
18
|
+
export declare const DEFAULT_ARCHIVE_SETTINGS: ArchiveSettings;
|
|
19
|
+
/** The format of a new archive from its name, or the format of the input. */
|
|
20
|
+
export declare function formatOfName(path: string, given: ArchiveFormat | undefined): ArchiveFormat;
|
|
21
|
+
/** The format that the first bytes of a file show, or undefined. */
|
|
22
|
+
export declare function sniffFormat(path: string): Promise<ArchiveFormat | undefined>;
|
|
23
|
+
/** The format of an existing archive: its first bytes, which must agree with the format of the input. */
|
|
24
|
+
export declare function formatOfFile(path: string, given: ArchiveFormat | undefined): Promise<ArchiveFormat>;
|
|
25
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,EAAE,MAA2B,CAAC;AAC5D,gCAAgC;AAChC,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,0CAA0C;AAC1C,eAAO,MAAM,wBAAwB,EAAE,eAAiG,CAAC;AAEzI,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,aAAa,CAO1F;AAED,oEAAoE;AACpE,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAclF;AAED,yGAAyG;AACzG,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,CAUzG"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The format of an archive: from the name of a new archive, or from the first bytes of a file.
|
|
3
|
+
* And the limits of the module.
|
|
4
|
+
*/
|
|
5
|
+
import { open } from "node:fs/promises";
|
|
6
|
+
import { ArchiveError } from "./errors.js";
|
|
7
|
+
/** The default most bytes: 1 GiB. */
|
|
8
|
+
export const DEFAULT_MAX_BYTES = 1024 * 1024 * 1024;
|
|
9
|
+
/** The default most entries. */
|
|
10
|
+
export const DEFAULT_MAX_ENTRIES = 100_000;
|
|
11
|
+
/** The settings of the default module. */
|
|
12
|
+
export const DEFAULT_ARCHIVE_SETTINGS = Object.freeze({ maxBytes: DEFAULT_MAX_BYTES, maxEntries: DEFAULT_MAX_ENTRIES });
|
|
13
|
+
/** The format of a new archive from its name, or the format of the input. */
|
|
14
|
+
export function formatOfName(path, given) {
|
|
15
|
+
if (given !== undefined)
|
|
16
|
+
return given;
|
|
17
|
+
const name = path.toLowerCase();
|
|
18
|
+
if (name.endsWith(".tar.gz") || name.endsWith(".tgz"))
|
|
19
|
+
return "tar.gz";
|
|
20
|
+
if (name.endsWith(".tar"))
|
|
21
|
+
return "tar";
|
|
22
|
+
if (name.endsWith(".zip"))
|
|
23
|
+
return "zip";
|
|
24
|
+
throw new ArchiveError("BAD_FORMAT", `The name ${path} does not tell the format: give format, or end the name with .tar.gz, .tgz, .tar or .zip`);
|
|
25
|
+
}
|
|
26
|
+
/** The format that the first bytes of a file show, or undefined. */
|
|
27
|
+
export async function sniffFormat(path) {
|
|
28
|
+
const handle = await open(path, "r");
|
|
29
|
+
try {
|
|
30
|
+
const head = Buffer.alloc(512);
|
|
31
|
+
const { bytesRead } = await handle.read(head, 0, 512, 0);
|
|
32
|
+
if (bytesRead >= 2 && head[0] === 0x1f && head[1] === 0x8b)
|
|
33
|
+
return "tar.gz";
|
|
34
|
+
if (bytesRead >= 4 && head[0] === 0x50 && head[1] === 0x4b && ((head[2] === 3 && head[3] === 4) || (head[2] === 5 && head[3] === 6)))
|
|
35
|
+
return "zip";
|
|
36
|
+
if (bytesRead >= 262 && head.toString("latin1", 257, 262) === "ustar")
|
|
37
|
+
return "tar";
|
|
38
|
+
// An empty tar: zero blocks without a header
|
|
39
|
+
if (bytesRead === 512 && head.every((byte) => byte === 0))
|
|
40
|
+
return "tar";
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await handle.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** The format of an existing archive: its first bytes, which must agree with the format of the input. */
|
|
48
|
+
export async function formatOfFile(path, given) {
|
|
49
|
+
const found = await sniffFormat(path);
|
|
50
|
+
if (found === undefined) {
|
|
51
|
+
if (given === "tar")
|
|
52
|
+
return "tar";
|
|
53
|
+
throw new ArchiveError("BAD_FORMAT", `${path} is not a tar.gz, tar or zip archive`);
|
|
54
|
+
}
|
|
55
|
+
if (given !== undefined && given !== found) {
|
|
56
|
+
throw new ArchiveError("BAD_FORMAT", `${path} is a ${found} archive, not a ${given} archive`);
|
|
57
|
+
}
|
|
58
|
+
return found;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAW,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5D,gCAAgC;AAChC,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAoB,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAEzI,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAgC;IACzE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,IAAI,YAAY,CAAC,YAAY,EAAE,YAAY,IAAI,0FAA0F,CAAC,CAAC;AACnJ,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;QAC5E,IAAI,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACnJ,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;QACpF,6CAA6C;QAC7C,IAAI,SAAS,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,KAAgC;IAC/E,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,KAAK,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAClC,MAAM,IAAI,YAAY,CAAC,YAAY,EAAE,GAAG,IAAI,sCAAsC,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC3C,MAAM,IAAI,YAAY,CAAC,YAAY,EAAE,GAAG,IAAI,SAAS,KAAK,mBAAmB,KAAK,UAAU,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./module.js";
|
|
2
|
+
export * from "./types.js";
|
|
3
|
+
export { archiveCreate, archiveExtract, archiveList } from "./procedures/archive/index.js";
|
|
4
|
+
export { ArchiveError, type ArchiveErrorCode } from "./errors.js";
|
|
5
|
+
export { DEFAULT_ARCHIVE_SETTINGS, DEFAULT_MAX_BYTES, DEFAULT_MAX_ENTRIES, formatOfFile, formatOfName, sniffFormat, type ArchiveSettings } from "./format.js";
|
|
6
|
+
export { entryParts, isAbsoluteName, planExtract, type PlanOptions, type PlannedEntry, type RawEntry } from "./paths.js";
|
|
7
|
+
export { crc32, readZipDirectory, writeZip, type ZipEntry, type ZipWriteEntry } from "./zip.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE3F,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9J,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AACzH,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// The root registers nothing: import "<package>/register", or give the module to createRegistry()
|
|
2
|
+
export * from "./module.js";
|
|
3
|
+
export * from "./types.js";
|
|
4
|
+
export { archiveCreate, archiveExtract, archiveList } from "./procedures/archive/index.js";
|
|
5
|
+
// The checks and the formats (roadmap R46)
|
|
6
|
+
export { ArchiveError } from "./errors.js";
|
|
7
|
+
export { DEFAULT_ARCHIVE_SETTINGS, DEFAULT_MAX_BYTES, DEFAULT_MAX_ENTRIES, formatOfFile, formatOfName, sniffFormat } from "./format.js";
|
|
8
|
+
export { entryParts, isAbsoluteName, planExtract } from "./paths.js";
|
|
9
|
+
export { crc32, readZipDirectory, writeZip } from "./zip.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC3F,2CAA2C;AAC3C,OAAO,EAAE,YAAY,EAAyB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAwB,MAAM,aAAa,CAAC;AAC9J,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAsD,MAAM,YAAY,CAAC;AACzH,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAqC,MAAM,UAAU,CAAC"}
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The procedures of @procedures/archive as data. Importing this file registers nothing.
|
|
3
|
+
*
|
|
4
|
+
* Scaffold a procedure with: mark procedure new <name> --path packages/archive
|
|
5
|
+
*
|
|
6
|
+
* `archiveModule` has the default limits: 1 GiB of files and 100000 entries in one archive.
|
|
7
|
+
* `createArchiveModule()` gives the same procedures with other limits (roadmap R46).
|
|
8
|
+
*/
|
|
9
|
+
import { type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
|
|
10
|
+
/**
|
|
11
|
+
* The module of this package, for `createRegistry()`: its procedures as data, with the default
|
|
12
|
+
* limits. Importing this file registers nothing.
|
|
13
|
+
*/
|
|
14
|
+
export declare const archiveModule: ProcedureModule;
|
|
15
|
+
export default archiveModule;
|
|
16
|
+
/** The options of `createArchiveModule()`. */
|
|
17
|
+
export interface ArchiveModuleOptions {
|
|
18
|
+
/** The most bytes of the files of one archive. The default is 1 GiB. */
|
|
19
|
+
readonly maxBytes?: number | undefined;
|
|
20
|
+
/** The most entries of one archive. The default is 100000. */
|
|
21
|
+
readonly maxEntries?: number | undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* This function gives the module of this package with other limits. Without options, it gives
|
|
25
|
+
* `archiveModule`. A host gives it to `createRegistry()` before its bundles, so it replaces the
|
|
26
|
+
* `archiveModule` that a bundle requires (the first module of a name counts).
|
|
27
|
+
*/
|
|
28
|
+
export declare function createArchiveModule(options?: ArchiveModuleOptions): ProcedureModule;
|
|
29
|
+
/**
|
|
30
|
+
* This function registers the procedures of @procedures/archive in a registry. The default is the
|
|
31
|
+
* global registry. The options are the options of `createArchiveModule()`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerArchiveProcedures(registry?: ProcedureRegistry, options?: ArchiveModuleOptions): void;
|
|
34
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAQL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAoI5B;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,eAAkG,CAAC;eAEhH,aAAa;AAE5B,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,CAUvF;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,GAAE,iBAAsC,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAEpI"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The procedures of @procedures/archive as data. Importing this file registers nothing.
|
|
3
|
+
*
|
|
4
|
+
* Scaffold a procedure with: mark procedure new <name> --path packages/archive
|
|
5
|
+
*
|
|
6
|
+
* `archiveModule` has the default limits: 1 GiB of files and 100000 entries in one archive.
|
|
7
|
+
* `createArchiveModule()` gives the same procedures with other limits (roadmap R46).
|
|
8
|
+
*/
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { defineModule, registerModules, PROCEDURE_REGISTRY, createProcedure, zodAdapter, } from "@procedures/client";
|
|
11
|
+
import { archiveCreate } from "./procedures/archive/create.js";
|
|
12
|
+
import { archiveExtract } from "./procedures/archive/extract.js";
|
|
13
|
+
import { archiveList } from "./procedures/archive/list.js";
|
|
14
|
+
import { DEFAULT_ARCHIVE_SETTINGS } from "./format.js";
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Schemas
|
|
17
|
+
// =============================================================================
|
|
18
|
+
const path = (description) => z.string().min(1).max(4096).describe(description);
|
|
19
|
+
const format = z.enum(["tar.gz", "tar", "zip"]);
|
|
20
|
+
const ArchiveCreateInputSchema = z.object({
|
|
21
|
+
output: path("The archive to make"),
|
|
22
|
+
source: path("A folder: the archive gets its content").optional(),
|
|
23
|
+
files: z.array(z.string().min(1).max(4096)).min(1).max(10_000).optional().describe("Files and folders, relative to cwd. A folder goes in with its content"),
|
|
24
|
+
cwd: path("The base folder of files (default: the working folder)").optional(),
|
|
25
|
+
format: format.optional().describe("The format (default: from the name of output: .tar.gz, .tgz, .tar or .zip)"),
|
|
26
|
+
overwrite: z.boolean().optional().describe("True: replace an existing archive (default false)"),
|
|
27
|
+
});
|
|
28
|
+
const ArchiveCreateOutputSchema = z.object({
|
|
29
|
+
path: z.string().describe("The absolute path of the archive"),
|
|
30
|
+
format,
|
|
31
|
+
entries: z.number().int().describe("The number of entries: files, folders and links"),
|
|
32
|
+
bytes: z.number().int().describe("The size of the archive, in bytes"),
|
|
33
|
+
});
|
|
34
|
+
const ArchiveExtractInputSchema = z.object({
|
|
35
|
+
archive: path("The archive"),
|
|
36
|
+
target: path("The folder that gets the content. The procedure makes it"),
|
|
37
|
+
format: format.optional().describe("The format (default: from the first bytes of the archive)"),
|
|
38
|
+
overwrite: z.boolean().optional().describe("True: replace an existing file (default false: an existing file is an error, and nothing changes)"),
|
|
39
|
+
});
|
|
40
|
+
const ArchiveExtractOutputSchema = z.object({
|
|
41
|
+
target: z.string().describe("The absolute path of the target folder"),
|
|
42
|
+
format,
|
|
43
|
+
files: z.number().int(),
|
|
44
|
+
directories: z.number().int(),
|
|
45
|
+
links: z.number().int().describe("The symbolic links and the hard links"),
|
|
46
|
+
bytes: z.number().int().describe("The bytes of the files"),
|
|
47
|
+
});
|
|
48
|
+
const ArchiveListInputSchema = z.object({
|
|
49
|
+
archive: path("The archive"),
|
|
50
|
+
format: format.optional().describe("The format (default: from the first bytes of the archive)"),
|
|
51
|
+
});
|
|
52
|
+
const ArchiveListOutputSchema = z.object({
|
|
53
|
+
format,
|
|
54
|
+
entries: z.array(z.object({
|
|
55
|
+
path: z.string().describe("The path in the archive"),
|
|
56
|
+
kind: z.enum(["file", "directory", "symlink", "hardlink", "other"]),
|
|
57
|
+
size: z.number().int(),
|
|
58
|
+
mode: z.number().int().optional(),
|
|
59
|
+
mtime: z.string().optional().describe("The time of the last change, as an ISO text"),
|
|
60
|
+
linkTarget: z.string().optional().describe("The target of a link"),
|
|
61
|
+
})),
|
|
62
|
+
bytes: z.number().int().describe("The sum of the sizes of the files"),
|
|
63
|
+
});
|
|
64
|
+
// =============================================================================
|
|
65
|
+
// Procedures
|
|
66
|
+
// =============================================================================
|
|
67
|
+
/** The effects of `create` and `extract`: they read and write files, and `overwrite` replaces a file. */
|
|
68
|
+
const READS_WRITES_FS = Object.freeze({ reads: Object.freeze(["fs"]), writes: Object.freeze(["fs"]) });
|
|
69
|
+
/** The effects of `list`: it reads a file and changes nothing. */
|
|
70
|
+
const READS_FS = Object.freeze({ reads: Object.freeze(["fs"]), writes: Object.freeze([]) });
|
|
71
|
+
/** The three procedures, with handlers that use the limits. */
|
|
72
|
+
function archiveProcedures(settings) {
|
|
73
|
+
const archiveCreateProcedure = createProcedure()
|
|
74
|
+
.path(["archive", "create"])
|
|
75
|
+
.input(zodAdapter(ArchiveCreateInputSchema))
|
|
76
|
+
.output(zodAdapter(ArchiveCreateOutputSchema))
|
|
77
|
+
.meta({
|
|
78
|
+
description: "Make a tar.gz or zip archive of a folder or of files",
|
|
79
|
+
tags: ["archive", "fs"],
|
|
80
|
+
args: ["output"],
|
|
81
|
+
shorts: { source: "s", format: "f" },
|
|
82
|
+
output: "json",
|
|
83
|
+
effects: READS_WRITES_FS,
|
|
84
|
+
})
|
|
85
|
+
.handler(async (input) => archiveCreate(input, settings))
|
|
86
|
+
.build();
|
|
87
|
+
const archiveExtractProcedure = createProcedure()
|
|
88
|
+
.path(["archive", "extract"])
|
|
89
|
+
.input(zodAdapter(ArchiveExtractInputSchema))
|
|
90
|
+
.output(zodAdapter(ArchiveExtractOutputSchema))
|
|
91
|
+
.meta({
|
|
92
|
+
description: "Extract a tar.gz or zip archive into a folder, with a check of each path",
|
|
93
|
+
tags: ["archive", "fs"],
|
|
94
|
+
args: ["archive", "target"],
|
|
95
|
+
shorts: { format: "f" },
|
|
96
|
+
output: "json",
|
|
97
|
+
effects: READS_WRITES_FS,
|
|
98
|
+
})
|
|
99
|
+
.handler(async (input) => archiveExtract(input, settings))
|
|
100
|
+
.build();
|
|
101
|
+
const archiveListProcedure = createProcedure()
|
|
102
|
+
.path(["archive", "list"])
|
|
103
|
+
.input(zodAdapter(ArchiveListInputSchema))
|
|
104
|
+
.output(zodAdapter(ArchiveListOutputSchema))
|
|
105
|
+
.meta({
|
|
106
|
+
description: "The entries of a tar.gz or zip archive",
|
|
107
|
+
tags: ["archive", "fs"],
|
|
108
|
+
args: ["archive"],
|
|
109
|
+
shorts: { format: "f" },
|
|
110
|
+
output: "json",
|
|
111
|
+
effects: READS_FS,
|
|
112
|
+
})
|
|
113
|
+
.handler(async (input) => archiveList(input, settings))
|
|
114
|
+
.build();
|
|
115
|
+
return [archiveCreateProcedure, archiveExtractProcedure, archiveListProcedure];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The module of this package, for `createRegistry()`: its procedures as data, with the default
|
|
119
|
+
* limits. Importing this file registers nothing.
|
|
120
|
+
*/
|
|
121
|
+
export const archiveModule = defineModule("@procedures/archive", archiveProcedures(DEFAULT_ARCHIVE_SETTINGS));
|
|
122
|
+
export default archiveModule;
|
|
123
|
+
/**
|
|
124
|
+
* This function gives the module of this package with other limits. Without options, it gives
|
|
125
|
+
* `archiveModule`. A host gives it to `createRegistry()` before its bundles, so it replaces the
|
|
126
|
+
* `archiveModule` that a bundle requires (the first module of a name counts).
|
|
127
|
+
*/
|
|
128
|
+
export function createArchiveModule(options = {}) {
|
|
129
|
+
if (Object.values(options).every((value) => value === undefined))
|
|
130
|
+
return archiveModule;
|
|
131
|
+
const settings = {
|
|
132
|
+
maxBytes: options.maxBytes ?? DEFAULT_ARCHIVE_SETTINGS.maxBytes,
|
|
133
|
+
maxEntries: options.maxEntries ?? DEFAULT_ARCHIVE_SETTINGS.maxEntries,
|
|
134
|
+
};
|
|
135
|
+
for (const [name, value] of Object.entries(settings)) {
|
|
136
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
137
|
+
throw new TypeError(`createArchiveModule: ${name} must be a whole number of 0 or more`);
|
|
138
|
+
}
|
|
139
|
+
return defineModule("@procedures/archive", archiveProcedures(settings));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* This function registers the procedures of @procedures/archive in a registry. The default is the
|
|
143
|
+
* global registry. The options are the options of `createArchiveModule()`.
|
|
144
|
+
*/
|
|
145
|
+
export function registerArchiveProcedures(registry = PROCEDURE_REGISTRY, options = {}) {
|
|
146
|
+
registerModules(registry, [createArchiveModule(options)]);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The check of the entries of an archive before an extract ("zip slip", roadmap R46).
|
|
3
|
+
*
|
|
4
|
+
* `planExtract()` examines all the entries before the extract writes a file. A hostile archive
|
|
5
|
+
* thus changes nothing. The rules:
|
|
6
|
+
*
|
|
7
|
+
* 1. A path must be relative and must not have `..`. A drive letter, a UNC path, a NUL character
|
|
8
|
+
* and (on Windows) a colon are refused too. A backslash counts as a separator.
|
|
9
|
+
* 2. An entry must not go through a symbolic link of the archive: a link `a` and a file `a/b`.
|
|
10
|
+
* 3. A symbolic link must stay in the target. Its target is relative, and the resolution through
|
|
11
|
+
* the other links of the archive stays in the target folder. The check knows all the links of
|
|
12
|
+
* the archive first, so the order of the entries does not matter.
|
|
13
|
+
* 4. A path of a link appears only one time in the archive.
|
|
14
|
+
* 5. A hard link names a file that came before it in the archive.
|
|
15
|
+
* 6. A folder of the target that the extract goes through must not be a symbolic link.
|
|
16
|
+
* 7. Without `overwrite`, an existing file at the path of an entry is an error.
|
|
17
|
+
*
|
|
18
|
+
* Rules 2 and 3 compare the paths two times: with the case, and without the case. A file system
|
|
19
|
+
* that ignores the case (Windows, macOS) then gets the same protection as one that does not.
|
|
20
|
+
*/
|
|
21
|
+
import type { ArchiveEntryKind } from "./types.js";
|
|
22
|
+
/** One entry of an archive, before the check. */
|
|
23
|
+
export interface RawEntry {
|
|
24
|
+
/** The name in the archive. */
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly kind: ArchiveEntryKind;
|
|
27
|
+
readonly size: number;
|
|
28
|
+
/** The target of a symbolic link, or the archive path of the file of a hard link. */
|
|
29
|
+
readonly linkTarget?: string | undefined;
|
|
30
|
+
/** The place of the entry in the archive. */
|
|
31
|
+
readonly index?: number | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** One entry after the check. */
|
|
34
|
+
export interface PlannedEntry extends RawEntry {
|
|
35
|
+
/** The parts of the path: no empty part, no `.` and no `..`. */
|
|
36
|
+
readonly parts: readonly string[];
|
|
37
|
+
/** The parts joined with `/`. */
|
|
38
|
+
readonly path: string;
|
|
39
|
+
}
|
|
40
|
+
/** The options of `planExtract()`. */
|
|
41
|
+
export interface PlanOptions {
|
|
42
|
+
readonly overwrite: boolean;
|
|
43
|
+
readonly maxBytes: number;
|
|
44
|
+
readonly maxEntries: number;
|
|
45
|
+
}
|
|
46
|
+
/** True for a path that starts at a root: `/x`, `\x`, `C:x`, `C:\x` or `\\server\share`. */
|
|
47
|
+
export declare function isAbsoluteName(name: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* This function gives the parts of the path of an entry. It throws `UNSAFE_PATH` for an absolute
|
|
50
|
+
* path, a `..`, a NUL character, and on Windows a colon (an alternate data stream).
|
|
51
|
+
*/
|
|
52
|
+
export declare function entryParts(name: string, code?: "UNSAFE_PATH" | "UNSAFE_LINK"): string[];
|
|
53
|
+
/**
|
|
54
|
+
* This function examines the entries of an archive for an extract into `target` (a real path),
|
|
55
|
+
* and gives them with their parts. It throws the first problem. It writes nothing.
|
|
56
|
+
*/
|
|
57
|
+
export declare function planExtract(entries: readonly RawEntry[], target: string, options: PlanOptions): PlannedEntry[];
|
|
58
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,iDAAiD;AACjD,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAOD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,aAAa,GAAG,aAA6B,GAAG,MAAM,EAAE,CAStG;AA2DD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,YAAY,EAAE,CA0F9G"}
|