roxify 1.13.0 → 1.13.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/Cargo.toml +1 -1
- package/dist/cli.js +86 -44
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/roxify-cli +0 -0
- package/dist/roxify_native.exe +0 -0
- package/dist/utils/rust-cli-wrapper.d.ts +3 -0
- package/dist/utils/rust-cli-wrapper.js +85 -55
- package/libroxify_native-x86_64-unknown-linux-gnu.node +0 -0
- package/package.json +1 -1
- package/roxify_native-x86_64-pc-windows-msvc.node +0 -0
- package/roxify_native-x86_64-unknown-linux-gnu.node +0 -0
- package/dist/rox-macos-universal +0 -0
- package/dist/roxify_native +0 -0
- package/dist/roxify_native-macos-arm64 +0 -0
- package/dist/roxify_native-macos-x64 +0 -0
- package/roxify_native-aarch64-apple-darwin.node +0 -0
- package/roxify_native-aarch64-pc-windows-msvc.node +0 -0
- package/roxify_native-aarch64-unknown-linux-gnu.node +0 -0
- package/roxify_native-i686-pc-windows-msvc.node +0 -0
- package/roxify_native-i686-unknown-linux-gnu.node +0 -0
- package/roxify_native-x86_64-apple-darwin.node +0 -0
package/Cargo.toml
CHANGED
package/dist/cli.js
CHANGED
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, } from 'fs';
|
|
3
3
|
import { open } from 'fs/promises';
|
|
4
4
|
import { basename, dirname, join, resolve } from 'path';
|
|
5
|
-
import { DataFormatError, decodePngToBinary, encodeBinaryToPng, hasPassphraseInPng, IncorrectPassphraseError, listFilesInPng, PassphraseRequiredError, } from './index.js';
|
|
6
|
-
import { packPathsGenerator, unpackBuffer } from './pack.js';
|
|
7
5
|
import * as cliProgress from './stub-progress.js';
|
|
8
|
-
import { encodeWithRustCLI, isRustBinaryAvailable, } from './utils/rust-cli-wrapper.js';
|
|
9
|
-
|
|
6
|
+
import { decodeWithRustCLI, encodeWithRustCLI, havepassphraseWithRustCLI, isRustBinaryAvailable, listWithRustCLI, } from './utils/rust-cli-wrapper.js';
|
|
7
|
+
async function loadJsEngine() {
|
|
8
|
+
const indexMod = await import('./index.js');
|
|
9
|
+
const packMod = await import('./pack.js');
|
|
10
|
+
return {
|
|
11
|
+
decodePngToBinary: indexMod.decodePngToBinary,
|
|
12
|
+
encodeBinaryToPng: indexMod.encodeBinaryToPng,
|
|
13
|
+
hasPassphraseInPng: indexMod.hasPassphraseInPng,
|
|
14
|
+
listFilesInPng: indexMod.listFilesInPng,
|
|
15
|
+
DataFormatError: indexMod.DataFormatError,
|
|
16
|
+
IncorrectPassphraseError: indexMod.IncorrectPassphraseError,
|
|
17
|
+
PassphraseRequiredError: indexMod.PassphraseRequiredError,
|
|
18
|
+
packPathsGenerator: packMod.packPathsGenerator,
|
|
19
|
+
unpackBuffer: packMod.unpackBuffer,
|
|
20
|
+
VFSIndexEntry: undefined,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const VERSION = '1.13.1';
|
|
10
24
|
function getDirectorySize(dirPath) {
|
|
11
25
|
let totalSize = 0;
|
|
12
26
|
try {
|
|
@@ -280,8 +294,9 @@ async function encodeCommand(args) {
|
|
|
280
294
|
return false;
|
|
281
295
|
}
|
|
282
296
|
});
|
|
283
|
-
if (anyDir) {
|
|
284
|
-
const
|
|
297
|
+
if (anyDir && !isRustBinaryAvailable()) {
|
|
298
|
+
const js = await loadJsEngine();
|
|
299
|
+
const { index } = await js.packPathsGenerator(inputPaths, undefined, () => { });
|
|
285
300
|
if (!index || index.length === 0) {
|
|
286
301
|
console.log(' ');
|
|
287
302
|
console.error('Error: No files found in specified input paths.');
|
|
@@ -357,6 +372,7 @@ async function encodeCommand(args) {
|
|
|
357
372
|
}
|
|
358
373
|
}
|
|
359
374
|
try {
|
|
375
|
+
const js = await loadJsEngine();
|
|
360
376
|
const encodeBar = new cliProgress.SingleBar({
|
|
361
377
|
format: ' {bar} {percentage}% | {step} | {elapsed}s',
|
|
362
378
|
}, cliProgress.Presets.shades_classic);
|
|
@@ -428,7 +444,7 @@ async function encodeCommand(args) {
|
|
|
428
444
|
};
|
|
429
445
|
if (inputPaths.length > 1) {
|
|
430
446
|
currentEncodeStep = 'Reading files';
|
|
431
|
-
const { index, stream, totalSize } = await packPathsGenerator(inputPaths, undefined, onProgress);
|
|
447
|
+
const { index, stream, totalSize } = await js.packPathsGenerator(inputPaths, undefined, onProgress);
|
|
432
448
|
if (!index || index.length === 0) {
|
|
433
449
|
console.log(' ');
|
|
434
450
|
console.error('Error: No files found in specified input paths.');
|
|
@@ -448,7 +464,7 @@ async function encodeCommand(args) {
|
|
|
448
464
|
const st = statSync(resolvedInput);
|
|
449
465
|
if (st.isDirectory()) {
|
|
450
466
|
currentEncodeStep = 'Reading files';
|
|
451
|
-
const { index, stream, totalSize } = await packPathsGenerator([resolvedInput], dirname(resolvedInput), onProgress);
|
|
467
|
+
const { index, stream, totalSize } = await js.packPathsGenerator([resolvedInput], dirname(resolvedInput), onProgress);
|
|
452
468
|
if (!index || index.length === 0) {
|
|
453
469
|
console.log(' ');
|
|
454
470
|
console.error(`Error: No files found in ${resolvedInput}`);
|
|
@@ -535,7 +551,7 @@ async function encodeCommand(args) {
|
|
|
535
551
|
else {
|
|
536
552
|
inputBuffer = inputData;
|
|
537
553
|
}
|
|
538
|
-
const output = await encodeBinaryToPng(inputBuffer, options);
|
|
554
|
+
const output = await js.encodeBinaryToPng(inputBuffer, options);
|
|
539
555
|
const encodeTime = Date.now() - startEncode;
|
|
540
556
|
clearInterval(encodeHeartbeat);
|
|
541
557
|
if (barStarted) {
|
|
@@ -574,7 +590,38 @@ async function decodeCommand(args) {
|
|
|
574
590
|
process.exit(1);
|
|
575
591
|
}
|
|
576
592
|
const resolvedInput = resolve(inputPath);
|
|
577
|
-
const resolvedOutput = parsed.output || outputPath || '
|
|
593
|
+
const resolvedOutput = parsed.output || outputPath || '.';
|
|
594
|
+
if (isRustBinaryAvailable() && !parsed.forceTs && !parsed.lossyResilient) {
|
|
595
|
+
try {
|
|
596
|
+
console.log(' ');
|
|
597
|
+
console.log('Decoding... (Using native Rust decoder)\n');
|
|
598
|
+
const startTime = Date.now();
|
|
599
|
+
const decodeBar = new cliProgress.SingleBar({ format: ' {bar} {percentage}% | {step} | {elapsed}s' }, cliProgress.Presets.shades_classic);
|
|
600
|
+
let barValue = 0;
|
|
601
|
+
decodeBar.start(100, 0, { step: 'Decoding', elapsed: '0' });
|
|
602
|
+
const progressInterval = setInterval(() => {
|
|
603
|
+
barValue = Math.min(barValue + 2, 99);
|
|
604
|
+
decodeBar.update(barValue, {
|
|
605
|
+
step: 'Decoding',
|
|
606
|
+
elapsed: String(Math.floor((Date.now() - startTime) / 1000)),
|
|
607
|
+
});
|
|
608
|
+
}, 300);
|
|
609
|
+
await decodeWithRustCLI(resolvedInput, resolvedOutput, parsed.passphrase, parsed.files, parsed.dict);
|
|
610
|
+
clearInterval(progressInterval);
|
|
611
|
+
const decodeTime = Date.now() - startTime;
|
|
612
|
+
decodeBar.update(100, { step: 'done', elapsed: String(Math.floor(decodeTime / 1000)) });
|
|
613
|
+
decodeBar.stop();
|
|
614
|
+
console.log(`\nSuccess!`);
|
|
615
|
+
console.log(` Time: ${decodeTime}ms`);
|
|
616
|
+
console.log(` Output: ${resolve(resolvedOutput)}`);
|
|
617
|
+
console.log(' ');
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
catch (err) {
|
|
621
|
+
console.warn('\nRust decoder failed, falling back to TypeScript decoder...');
|
|
622
|
+
console.warn(`Reason: ${err.message}\n`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
578
625
|
try {
|
|
579
626
|
const options = {};
|
|
580
627
|
if (parsed.passphrase) {
|
|
@@ -645,7 +692,8 @@ async function decodeCommand(args) {
|
|
|
645
692
|
}
|
|
646
693
|
};
|
|
647
694
|
const inputBuffer = await readLargeFile(resolvedInput);
|
|
648
|
-
const
|
|
695
|
+
const js = await loadJsEngine();
|
|
696
|
+
const result = await js.decodePngToBinary(inputBuffer, options);
|
|
649
697
|
const decodeTime = Date.now() - startDecode;
|
|
650
698
|
clearInterval(heartbeat);
|
|
651
699
|
if (barStarted) {
|
|
@@ -684,7 +732,7 @@ async function decodeCommand(args) {
|
|
|
684
732
|
console.log(`Time: ${decodeTime}ms`);
|
|
685
733
|
}
|
|
686
734
|
else if (result.buf) {
|
|
687
|
-
const unpacked = unpackBuffer(result.buf);
|
|
735
|
+
const unpacked = js.unpackBuffer(result.buf);
|
|
688
736
|
if (unpacked) {
|
|
689
737
|
const baseDir = parsed.output || outputPath || '.';
|
|
690
738
|
for (const file of unpacked.files) {
|
|
@@ -720,17 +768,17 @@ async function decodeCommand(args) {
|
|
|
720
768
|
console.log(' ');
|
|
721
769
|
}
|
|
722
770
|
catch (err) {
|
|
723
|
-
if (err
|
|
771
|
+
if ((err.message && err.message.includes('passphrase required')) ||
|
|
724
772
|
(err.message && err.message.includes('passphrase') && !parsed.passphrase)) {
|
|
725
773
|
console.log(' ');
|
|
726
774
|
console.error('File appears to be encrypted. Provide a passphrase with -p');
|
|
727
775
|
}
|
|
728
|
-
else if (err
|
|
776
|
+
else if ((err.message && err.message.includes('Incorrect passphrase')) ||
|
|
729
777
|
(err.message && err.message.includes('Incorrect passphrase'))) {
|
|
730
778
|
console.log(' ');
|
|
731
779
|
console.error('Incorrect passphrase');
|
|
732
780
|
}
|
|
733
|
-
else if (err
|
|
781
|
+
else if ((err.message && err.message.includes('data format error')) ||
|
|
734
782
|
(err.message &&
|
|
735
783
|
(err.message.includes('decompression failed') ||
|
|
736
784
|
err.message.includes('missing ROX1') ||
|
|
@@ -761,40 +809,25 @@ async function listCommand(args) {
|
|
|
761
809
|
const resolvedInput = resolve(inputPath);
|
|
762
810
|
if (isRustBinaryAvailable()) {
|
|
763
811
|
try {
|
|
764
|
-
const
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}
|
|
773
|
-
const output = execSync(`"${cliPath}" list "${resolvedInput}"`, {
|
|
774
|
-
encoding: 'utf-8',
|
|
775
|
-
stdio: ['pipe', 'pipe', 'inherit'],
|
|
776
|
-
timeout: 30000,
|
|
777
|
-
});
|
|
778
|
-
const fileList = JSON.parse(output.trim());
|
|
779
|
-
console.log(`Files in ${resolvedInput}:`);
|
|
780
|
-
for (const file of fileList) {
|
|
781
|
-
if (typeof file === 'string') {
|
|
782
|
-
console.log(` ${file}`);
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
console.log(` ${file.name} (${file.size} bytes)`);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
return;
|
|
812
|
+
const output = await listWithRustCLI(resolvedInput);
|
|
813
|
+
const fileList = JSON.parse(output.trim());
|
|
814
|
+
console.log(`Files in ${resolvedInput}:`);
|
|
815
|
+
for (const file of fileList) {
|
|
816
|
+
if (typeof file === 'string') {
|
|
817
|
+
console.log(` ${file}`);
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
console.log(` ${file.name} (${file.size} bytes)`);
|
|
789
821
|
}
|
|
790
|
-
catch (e) { }
|
|
791
822
|
}
|
|
823
|
+
return;
|
|
792
824
|
}
|
|
793
|
-
catch (
|
|
825
|
+
catch (e) { }
|
|
794
826
|
}
|
|
795
827
|
try {
|
|
796
828
|
const inputBuffer = readFileSync(resolvedInput);
|
|
797
|
-
const
|
|
829
|
+
const js = await loadJsEngine();
|
|
830
|
+
const fileList = await js.listFilesInPng(inputBuffer, {
|
|
798
831
|
includeSizes: parsed.sizes !== false,
|
|
799
832
|
});
|
|
800
833
|
if (fileList) {
|
|
@@ -831,9 +864,18 @@ async function havePassphraseCommand(args) {
|
|
|
831
864
|
process.exit(1);
|
|
832
865
|
}
|
|
833
866
|
const resolvedInput = resolve(inputPath);
|
|
867
|
+
if (isRustBinaryAvailable()) {
|
|
868
|
+
try {
|
|
869
|
+
const output = await havepassphraseWithRustCLI(resolvedInput);
|
|
870
|
+
console.log(output.trim());
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
catch (e) { }
|
|
874
|
+
}
|
|
834
875
|
try {
|
|
835
876
|
const inputBuffer = readFileSync(resolvedInput);
|
|
836
|
-
const
|
|
877
|
+
const js = await loadJsEngine();
|
|
878
|
+
const has = await js.hasPassphraseInPng(inputBuffer);
|
|
837
879
|
console.log(has ? 'Passphrase detected.' : 'No passphrase detected.');
|
|
838
880
|
}
|
|
839
881
|
catch (err) {
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export * from './utils/optimization.js';
|
|
|
12
12
|
export * from './utils/reconstitution.js';
|
|
13
13
|
export * from './utils/robust-audio.js';
|
|
14
14
|
export * from './utils/robust-image.js';
|
|
15
|
-
export { encodeWithRustCLI, isRustBinaryAvailable } from './utils/rust-cli-wrapper.js';
|
|
15
|
+
export { decodeWithRustCLI, encodeWithRustCLI, havepassphraseWithRustCLI, isRustBinaryAvailable, listWithRustCLI, } from './utils/rust-cli-wrapper.js';
|
|
16
16
|
export * from './utils/types.js';
|
|
17
17
|
export * from './utils/zstd.js';
|
|
18
18
|
export { packPaths, packPathsToParts, unpackBuffer } from './pack.js';
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ export * from './utils/optimization.js';
|
|
|
12
12
|
export * from './utils/reconstitution.js';
|
|
13
13
|
export * from './utils/robust-audio.js';
|
|
14
14
|
export * from './utils/robust-image.js';
|
|
15
|
-
export { encodeWithRustCLI, isRustBinaryAvailable } from './utils/rust-cli-wrapper.js';
|
|
15
|
+
export { decodeWithRustCLI, encodeWithRustCLI, havepassphraseWithRustCLI, isRustBinaryAvailable, listWithRustCLI, } from './utils/rust-cli-wrapper.js';
|
|
16
16
|
export * from './utils/types.js';
|
|
17
17
|
export * from './utils/zstd.js';
|
|
18
18
|
export { packPaths, packPathsToParts, unpackBuffer } from './pack.js';
|
package/dist/roxify-cli
ADDED
|
Binary file
|
package/dist/roxify_native.exe
CHANGED
|
Binary file
|
|
@@ -2,3 +2,6 @@ declare function findRustBinary(): string | null;
|
|
|
2
2
|
export { findRustBinary };
|
|
3
3
|
export declare function isRustBinaryAvailable(): boolean;
|
|
4
4
|
export declare function encodeWithRustCLI(inputPath: string, outputPath: string, compressionLevel?: number, passphrase?: string, encryptType?: 'aes' | 'xor', name?: string): Promise<void>;
|
|
5
|
+
export declare function decodeWithRustCLI(inputPath: string, outputPath: string, passphrase?: string, files?: string[], dict?: string): Promise<void>;
|
|
6
|
+
export declare function listWithRustCLI(inputPath: string): Promise<string>;
|
|
7
|
+
export declare function havepassphraseWithRustCLI(inputPath: string): Promise<string>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execSync, spawn } from 'child_process';
|
|
2
|
-
import { existsSync } from 'fs';
|
|
2
|
+
import { accessSync, constants, existsSync } from 'fs';
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
let moduleDir;
|
|
@@ -14,6 +14,19 @@ else {
|
|
|
14
14
|
moduleDir = process.cwd();
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
function canExecute(p) {
|
|
18
|
+
if (!existsSync(p))
|
|
19
|
+
return false;
|
|
20
|
+
if (process.platform === 'win32')
|
|
21
|
+
return true;
|
|
22
|
+
try {
|
|
23
|
+
accessSync(p, constants.X_OK);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
17
30
|
function findRustBinary() {
|
|
18
31
|
const platformBins = {
|
|
19
32
|
win32: ['roxify_native.exe', 'roxify-cli.exe', 'roxify_cli.exe'],
|
|
@@ -24,13 +37,13 @@ function findRustBinary() {
|
|
|
24
37
|
const baseDir = moduleDir;
|
|
25
38
|
for (const name of binNames) {
|
|
26
39
|
const sameDirPath = join(baseDir, name);
|
|
27
|
-
if (
|
|
40
|
+
if (canExecute(sameDirPath))
|
|
28
41
|
return sameDirPath;
|
|
29
42
|
const parentPath = join(baseDir, '..', name);
|
|
30
|
-
if (
|
|
43
|
+
if (canExecute(parentPath))
|
|
31
44
|
return parentPath;
|
|
32
45
|
const parentDistPath = join(baseDir, '..', 'dist', name);
|
|
33
|
-
if (
|
|
46
|
+
if (canExecute(parentDistPath))
|
|
34
47
|
return parentDistPath;
|
|
35
48
|
}
|
|
36
49
|
if (process.pkg) {
|
|
@@ -42,7 +55,7 @@ function findRustBinary() {
|
|
|
42
55
|
for (const basePath of snapshotPaths) {
|
|
43
56
|
for (const name of binNames) {
|
|
44
57
|
const binPath = join(basePath, name);
|
|
45
|
-
if (
|
|
58
|
+
if (canExecute(binPath))
|
|
46
59
|
return binPath;
|
|
47
60
|
}
|
|
48
61
|
}
|
|
@@ -58,7 +71,7 @@ function findRustBinary() {
|
|
|
58
71
|
for (const c of execCandidates) {
|
|
59
72
|
for (const name of binNames) {
|
|
60
73
|
const p = join(c, name);
|
|
61
|
-
if (
|
|
74
|
+
if (canExecute(p))
|
|
62
75
|
return p;
|
|
63
76
|
}
|
|
64
77
|
}
|
|
@@ -97,7 +110,7 @@ function findRustBinary() {
|
|
|
97
110
|
for (const c of candidates) {
|
|
98
111
|
for (const name of binNames) {
|
|
99
112
|
const candidate = join(c, name);
|
|
100
|
-
if (
|
|
113
|
+
if (canExecute(candidate))
|
|
101
114
|
return candidate;
|
|
102
115
|
}
|
|
103
116
|
}
|
|
@@ -108,16 +121,16 @@ function findRustBinary() {
|
|
|
108
121
|
catch { }
|
|
109
122
|
for (const name of binNames) {
|
|
110
123
|
const parentParentLocal = join(baseDir, '..', '..', name);
|
|
111
|
-
if (
|
|
124
|
+
if (canExecute(parentParentLocal))
|
|
112
125
|
return parentParentLocal;
|
|
113
126
|
const nodeModulesPath = join(baseDir, '..', '..', '..', '..', name);
|
|
114
|
-
if (
|
|
127
|
+
if (canExecute(nodeModulesPath))
|
|
115
128
|
return nodeModulesPath;
|
|
116
129
|
}
|
|
117
130
|
const targetRelease = join(baseDir, '..', '..', 'target', 'release');
|
|
118
131
|
for (const name of binNames) {
|
|
119
132
|
const targetPath = join(targetRelease, name);
|
|
120
|
-
if (
|
|
133
|
+
if (canExecute(targetPath))
|
|
121
134
|
return targetPath;
|
|
122
135
|
}
|
|
123
136
|
return null;
|
|
@@ -128,52 +141,32 @@ export function isRustBinaryAvailable() {
|
|
|
128
141
|
}
|
|
129
142
|
import { chmodSync, mkdtempSync, readFileSync, unlinkSync, writeFileSync, } from 'fs';
|
|
130
143
|
import { tmpdir } from 'os';
|
|
131
|
-
|
|
144
|
+
function extractToTemp(pathToRead) {
|
|
145
|
+
const buf = readFileSync(pathToRead);
|
|
146
|
+
const tmp = mkdtempSync(join(tmpdir(), 'roxify-'));
|
|
147
|
+
const dest = join(tmp, pathToRead.replace(/.*[\\/]/, ''));
|
|
148
|
+
writeFileSync(dest, buf);
|
|
149
|
+
try {
|
|
150
|
+
chmodSync(dest, 0o755);
|
|
151
|
+
}
|
|
152
|
+
catch (e) { }
|
|
153
|
+
return dest;
|
|
154
|
+
}
|
|
155
|
+
function spawnRustCLI(args, options) {
|
|
132
156
|
const cliPath = findRustBinary();
|
|
133
|
-
if (!cliPath)
|
|
157
|
+
if (!cliPath)
|
|
134
158
|
throw new Error('Rust CLI binary not found');
|
|
135
|
-
}
|
|
136
|
-
function extractToTemp(pathToRead) {
|
|
137
|
-
const buf = readFileSync(pathToRead);
|
|
138
|
-
const tmp = mkdtempSync(join(tmpdir(), 'roxify-'));
|
|
139
|
-
const dest = join(tmp, pathToRead.replace(/.*[\\/]/, ''));
|
|
140
|
-
writeFileSync(dest, buf);
|
|
141
|
-
try {
|
|
142
|
-
chmodSync(dest, 0o755);
|
|
143
|
-
}
|
|
144
|
-
catch (e) { }
|
|
145
|
-
return dest;
|
|
146
|
-
}
|
|
147
159
|
return new Promise((resolve, reject) => {
|
|
148
|
-
const args = ['encode', '--level', String(compressionLevel)];
|
|
149
|
-
let supportsName = false;
|
|
150
|
-
if (name) {
|
|
151
|
-
try {
|
|
152
|
-
const helpOut = execSync(`"${cliPath}" --help`, {
|
|
153
|
-
encoding: 'utf8',
|
|
154
|
-
timeout: 2000,
|
|
155
|
-
});
|
|
156
|
-
if (helpOut && helpOut.includes('--name'))
|
|
157
|
-
supportsName = true;
|
|
158
|
-
}
|
|
159
|
-
catch (e) {
|
|
160
|
-
supportsName = false;
|
|
161
|
-
}
|
|
162
|
-
if (supportsName) {
|
|
163
|
-
args.push('--name', name);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (passphrase) {
|
|
167
|
-
args.push('--passphrase', passphrase);
|
|
168
|
-
args.push('--encrypt', encryptType);
|
|
169
|
-
}
|
|
170
|
-
args.push(inputPath, outputPath);
|
|
171
160
|
let triedExtract = false;
|
|
172
161
|
let tempExe;
|
|
162
|
+
let stdout = '';
|
|
173
163
|
const runSpawn = (exePath) => {
|
|
174
164
|
let proc;
|
|
165
|
+
const stdio = options?.collectStdout
|
|
166
|
+
? ['pipe', 'pipe', 'inherit']
|
|
167
|
+
: 'inherit';
|
|
175
168
|
try {
|
|
176
|
-
proc = spawn(exePath, args, { stdio
|
|
169
|
+
proc = spawn(exePath, args, { stdio });
|
|
177
170
|
}
|
|
178
171
|
catch (err) {
|
|
179
172
|
if (!triedExtract) {
|
|
@@ -188,6 +181,9 @@ export async function encodeWithRustCLI(inputPath, outputPath, compressionLevel
|
|
|
188
181
|
}
|
|
189
182
|
return reject(err);
|
|
190
183
|
}
|
|
184
|
+
if (options?.collectStdout && proc.stdout) {
|
|
185
|
+
proc.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
|
|
186
|
+
}
|
|
191
187
|
proc.on('error', (err) => {
|
|
192
188
|
if (!triedExtract) {
|
|
193
189
|
triedExtract = true;
|
|
@@ -201,21 +197,55 @@ export async function encodeWithRustCLI(inputPath, outputPath, compressionLevel
|
|
|
201
197
|
}
|
|
202
198
|
reject(err);
|
|
203
199
|
});
|
|
204
|
-
proc.on('close', (code) => {
|
|
200
|
+
proc.on('close', (code, signal) => {
|
|
205
201
|
if (tempExe) {
|
|
206
202
|
try {
|
|
207
203
|
unlinkSync(tempExe);
|
|
208
204
|
}
|
|
209
205
|
catch (e) { }
|
|
210
206
|
}
|
|
211
|
-
if (code === 0)
|
|
212
|
-
resolve();
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
reject(new Error(`Rust encoder exited with status ${code}`));
|
|
216
|
-
}
|
|
207
|
+
if (code === 0 || (code === null && signal === null))
|
|
208
|
+
resolve(stdout);
|
|
209
|
+
else
|
|
210
|
+
reject(new Error(`Rust CLI exited with status ${code ?? signal}`));
|
|
217
211
|
});
|
|
218
212
|
};
|
|
219
213
|
runSpawn(cliPath);
|
|
220
214
|
});
|
|
221
215
|
}
|
|
216
|
+
export async function encodeWithRustCLI(inputPath, outputPath, compressionLevel = 3, passphrase, encryptType = 'aes', name) {
|
|
217
|
+
const cliPath = findRustBinary();
|
|
218
|
+
if (!cliPath)
|
|
219
|
+
throw new Error('Rust CLI binary not found');
|
|
220
|
+
const args = ['encode', '--level', String(compressionLevel)];
|
|
221
|
+
if (name) {
|
|
222
|
+
try {
|
|
223
|
+
const helpOut = execSync(`"${cliPath}" --help`, { encoding: 'utf8', timeout: 2000 });
|
|
224
|
+
if (helpOut && helpOut.includes('--name'))
|
|
225
|
+
args.push('--name', name);
|
|
226
|
+
}
|
|
227
|
+
catch (e) { }
|
|
228
|
+
}
|
|
229
|
+
if (passphrase) {
|
|
230
|
+
args.push('--passphrase', passphrase);
|
|
231
|
+
args.push('--encrypt', encryptType);
|
|
232
|
+
}
|
|
233
|
+
args.push(inputPath, outputPath);
|
|
234
|
+
await spawnRustCLI(args);
|
|
235
|
+
}
|
|
236
|
+
export async function decodeWithRustCLI(inputPath, outputPath, passphrase, files, dict) {
|
|
237
|
+
const args = ['decompress', inputPath, outputPath];
|
|
238
|
+
if (passphrase)
|
|
239
|
+
args.push('--passphrase', passphrase);
|
|
240
|
+
if (files && files.length > 0)
|
|
241
|
+
args.push('--files', JSON.stringify(files));
|
|
242
|
+
if (dict)
|
|
243
|
+
args.push('--dict', dict);
|
|
244
|
+
await spawnRustCLI(args);
|
|
245
|
+
}
|
|
246
|
+
export async function listWithRustCLI(inputPath) {
|
|
247
|
+
return spawnRustCLI(['list', inputPath], { collectStdout: true });
|
|
248
|
+
}
|
|
249
|
+
export async function havepassphraseWithRustCLI(inputPath) {
|
|
250
|
+
return spawnRustCLI(['havepassphrase', inputPath], { collectStdout: true });
|
|
251
|
+
}
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
package/dist/rox-macos-universal
DELETED
|
Binary file
|
package/dist/roxify_native
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|