text-compress 2.0.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +186 -0
  3. package/dist/api/folder.d.ts +38 -0
  4. package/dist/api/folder.d.ts.map +1 -0
  5. package/dist/api/folder.js +50 -0
  6. package/dist/api/folder.js.map +1 -0
  7. package/dist/api/text.d.ts +30 -0
  8. package/dist/api/text.d.ts.map +1 -0
  9. package/dist/api/text.js +38 -0
  10. package/dist/api/text.js.map +1 -0
  11. package/dist/archive/collect.d.ts +26 -0
  12. package/dist/archive/collect.d.ts.map +1 -0
  13. package/dist/archive/collect.js +38 -0
  14. package/dist/archive/collect.js.map +1 -0
  15. package/dist/archive/format.d.ts +62 -0
  16. package/dist/archive/format.d.ts.map +1 -0
  17. package/dist/archive/format.js +143 -0
  18. package/dist/archive/format.js.map +1 -0
  19. package/dist/archive/types.d.ts +25 -0
  20. package/dist/archive/types.d.ts.map +1 -0
  21. package/dist/archive/types.js +10 -0
  22. package/dist/archive/types.js.map +1 -0
  23. package/dist/archive/unpack.d.ts +21 -0
  24. package/dist/archive/unpack.d.ts.map +1 -0
  25. package/dist/archive/unpack.js +41 -0
  26. package/dist/archive/unpack.js.map +1 -0
  27. package/dist/cli/analytics.d.ts +10 -0
  28. package/dist/cli/analytics.d.ts.map +1 -0
  29. package/dist/cli/analytics.js +22 -0
  30. package/dist/cli/analytics.js.map +1 -0
  31. package/dist/cli/args.d.ts +43 -0
  32. package/dist/cli/args.d.ts.map +1 -0
  33. package/dist/cli/args.js +152 -0
  34. package/dist/cli/args.js.map +1 -0
  35. package/dist/cli/commands/compress.d.ts +9 -0
  36. package/dist/cli/commands/compress.d.ts.map +1 -0
  37. package/dist/cli/commands/compress.js +62 -0
  38. package/dist/cli/commands/compress.js.map +1 -0
  39. package/dist/cli/commands/decompress.d.ts +9 -0
  40. package/dist/cli/commands/decompress.d.ts.map +1 -0
  41. package/dist/cli/commands/decompress.js +69 -0
  42. package/dist/cli/commands/decompress.js.map +1 -0
  43. package/dist/cli/detect.d.ts +25 -0
  44. package/dist/cli/detect.d.ts.map +1 -0
  45. package/dist/cli/detect.js +78 -0
  46. package/dist/cli/detect.js.map +1 -0
  47. package/dist/cli/main.d.ts +8 -0
  48. package/dist/cli/main.d.ts.map +1 -0
  49. package/dist/cli/main.js +74 -0
  50. package/dist/cli/main.js.map +1 -0
  51. package/dist/cli/output.d.ts +13 -0
  52. package/dist/cli/output.d.ts.map +1 -0
  53. package/dist/cli/output.js +26 -0
  54. package/dist/cli/output.js.map +1 -0
  55. package/dist/cli/paths.d.ts +13 -0
  56. package/dist/cli/paths.d.ts.map +1 -0
  57. package/dist/cli/paths.js +24 -0
  58. package/dist/cli/paths.js.map +1 -0
  59. package/dist/cli/usage.d.ts +8 -0
  60. package/dist/cli/usage.d.ts.map +1 -0
  61. package/dist/cli/usage.js +73 -0
  62. package/dist/cli/usage.js.map +1 -0
  63. package/dist/cli.d.ts +3 -0
  64. package/dist/cli.d.ts.map +1 -0
  65. package/dist/cli.js +10 -0
  66. package/dist/cli.js.map +1 -0
  67. package/dist/compression/brotli.d.ts +43 -0
  68. package/dist/compression/brotli.d.ts.map +1 -0
  69. package/dist/compression/brotli.js +56 -0
  70. package/dist/compression/brotli.js.map +1 -0
  71. package/dist/crypto/password.d.ts +22 -0
  72. package/dist/crypto/password.d.ts.map +1 -0
  73. package/dist/crypto/password.js +62 -0
  74. package/dist/crypto/password.js.map +1 -0
  75. package/dist/encoding/base64.d.ts +17 -0
  76. package/dist/encoding/base64.d.ts.map +1 -0
  77. package/dist/encoding/base64.js +21 -0
  78. package/dist/encoding/base64.js.map +1 -0
  79. package/dist/encoding/index.d.ts +29 -0
  80. package/dist/encoding/index.d.ts.map +1 -0
  81. package/dist/encoding/index.js +47 -0
  82. package/dist/encoding/index.js.map +1 -0
  83. package/dist/encoding/z85.d.ts +64 -0
  84. package/dist/encoding/z85.d.ts.map +1 -0
  85. package/dist/encoding/z85.js +99 -0
  86. package/dist/encoding/z85.js.map +1 -0
  87. package/dist/fs/gitignore.d.ts +30 -0
  88. package/dist/fs/gitignore.d.ts.map +1 -0
  89. package/dist/fs/gitignore.js +104 -0
  90. package/dist/fs/gitignore.js.map +1 -0
  91. package/dist/fs/paths.d.ts +22 -0
  92. package/dist/fs/paths.d.ts.map +1 -0
  93. package/dist/fs/paths.js +55 -0
  94. package/dist/fs/paths.js.map +1 -0
  95. package/dist/fs/walk.d.ts +22 -0
  96. package/dist/fs/walk.d.ts.map +1 -0
  97. package/dist/fs/walk.js +49 -0
  98. package/dist/fs/walk.js.map +1 -0
  99. package/dist/index.d.ts +21 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +25 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/payload/tags.d.ts +60 -0
  104. package/dist/payload/tags.d.ts.map +1 -0
  105. package/dist/payload/tags.js +78 -0
  106. package/dist/payload/tags.js.map +1 -0
  107. package/dist/split/parts.d.ts +130 -0
  108. package/dist/split/parts.d.ts.map +1 -0
  109. package/dist/split/parts.js +290 -0
  110. package/dist/split/parts.js.map +1 -0
  111. package/dist/streaming/folder.d.ts +49 -0
  112. package/dist/streaming/folder.d.ts.map +1 -0
  113. package/dist/streaming/folder.js +220 -0
  114. package/dist/streaming/folder.js.map +1 -0
  115. package/dist/streaming.d.ts +16 -0
  116. package/dist/streaming.d.ts.map +1 -0
  117. package/dist/streaming.js +243 -0
  118. package/dist/streaming.js.map +1 -0
  119. package/dist/types.d.ts +18 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +11 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +60 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @module archive/types
3
+ *
4
+ * Data structures for the custom folder archive format.
5
+ */
6
+ /**
7
+ * A single entry in a folder archive — either a directory marker or a file.
8
+ *
9
+ * Directories carry only a relative path; files carry path + binary content.
10
+ * This flat list representation (vs a nested tree) simplifies both
11
+ * serialization and streaming writes.
12
+ */
13
+ export interface ArchiveEntry {
14
+ /** `"d"` = directory marker, `"f"` = file with content. */
15
+ type: "d" | "f";
16
+ /** POSIX-style relative path (forward slashes, no leading `/`). */
17
+ relPath: string;
18
+ /** File content; absent for directory entries. */
19
+ content?: Buffer;
20
+ }
21
+ /** Directory entry type byte on the wire. */
22
+ export declare const ENTRY_DIR = 68;
23
+ /** File entry type byte on the wire (`"F"` in ASCII). */
24
+ export declare const ENTRY_FILE = 70;
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/archive/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,IAAI,EAAE,GAAG,GAAG,GAAG,CAAA;IACf,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,6CAA6C;AAC7C,eAAO,MAAM,SAAS,KAAO,CAAA;AAE7B,yDAAyD;AACzD,eAAO,MAAM,UAAU,KAAO,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @module archive/types
3
+ *
4
+ * Data structures for the custom folder archive format.
5
+ */
6
+ /** Directory entry type byte on the wire. */
7
+ export const ENTRY_DIR = 0x44;
8
+ /** File entry type byte on the wire (`"F"` in ASCII). */
9
+ export const ENTRY_FILE = 0x46;
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/archive/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAA;AAE7B,yDAAyD;AACzD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @module archive/unpack
3
+ *
4
+ * Restore a folder archive from binary data to the filesystem.
5
+ *
6
+ * Iterates deserialized entries and creates directories / writes files.
7
+ * Parent directories are created on demand (`mkdirSync` with `recursive`).
8
+ */
9
+ /**
10
+ * Unpack a binary archive buffer into a destination directory.
11
+ *
12
+ * @param buffer - Serialized archive bytes (not Brotli-compressed).
13
+ * @param destDir - Where to recreate the folder tree.
14
+ * @returns Counts of files, directories, and total bytes restored.
15
+ */
16
+ export declare function unpackDirectory(buffer: Buffer, destDir: string): {
17
+ files: number;
18
+ dirs: number;
19
+ bytes: number;
20
+ };
21
+ //# sourceMappingURL=unpack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpack.d.ts","sourceRoot":"","sources":["../../src/archive/unpack.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBhD"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @module archive/unpack
3
+ *
4
+ * Restore a folder archive from binary data to the filesystem.
5
+ *
6
+ * Iterates deserialized entries and creates directories / writes files.
7
+ * Parent directories are created on demand (`mkdirSync` with `recursive`).
8
+ */
9
+ import { mkdirSync, writeFileSync } from "node:fs";
10
+ import { dirname, join } from "node:path";
11
+ import { deserializeArchive } from "./format.js";
12
+ /**
13
+ * Unpack a binary archive buffer into a destination directory.
14
+ *
15
+ * @param buffer - Serialized archive bytes (not Brotli-compressed).
16
+ * @param destDir - Where to recreate the folder tree.
17
+ * @returns Counts of files, directories, and total bytes restored.
18
+ */
19
+ export function unpackDirectory(buffer, destDir) {
20
+ mkdirSync(destDir, { recursive: true });
21
+ const entries = deserializeArchive(buffer);
22
+ let files = 0;
23
+ let dirs = 0;
24
+ let bytes = 0;
25
+ for (const entry of entries) {
26
+ const destPath = join(destDir, ...entry.relPath.split("/"));
27
+ if (entry.type === "d") {
28
+ mkdirSync(destPath, { recursive: true });
29
+ dirs++;
30
+ }
31
+ else {
32
+ mkdirSync(dirname(destPath), { recursive: true });
33
+ const content = entry.content ?? Buffer.alloc(0);
34
+ writeFileSync(destPath, content);
35
+ files++;
36
+ bytes += content.length;
37
+ }
38
+ }
39
+ return { files, dirs, bytes };
40
+ }
41
+ //# sourceMappingURL=unpack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpack.js","sourceRoot":"","sources":["../../src/archive/unpack.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,OAAe;IAEf,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAE1C,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YACvB,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACxC,IAAI,EAAE,CAAA;QACR,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAChD,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAChC,KAAK,EAAE,CAAA;YACP,KAAK,IAAI,OAAO,CAAC,MAAM,CAAA;QACzB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @module cli/analytics
3
+ *
4
+ * Post-run statistics printed to stdout after each CLI command.
5
+ */
6
+ /** Print a key/value analytics block below the main status line. */
7
+ export declare function printAnalytics(stats: Record<string, string | number>): void;
8
+ /** Build split-related analytics fields when output was split. */
9
+ export declare function splitAnalytics(splitChunkSize: number | undefined, outputParts: number): Record<string, string | number>;
10
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,QAKpE;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAC5B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,EAAE,MAAM,GAClB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAMjC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module cli/analytics
3
+ *
4
+ * Post-run statistics printed to stdout after each CLI command.
5
+ */
6
+ /** Print a key/value analytics block below the main status line. */
7
+ export function printAnalytics(stats) {
8
+ console.log("\n--- Analytics ---");
9
+ for (const [key, value] of Object.entries(stats)) {
10
+ console.log(`${key}: ${value}`);
11
+ }
12
+ }
13
+ /** Build split-related analytics fields when output was split. */
14
+ export function splitAnalytics(splitChunkSize, outputParts) {
15
+ if (splitChunkSize === undefined)
16
+ return {};
17
+ return {
18
+ "Split size (chars)": splitChunkSize,
19
+ "Output parts": outputParts,
20
+ };
21
+ }
22
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,KAAsC;IACnE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;IAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAC5B,cAAkC,EAClC,WAAmB;IAEnB,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAC3C,OAAO;QACL,oBAAoB,EAAE,cAAc;QACpC,cAAc,EAAE,WAAW;KAC5B,CAAA;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module cli/args
3
+ *
4
+ * Command-line argument parsing and input resolution.
5
+ *
6
+ * The CLI accepts a positional path or explicit flags (`-t`, `-f`, `-d`).
7
+ * `resolveInputArgs` normalises these into a single internal representation
8
+ * and auto-detects files vs directories when a bare path is given.
9
+ */
10
+ import type { Encoding } from "../types.js";
11
+ /** Parsed CLI flags (before input resolution). */
12
+ export interface Args {
13
+ text?: string;
14
+ path?: string;
15
+ file?: string;
16
+ dir?: string;
17
+ output?: string;
18
+ encoding?: string;
19
+ split?: number;
20
+ password?: string;
21
+ /** Force compress or decompress instead of auto-detecting from input. */
22
+ mode?: "compress" | "decompress";
23
+ }
24
+ /**
25
+ * Parse `process.argv` tail into an {@link Args} object.
26
+ *
27
+ * Uses a simple sequential scan (not a general-purpose parser library)
28
+ * because the flag set is small and fixed.
29
+ */
30
+ export declare function parseArgs(argv: string[]): Args;
31
+ /**
32
+ * Normalise and validate input paths after parsing.
33
+ *
34
+ * Mutates `args` in place: e.g. a directory passed as `-f` becomes `args.dir`.
35
+ */
36
+ export declare function resolveInputArgs(args: Args, command: "compress" | "decompress"): void;
37
+ /** Read compress input from resolved args (file or inline text). */
38
+ export declare function readInput(args: Args): string;
39
+ /** Parse `-e` encoding flag into the library's {@link Encoding} type. */
40
+ export declare function resolveEncoding(args: Args): Encoding;
41
+ /** Parse `-e` when set, otherwise `undefined` for auto-detection. */
42
+ export declare function resolveEncodingOptional(args: Args): Encoding | undefined;
43
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,kDAAkD;AAClD,MAAM,WAAW,IAAI;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;CACjC;AAUD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuC9C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CA0DrF;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAI5C;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAKpD;AAED,qEAAqE;AACrE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,SAAS,CAGxE"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * @module cli/args
3
+ *
4
+ * Command-line argument parsing and input resolution.
5
+ *
6
+ * The CLI accepts a positional path or explicit flags (`-t`, `-f`, `-d`).
7
+ * `resolveInputArgs` normalises these into a single internal representation
8
+ * and auto-detects files vs directories when a bare path is given.
9
+ */
10
+ import { existsSync, statSync } from "node:fs";
11
+ import { assertDirectory, readTextFile } from "../fs/paths.js";
12
+ /** Reject multiple simultaneous input sources. */
13
+ function assertSingleInput(args) {
14
+ const sources = [args.text, args.path, args.file, args.dir].filter((value) => value !== undefined);
15
+ if (sources.length > 1) {
16
+ throw new Error("Multiple inputs specified. Pass one path, or use -t, -f, or -d.");
17
+ }
18
+ }
19
+ /**
20
+ * Parse `process.argv` tail into an {@link Args} object.
21
+ *
22
+ * Uses a simple sequential scan (not a general-purpose parser library)
23
+ * because the flag set is small and fixed.
24
+ */
25
+ export function parseArgs(argv) {
26
+ const args = {};
27
+ for (let i = 0; i < argv.length; i++) {
28
+ const arg = argv[i];
29
+ if (arg === "-t" || arg === "--text") {
30
+ args.text = argv[++i];
31
+ }
32
+ else if (arg === "-f" || arg === "--file") {
33
+ args.file = argv[++i];
34
+ }
35
+ else if (arg === "-d" || arg === "--dir") {
36
+ args.dir = argv[++i];
37
+ }
38
+ else if (arg === "-o" || arg === "--output") {
39
+ args.output = argv[++i];
40
+ }
41
+ else if (arg === "-e" || arg === "--encoding") {
42
+ args.encoding = argv[++i];
43
+ }
44
+ else if (arg === "-s" || arg === "--split") {
45
+ const value = argv[++i];
46
+ const split = Number(value);
47
+ if (!value || !Number.isInteger(split) || split < 1) {
48
+ throw new Error(`Invalid -s/--split "${value}". Use a positive integer character count.`);
49
+ }
50
+ args.split = split;
51
+ }
52
+ else if (arg === "-p" || arg === "--password") {
53
+ const value = argv[++i];
54
+ if (!value) {
55
+ throw new Error("Missing value for -p/--password.");
56
+ }
57
+ args.password = value;
58
+ }
59
+ else if (arg === "-C" || arg === "--compress") {
60
+ args.mode = "compress";
61
+ }
62
+ else if (arg === "-D" || arg === "--decompress") {
63
+ args.mode = "decompress";
64
+ }
65
+ else if (!arg.startsWith("-")) {
66
+ if (args.path !== undefined || args.text !== undefined || args.file || args.dir) {
67
+ throw new Error("Multiple inputs specified. Pass one path, or use -t, -f, or -d.");
68
+ }
69
+ args.path = arg;
70
+ }
71
+ }
72
+ return args;
73
+ }
74
+ /**
75
+ * Normalise and validate input paths after parsing.
76
+ *
77
+ * Mutates `args` in place: e.g. a directory passed as `-f` becomes `args.dir`.
78
+ */
79
+ export function resolveInputArgs(args, command) {
80
+ assertSingleInput(args);
81
+ if (args.text !== undefined)
82
+ return;
83
+ const path = args.file ?? args.dir ?? args.path;
84
+ if (!path) {
85
+ throw new Error("No input provided. Pass a path, or use -t <text>.");
86
+ }
87
+ if (args.dir) {
88
+ assertDirectory(args.dir);
89
+ return;
90
+ }
91
+ if (args.file) {
92
+ if (existsSync(args.file)) {
93
+ const stat = statSync(args.file);
94
+ if (stat.isDirectory()) {
95
+ if (command === "decompress") {
96
+ throw new Error(`"${args.file}" is a directory. Pass the compressed .txt file, not a decompressed output folder.`);
97
+ }
98
+ args.dir = args.file;
99
+ args.file = undefined;
100
+ }
101
+ }
102
+ return;
103
+ }
104
+ if (!existsSync(path)) {
105
+ if (command === "compress") {
106
+ args.text = path;
107
+ args.path = undefined;
108
+ return;
109
+ }
110
+ throw new Error(`Input not found: ${path}`);
111
+ }
112
+ const stat = statSync(path);
113
+ if (stat.isDirectory()) {
114
+ if (command === "decompress") {
115
+ throw new Error(`"${path}" is a directory. Pass the compressed .txt file, not a decompressed output folder.`);
116
+ }
117
+ args.dir = path;
118
+ args.path = undefined;
119
+ return;
120
+ }
121
+ if (stat.isFile()) {
122
+ args.file = path;
123
+ args.path = undefined;
124
+ return;
125
+ }
126
+ throw new Error(`Cannot read "${path}": not a regular file or directory.`);
127
+ }
128
+ /** Read compress input from resolved args (file or inline text). */
129
+ export function readInput(args) {
130
+ if (args.file)
131
+ return readTextFile(args.file, "compress");
132
+ if (args.text !== undefined)
133
+ return args.text;
134
+ throw new Error("No input provided. Pass a path, or use -t <text>.");
135
+ }
136
+ /** Parse `-e` encoding flag into the library's {@link Encoding} type. */
137
+ export function resolveEncoding(args) {
138
+ if (!args.encoding)
139
+ return 64;
140
+ if (args.encoding === "64")
141
+ return 64;
142
+ if (args.encoding === "85")
143
+ return 85;
144
+ throw new Error(`Invalid -e/--encoding "${args.encoding}". Use 64 or 85.`);
145
+ }
146
+ /** Parse `-e` when set, otherwise `undefined` for auto-detection. */
147
+ export function resolveEncodingOptional(args) {
148
+ if (!args.encoding)
149
+ return undefined;
150
+ return resolveEncoding(args);
151
+ }
152
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module cli/commands/compress
3
+ *
4
+ * `text-compress` command — Brotli-compress input and write encoded output.
5
+ */
6
+ import { type Args } from "../args.js";
7
+ /** Execute the compress subcommand. */
8
+ export declare function runCompress(args: Args): Promise<void>;
9
+ //# sourceMappingURL=compress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/compress.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,KAAK,IAAI,EAA8B,MAAM,YAAY,CAAA;AAIlE,uCAAuC;AACvC,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE3D"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @module cli/commands/compress
3
+ *
4
+ * `text-compress` command — Brotli-compress input and write encoded output.
5
+ */
6
+ import { compress } from "../../api/text.js";
7
+ import { assertDirectory } from "../../fs/paths.js";
8
+ import { compressFolderToPath } from "../../streaming/folder.js";
9
+ import { printAnalytics, splitAnalytics } from "../analytics.js";
10
+ import { readInput, resolveEncoding } from "../args.js";
11
+ import { writeCompressedOutput } from "../output.js";
12
+ import { resolveOutputPath } from "../paths.js";
13
+ /** Execute the compress subcommand. */
14
+ export async function runCompress(args) {
15
+ const encoding = resolveEncoding(args);
16
+ if (args.dir) {
17
+ assertDirectory(args.dir);
18
+ const outputPath = resolveOutputPath(args, "compressed.txt", ".txt");
19
+ const start = process.hrtime.bigint();
20
+ const { fileCount, dirCount, originalBytes, archiveBytes, compressedBytes, outputPaths, splitChunkSize, } = await compressFolderToPath(args.dir, outputPath, encoding, args.split, args.password);
21
+ const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6;
22
+ const ratio = originalBytes === 0 ? 0 : compressedBytes / originalBytes;
23
+ console.log(outputPaths.length === 1
24
+ ? `Compressed folder written to ${outputPaths[0]}`
25
+ : `Compressed folder written to ${outputPaths.length} files:\n ${outputPaths.join("\n ")}`);
26
+ printAnalytics({
27
+ Encoding: `base${encoding}`,
28
+ Files: fileCount,
29
+ Directories: dirCount,
30
+ "Original size (bytes)": originalBytes,
31
+ "Archive size before compression (bytes)": archiveBytes,
32
+ [`Compressed size (bytes, base${encoding})`]: compressedBytes,
33
+ ...splitAnalytics(splitChunkSize, outputPaths.length),
34
+ "Size ratio (compressed/original)": ratio.toFixed(3),
35
+ "Space saved": `${((1 - ratio) * 100).toFixed(1)}%`,
36
+ "Time taken (ms)": elapsedMs.toFixed(3),
37
+ });
38
+ return;
39
+ }
40
+ const outputPath = resolveOutputPath(args, "compressed.txt", ".txt");
41
+ const input = readInput(args);
42
+ const inputBytes = Buffer.byteLength(input, "utf-8");
43
+ const start = process.hrtime.bigint();
44
+ const result = compress(input, encoding, args.password);
45
+ const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6;
46
+ const { paths: outputPaths, splitChunkSize } = writeCompressedOutput(result, outputPath, args.split);
47
+ const outputBytes = Buffer.byteLength(result, "utf-8");
48
+ const ratio = inputBytes === 0 ? 0 : outputBytes / inputBytes;
49
+ console.log(outputPaths.length === 1
50
+ ? `Compressed output written to ${outputPath}`
51
+ : `Compressed output written to ${outputPaths.length} files:\n ${outputPaths.join("\n ")}`);
52
+ printAnalytics({
53
+ Encoding: `base${encoding}`,
54
+ "Original size (bytes)": inputBytes,
55
+ [`Compressed size (bytes, base${encoding})`]: outputBytes,
56
+ ...splitAnalytics(splitChunkSize, outputPaths.length),
57
+ "Size ratio (compressed/original)": ratio.toFixed(3),
58
+ "Space saved": `${((1 - ratio) * 100).toFixed(1)}%`,
59
+ "Time taken (ms)": elapsedMs.toFixed(3),
60
+ });
61
+ }
62
+ //# sourceMappingURL=compress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compress.js","sourceRoot":"","sources":["../../../src/cli/commands/compress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module cli/commands/decompress
3
+ *
4
+ * `text-compress` decompress path — decode and restore text or folder payloads.
5
+ */
6
+ import { type Args } from "../args.js";
7
+ /** Execute the decompress subcommand. */
8
+ export declare function runDecompress(args: Args): void;
9
+ //# sourceMappingURL=decompress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/decompress.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,KAAK,IAAI,EAAuD,MAAM,YAAY,CAAA;AAuB3F,yCAAyC;AACzC,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CA8C9C"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @module cli/commands/decompress
3
+ *
4
+ * `text-compress` decompress path — decode and restore text or folder payloads.
5
+ */
6
+ import { writeFileSync } from "node:fs";
7
+ import { unpackDirectory } from "../../archive/unpack.js";
8
+ import { decompressPayload, TAG_FOLDER, TAG_TEXT } from "../../payload/tags.js";
9
+ import { readSplitInput } from "../../split/parts.js";
10
+ import { printAnalytics } from "../analytics.js";
11
+ import { readInput, resolveEncoding, resolveEncodingOptional } from "../args.js";
12
+ import { resolveDetectedEncoding } from "../detect.js";
13
+ import { resolveOutputPath } from "../paths.js";
14
+ /** Read compressed input from file (with split support) or inline text. */
15
+ function readCompressedInput(args) {
16
+ if (args.file) {
17
+ const { content, partPaths } = readSplitInput(args.file);
18
+ return {
19
+ content,
20
+ inputBytes: Buffer.byteLength(content, "utf-8"),
21
+ partPaths: partPaths.length > 1 ? partPaths : undefined,
22
+ };
23
+ }
24
+ const content = readInput(args);
25
+ return { content, inputBytes: Buffer.byteLength(content, "utf-8") };
26
+ }
27
+ /** Execute the decompress subcommand. */
28
+ export function runDecompress(args) {
29
+ const { content: input, inputBytes, partPaths } = readCompressedInput(args);
30
+ const encoding = resolveEncodingOptional(args)
31
+ ? resolveEncoding(args)
32
+ : resolveDetectedEncoding(input, undefined, args.password);
33
+ const start = process.hrtime.bigint();
34
+ const { tag, data } = decompressPayload(input.trim(), encoding, args.password);
35
+ const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6;
36
+ if (tag === TAG_FOLDER) {
37
+ const outputPath = resolveOutputPath(args, "decompressed.de", ".de");
38
+ const { files, dirs, bytes } = unpackDirectory(data, outputPath);
39
+ console.log(`Decompressed folder recreated at ${outputPath}`);
40
+ printAnalytics({
41
+ Encoding: `base${encoding}`,
42
+ [`Compressed size (bytes, base${encoding})`]: inputBytes,
43
+ ...(partPaths ? { "Input parts": partPaths.length } : {}),
44
+ "Files restored": files,
45
+ "Directories restored": dirs,
46
+ "Decompressed size (bytes)": bytes,
47
+ "Time taken (ms)": elapsedMs.toFixed(3),
48
+ });
49
+ return;
50
+ }
51
+ if (tag !== TAG_TEXT) {
52
+ throw new Error(`Corrupt or unrecognized payload (tag 0x${tag.toString(16)}).`);
53
+ }
54
+ const outputPath = resolveOutputPath(args, "decompressed.de.txt", ".de.txt");
55
+ const result = data.toString("utf-8");
56
+ writeFileSync(outputPath, result, "utf-8");
57
+ const outputBytes = Buffer.byteLength(result, "utf-8");
58
+ const ratio = inputBytes === 0 ? 0 : outputBytes / inputBytes;
59
+ console.log(`Decompressed output written to ${outputPath}`);
60
+ printAnalytics({
61
+ Encoding: `base${encoding}`,
62
+ [`Compressed size (bytes, base${encoding})`]: inputBytes,
63
+ ...(partPaths ? { "Input parts": partPaths.length } : {}),
64
+ "Decompressed size (bytes)": outputBytes,
65
+ "Expansion ratio (decompressed/compressed)": ratio.toFixed(3),
66
+ "Time taken (ms)": elapsedMs.toFixed(3),
67
+ });
68
+ }
69
+ //# sourceMappingURL=decompress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../../src/cli/commands/decompress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @module cli/detect
3
+ *
4
+ * Detect whether input is a valid compressed payload for auto-routing.
5
+ */
6
+ import type { Encoding } from "../types.js";
7
+ export type DetectResult = "compressed" | "not-compressed" | "password-required";
8
+ /** True when an error means the payload is locked, not that it is plain text. */
9
+ export declare function isPasswordRelatedError(err: unknown): boolean;
10
+ /**
11
+ * Return whether trimmed encoded text is a valid compressed payload.
12
+ *
13
+ * When `-e` is omitted, both Base64 and Z85 are tried. Encrypted payloads
14
+ * without a password return `password-required` instead of `not-compressed`.
15
+ */
16
+ export declare function detectCompressedPayload(encoded: string, encoding: Encoding | undefined, password?: string): DetectResult;
17
+ /**
18
+ * Resolve the best encoding for decompress after auto-detection.
19
+ *
20
+ * When `-e` is set, use it. Otherwise return the encoding that validates.
21
+ */
22
+ export declare function resolveDetectedEncoding(encoded: string, encoding: Encoding | undefined, password?: string): Encoding;
23
+ /** Validate using the full decompress path (used when forcing decompress). */
24
+ export declare function assertDecompressible(encoded: string, encoding: Encoding, password?: string): void;
25
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/cli/detect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,gBAAgB,GAAG,mBAAmB,CAAA;AAEhF,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG5D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,YAAY,CAkCd;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,QAAQ,CAUV;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAKjG"}