dir-archiver 2.2.0 → 3.0.1

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/dist/cli.js CHANGED
@@ -1,51 +1,137 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const index_1 = __importDefault(require("./index"));
8
- const argv_flags_1 = __importDefault(require("argv-flags"));
9
- const parseBooleanFlag = (flag) => {
10
- const rawValue = (0, argv_flags_1.default)(flag, 'string');
11
- if (typeof rawValue === 'string' && rawValue.length > 0 && !rawValue.startsWith('-')) {
12
- const normalized = rawValue.toLowerCase();
13
- if (normalized === 'true') {
14
- return true;
15
- }
16
- if (normalized === 'false') {
17
- return false;
2
+ import { audit, detect, extract, list, normalize, open, write } from './index.js';
3
+ import { DirArchiverError } from './errors.js';
4
+ import { parseCliArgs } from './cli-args.js';
5
+ const usage = `Usage:
6
+ dir-archiver write --source <path> --output <archive> [--format <format>] [--include-base-directory] [--exclude <path>...]
7
+ dir-archiver open --input <archive> [--profile compat|strict|agent]
8
+ dir-archiver detect --input <archive>
9
+ dir-archiver list --input <archive>
10
+ dir-archiver audit --input <archive> [--profile compat|strict|agent]
11
+ dir-archiver extract --input <archive> --output <directory> [--profile compat|strict|agent] [--max-entry-bytes <n>] [--max-total-extracted-bytes <n>]
12
+ dir-archiver normalize --input <archive> --output <archive> [--profile compat|strict|agent]
13
+
14
+ Common options:
15
+ --format <format> zip|tar|tgz|tar.gz|gz|bz2|tar.bz2|zst|tar.zst|br|tar.br|xz|tar.xz
16
+ --profile <profile> compat|strict|agent
17
+ --json emit machine-readable JSON
18
+ --allow-symlinks enable symlink extraction
19
+ --allow-hardlinks enable hardlink extraction (currently unsupported)
20
+ `;
21
+ const run = async () => {
22
+ const parsed = await parseCliArgs(process.argv.slice(2));
23
+ const command = parsed.command;
24
+ if (!parsed.ok || !command) {
25
+ const payload = {
26
+ schemaVersion: '1',
27
+ code: 'DIRARCHIVER_USAGE',
28
+ message: 'Invalid CLI arguments.',
29
+ issues: parsed.issues
30
+ };
31
+ if (parsed.json) {
32
+ console.log(JSON.stringify(payload));
33
+ }
34
+ else {
35
+ console.error(usage);
36
+ for (const issue of parsed.issues) {
37
+ console.error(`- [${issue.code}] ${issue.message}`);
38
+ }
39
+ }
40
+ return 2;
41
+ }
42
+ const commonOptions = {
43
+ profile: parsed.profile,
44
+ ...(parsed.format ? { format: parsed.format } : {})
45
+ };
46
+ switch (command) {
47
+ case 'write': {
48
+ const result = await write(requireString(parsed.source, 'write requires --source/--src'), requireString(parsed.output, 'write requires --output/--dest'), {
49
+ ...commonOptions,
50
+ includeBaseDirectory: parsed.includeBaseDirectory,
51
+ followSymlinks: parsed.followSymlinks,
52
+ exclude: parsed.exclude
53
+ });
54
+ outputResult(parsed.json, result);
55
+ return 0;
56
+ }
57
+ case 'open': {
58
+ const reader = await open(requireString(parsed.input, 'open requires --input'), commonOptions);
59
+ outputResult(parsed.json, {
60
+ format: reader.format,
61
+ detection: reader.detection
62
+ });
63
+ return 0;
64
+ }
65
+ case 'detect': {
66
+ const result = await detect(requireString(parsed.input, 'detect requires --input'), commonOptions);
67
+ outputResult(parsed.json, result);
68
+ return 0;
69
+ }
70
+ case 'list': {
71
+ const result = await list(requireString(parsed.input, 'list requires --input'), commonOptions);
72
+ outputResult(parsed.json, result);
73
+ return 0;
74
+ }
75
+ case 'audit': {
76
+ const result = await audit(requireString(parsed.input, 'audit requires --input'), commonOptions);
77
+ outputResult(parsed.json, result);
78
+ return 0;
79
+ }
80
+ case 'extract': {
81
+ const result = await extract(requireString(parsed.input, 'extract requires --input'), requireString(parsed.output, 'extract requires --output'), {
82
+ ...commonOptions,
83
+ allowSymlinks: parsed.allowSymlinks,
84
+ allowHardlinks: parsed.allowHardlinks,
85
+ ...(typeof parsed.maxEntryBytes === 'number' ? { maxEntryBytes: parsed.maxEntryBytes } : {}),
86
+ ...(typeof parsed.maxTotalExtractedBytes === 'number'
87
+ ? { maxTotalExtractedBytes: parsed.maxTotalExtractedBytes }
88
+ : {})
89
+ });
90
+ outputResult(parsed.json, result);
91
+ return 0;
92
+ }
93
+ case 'normalize': {
94
+ const result = await normalize(requireString(parsed.input, 'normalize requires --input'), requireString(parsed.output, 'normalize requires --output'), {
95
+ ...commonOptions
96
+ });
97
+ outputResult(parsed.json, result);
98
+ return 0;
18
99
  }
100
+ default:
101
+ break;
19
102
  }
20
- return (0, argv_flags_1.default)(flag, 'boolean') === true;
103
+ const unreachable = command;
104
+ throw new Error(`Unhandled command: ${String(unreachable)}`);
21
105
  };
22
- const directoryPath = (0, argv_flags_1.default)('--src', 'string');
23
- const zipPath = (0, argv_flags_1.default)('--dest', 'string');
24
- const includeBaseDirectory = parseBooleanFlag('--includebasedir');
25
- const followSymlinks = parseBooleanFlag('--followsymlinks');
26
- const excludeValues = (0, argv_flags_1.default)('--exclude', 'array');
27
- const excludes = Array.isArray(excludeValues) ? excludeValues : [];
28
- if (typeof directoryPath !== 'string' || typeof zipPath !== 'string') {
29
- console.log(` Dir Archiver could not be executed. Some arguments are missing.
30
-
31
- Options:
32
- --src The path of the folder to archive. [string][required]
33
- --dest The path of the zip file to create. [string][required]
34
- --includebasedir Includes a base directory at the root of the archive.
35
- For example, if the root folder of your project is named
36
- "your-project", setting this option to true will create
37
- an archive that includes this base directory.
38
- If this option is set to false the archive created will
39
- unzip its content to the current directory. [bool]
40
- --followsymlinks Follow symlinks when traversing directories. [bool]
41
- --exclude A list with the names of the files and folders to exclude. [array]`);
42
- process.exitCode = 1;
43
- }
44
- else {
45
- const archive = new index_1.default(directoryPath, zipPath, includeBaseDirectory, excludes, followSymlinks);
46
- archive.createZip().catch((err) => {
47
- const normalizedError = err instanceof Error ? err : new Error(String(err));
48
- console.error(normalizedError);
106
+ const outputResult = (asJson, payload) => {
107
+ if (asJson) {
108
+ console.log(JSON.stringify(payload));
109
+ return;
110
+ }
111
+ console.log(payload);
112
+ };
113
+ const requireString = (value, message) => {
114
+ if (typeof value !== 'string' || value.length === 0) {
115
+ throw new DirArchiverError('DIRARCHIVER_USAGE', message);
116
+ }
117
+ return value;
118
+ };
119
+ void run()
120
+ .then((exitCode) => {
121
+ process.exitCode = exitCode;
122
+ })
123
+ .catch((error) => {
124
+ var _a;
125
+ if (error instanceof DirArchiverError) {
126
+ console.error(JSON.stringify(error.toJSON()));
49
127
  process.exitCode = 1;
50
- });
51
- }
128
+ return;
129
+ }
130
+ if (error instanceof Error) {
131
+ console.error((_a = error.stack) !== null && _a !== void 0 ? _a : error.message);
132
+ }
133
+ else {
134
+ console.error(String(error));
135
+ }
136
+ process.exitCode = 1;
137
+ });
package/dist/core.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import type { ArchiveAuditReport, ArchiveReader } from '@ismail-elkorchi/bytefold';
2
+ import type { DetectResult, DirArchiverInput, ExtractOptions, ExtractResult, ListResult, NormalizeOptions, NormalizeResult, OpenOptions, WriteOptions, WriteResult } from './types.js';
3
+ /**
4
+ * Opens an archive input with bytefold runtime bindings.
5
+ */
6
+ export declare const open: (input: DirArchiverInput, options?: OpenOptions) => Promise<ArchiveReader>;
7
+ /**
8
+ * Detects archive format and exposes bytefold detection metadata.
9
+ */
10
+ export declare const detect: (input: DirArchiverInput, options?: OpenOptions) => Promise<DetectResult>;
11
+ /**
12
+ * Lists archive entries without extracting to disk.
13
+ */
14
+ export declare const list: (input: DirArchiverInput, options?: OpenOptions) => Promise<ListResult>;
15
+ /**
16
+ * Runs bytefold audit checks for the selected safety profile.
17
+ */
18
+ export declare const audit: (input: DirArchiverInput, options?: OpenOptions) => Promise<ArchiveAuditReport>;
19
+ /**
20
+ * Writes a normalized deterministic archive when supported by the format.
21
+ */
22
+ export declare const normalize: (input: DirArchiverInput, destination: string, options?: NormalizeOptions) => Promise<NormalizeResult>;
23
+ /**
24
+ * Extracts entries to a destination directory with safety enforcement.
25
+ */
26
+ export declare const extract: (input: DirArchiverInput, destination: string, options?: ExtractOptions) => Promise<ExtractResult>;
27
+ /**
28
+ * Writes an archive from a file or directory source.
29
+ */
30
+ export declare const write: (source: string, destination: string, options?: WriteOptions) => Promise<WriteResult>;
31
+ export declare const copyStreamToFile: (source: string, destination: string) => Promise<void>;
32
+ export declare const pathExists: (value: string) => boolean;
33
+ export declare const fileSize: (value: string) => number;