roxify 1.9.0 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "roxify_native"
3
- version = "1.9.0"
3
+ version = "1.9.2"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import { DataFormatError, decodePngToBinary, encodeBinaryToPng, hasPassphraseInP
6
6
  import { packPathsGenerator, unpackBuffer } from './pack.js';
7
7
  import * as cliProgress from './stub-progress.js';
8
8
  import { encodeWithRustCLI, isRustBinaryAvailable, } from './utils/rust-cli-wrapper.js';
9
- const VERSION = '1.8.0';
9
+ const VERSION = '1.9.2';
10
10
  function getDirectorySize(dirPath) {
11
11
  let totalSize = 0;
12
12
  try {
Binary file
@@ -72,15 +72,7 @@ function getNativeModule() {
72
72
  for (const triple of triples) {
73
73
  const name = `roxify_native-${triple}.node`;
74
74
  const libName = `libroxify_native-${triple}.node`;
75
- candidates.push(
76
- // dist/ sibling (npm-installed package)
77
- resolve(moduleDir, '..', name), resolve(moduleDir, '..', libName),
78
- // package root
79
- resolve(root, name), resolve(root, libName),
80
- // node_modules/roxify/
81
- resolve(root, 'node_modules', 'roxify', name), resolve(root, 'node_modules', 'roxify', libName),
82
- // two levels up (global npm install)
83
- resolve(moduleDir, '..', '..', name), resolve(moduleDir, '..', '..', libName));
75
+ candidates.push(resolve(moduleDir, '..', name), resolve(moduleDir, '..', libName), resolve(root, name), resolve(root, libName), resolve(root, 'node_modules', 'roxify', name), resolve(root, 'node_modules', 'roxify', libName), resolve(moduleDir, '..', '..', name), resolve(moduleDir, '..', '..', libName));
84
76
  }
85
77
  // --- 2. Build output candidates (local dev) ---
86
78
  for (const triple of triples) {
@@ -1,18 +1,35 @@
1
1
  import { execSync, spawn } from 'child_process';
2
2
  import { existsSync } from 'fs';
3
3
  import { dirname, join } from 'path';
4
+ import { fileURLToPath } from 'url';
4
5
  let moduleDir;
5
6
  if (typeof __dirname !== 'undefined') {
6
7
  moduleDir = __dirname;
7
8
  }
8
9
  else {
9
- moduleDir = process.cwd();
10
+ try {
11
+ moduleDir = dirname(fileURLToPath(import.meta.url));
12
+ }
13
+ catch {
14
+ moduleDir = process.cwd();
15
+ }
10
16
  }
11
17
  function findRustBinary() {
12
18
  const binNames = process.platform === 'win32'
13
19
  ? ['roxify_native.exe', 'roxify-cli.exe', 'roxify_cli.exe']
14
20
  : ['roxify_native', 'roxify-cli', 'roxify_cli'];
15
- const baseDir = typeof moduleDir !== 'undefined' ? moduleDir : process.cwd();
21
+ const baseDir = moduleDir;
22
+ for (const name of binNames) {
23
+ const sameDirPath = join(baseDir, name);
24
+ if (existsSync(sameDirPath))
25
+ return sameDirPath;
26
+ const parentPath = join(baseDir, '..', name);
27
+ if (existsSync(parentPath))
28
+ return parentPath;
29
+ const parentDistPath = join(baseDir, '..', 'dist', name);
30
+ if (existsSync(parentDistPath))
31
+ return parentDistPath;
32
+ }
16
33
  if (process.pkg) {
17
34
  const snapshotPaths = [
18
35
  join(baseDir, '..', '..', 'target', 'release'),
@@ -22,9 +39,8 @@ function findRustBinary() {
22
39
  for (const basePath of snapshotPaths) {
23
40
  for (const name of binNames) {
24
41
  const binPath = join(basePath, name);
25
- if (existsSync(binPath)) {
42
+ if (existsSync(binPath))
26
43
  return binPath;
27
- }
28
44
  }
29
45
  }
30
46
  try {
@@ -35,40 +51,35 @@ function findRustBinary() {
35
51
  join(execDir, 'tools', 'roxify'),
36
52
  join(execDir, '..', 'tools', 'roxify', 'dist'),
37
53
  join(execDir, '..', 'tools', 'roxify'),
38
- join(execDir, 'tools', 'roxify', 'roxify_native.exe'),
39
54
  ];
40
55
  for (const c of execCandidates) {
41
56
  for (const name of binNames) {
42
- const p = c.endsWith(name) ? c : join(c, name);
43
- if (existsSync(p)) {
57
+ const p = join(c, name);
58
+ if (existsSync(p))
44
59
  return p;
45
- }
46
60
  }
47
61
  }
48
62
  }
49
63
  }
50
- catch (e) { }
64
+ catch { }
51
65
  }
52
66
  try {
53
67
  let paths = [];
54
68
  if (process.platform === 'win32') {
55
69
  try {
56
- const out = execSync('where rox', { encoding: 'utf-8' }).trim();
70
+ const out = execSync('where rox', { encoding: 'utf-8', timeout: 5000 }).trim();
57
71
  if (out)
58
- paths = out
59
- .split(/\r?\n/)
60
- .map((s) => s.trim())
61
- .filter(Boolean);
72
+ paths = out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
62
73
  }
63
- catch (e) { }
74
+ catch { }
64
75
  }
65
76
  else {
66
77
  try {
67
- const out = execSync('which rox', { encoding: 'utf-8' }).trim();
78
+ const out = execSync('which rox', { encoding: 'utf-8', timeout: 5000 }).trim();
68
79
  if (out)
69
80
  paths = [out.trim()];
70
81
  }
71
- catch (e) { }
82
+ catch { }
72
83
  }
73
84
  for (const p of paths) {
74
85
  try {
@@ -78,44 +89,33 @@ function findRustBinary() {
78
89
  join(d, 'dist'),
79
90
  join(d, '..', 'dist'),
80
91
  join(d, '..'),
92
+ join(d, 'node_modules', 'roxify', 'dist'),
81
93
  ];
82
94
  for (const c of candidates) {
83
95
  for (const name of binNames) {
84
96
  const candidate = join(c, name);
85
- if (existsSync(candidate)) {
97
+ if (existsSync(candidate))
86
98
  return candidate;
87
- }
88
99
  }
89
100
  }
90
101
  }
91
- catch (e) { }
102
+ catch { }
92
103
  }
93
104
  }
94
- catch (e) { }
105
+ catch { }
95
106
  for (const name of binNames) {
96
- const local = join(baseDir, name);
97
- if (existsSync(local)) {
98
- return local;
99
- }
100
- const parentLocal = join(baseDir, '..', name);
101
- if (existsSync(parentLocal)) {
102
- return parentLocal;
103
- }
104
107
  const parentParentLocal = join(baseDir, '..', '..', name);
105
- if (existsSync(parentParentLocal)) {
108
+ if (existsSync(parentParentLocal))
106
109
  return parentParentLocal;
107
- }
108
110
  const nodeModulesPath = join(baseDir, '..', '..', '..', '..', name);
109
- if (existsSync(nodeModulesPath)) {
111
+ if (existsSync(nodeModulesPath))
110
112
  return nodeModulesPath;
111
- }
112
113
  }
113
114
  const targetRelease = join(baseDir, '..', '..', 'target', 'release');
114
115
  for (const name of binNames) {
115
116
  const targetPath = join(targetRelease, name);
116
- if (existsSync(targetPath)) {
117
+ if (existsSync(targetPath))
117
118
  return targetPath;
118
- }
119
119
  }
120
120
  return null;
121
121
  }
@@ -160,6 +160,14 @@ fn decode_to_rgb(png_data: &[u8]) -> Result<Vec<u8>, String> {
160
160
  }
161
161
 
162
162
  pub fn extract_name_from_png(png_data: &[u8]) -> Option<String> {
163
+ if let Some(name) = extract_name_direct(png_data) {
164
+ return Some(name);
165
+ }
166
+ let reconst = crate::reconstitution::crop_and_reconstitute(png_data).ok()?;
167
+ extract_name_direct(&reconst)
168
+ }
169
+
170
+ fn extract_name_direct(png_data: &[u8]) -> Option<String> {
163
171
  let raw = decode_to_rgb(png_data).ok()?;
164
172
  let pos = find_pixel_header(&raw).ok()?;
165
173
  let mut idx = pos + 4;
@@ -192,13 +200,15 @@ fn extract_payload_direct(png_data: &[u8]) -> Result<Vec<u8>, String> {
192
200
  }
193
201
 
194
202
  pub fn extract_file_list_from_pixels(png_data: &[u8]) -> Result<String, String> {
195
- let raw = match decode_to_rgb(png_data) {
196
- Ok(r) => r,
197
- Err(_) => {
198
- let reconst = crate::reconstitution::crop_and_reconstitute(png_data)?;
199
- decode_to_rgb(&reconst)?
200
- }
201
- };
203
+ if let Ok(result) = extract_file_list_direct(png_data) {
204
+ return Ok(result);
205
+ }
206
+ let reconst = crate::reconstitution::crop_and_reconstitute(png_data)?;
207
+ extract_file_list_direct(&reconst)
208
+ }
209
+
210
+ fn extract_file_list_direct(png_data: &[u8]) -> Result<String, String> {
211
+ let raw = decode_to_rgb(png_data)?;
202
212
  let pos = find_pixel_header(&raw)?;
203
213
  let mut idx = pos + 4;
204
214
  if idx + 2 > raw.len() { return Err("Truncated header".to_string()); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roxify",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "type": "module",
5
5
  "description": "Ultra-lightweight PNG steganography with native Rust acceleration. Encode binary data into PNG images with zstd compression.",
6
6
  "main": "dist/index.js",
@@ -11,8 +11,6 @@
11
11
  },
12
12
  "files": [
13
13
  "dist",
14
- "roxify_native.node",
15
- "libroxify_native.node",
16
14
  "roxify_native-x86_64-unknown-linux-gnu.node",
17
15
  "roxify_native-i686-unknown-linux-gnu.node",
18
16
  "roxify_native-aarch64-unknown-linux-gnu.node",
@@ -1,6 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
  const { existsSync, copyFileSync, mkdirSync } = require('fs');
3
- const { join, dirname } = require('path');
3
+ const { join } = require('path');
4
+ const { platform, arch } = require('os');
4
5
 
5
6
  const root = join(__dirname, '..');
6
7
  const distDir = join(root, 'dist');
@@ -12,90 +13,149 @@ function hasCargo() {
12
13
  } catch { return false; }
13
14
  }
14
15
 
16
+ function getTriples() {
17
+ const os = platform();
18
+ const cpu = arch();
19
+ const map = {
20
+ linux: { x64: ['x86_64-unknown-linux-gnu'], arm64: ['aarch64-unknown-linux-gnu'] },
21
+ win32: { x64: ['x86_64-pc-windows-msvc', 'x86_64-pc-windows-gnu'], arm64: ['aarch64-pc-windows-msvc'] },
22
+ darwin: { x64: ['x86_64-apple-darwin'], arm64: ['aarch64-apple-darwin'] },
23
+ };
24
+ return (map[os] && map[os][cpu]) || [];
25
+ }
26
+
27
+ function getLibExt() {
28
+ if (platform() === 'win32') return 'dll';
29
+ if (platform() === 'darwin') return 'dylib';
30
+ return 'so';
31
+ }
32
+
15
33
  function getBinaryName() {
16
- return process.platform === 'win32' ? 'roxify_native.exe' : 'roxify_native';
34
+ return platform() === 'win32' ? 'roxify_native.exe' : 'roxify_native';
17
35
  }
18
36
 
19
37
  function findExistingBinary() {
20
38
  const name = getBinaryName();
21
- const candidates = [
22
- join(distDir, name),
23
- join(root, 'target', 'release', name),
24
- ];
25
-
26
- if (process.platform === 'win32') {
27
- candidates.push(join(root, 'target', 'x86_64-pc-windows-gnu', 'release', name));
28
- candidates.push(join(root, 'target', 'x86_64-pc-windows-msvc', 'release', name));
29
- } else if (process.platform === 'linux') {
30
- candidates.push(join(root, 'target', 'x86_64-unknown-linux-gnu', 'release', name));
31
- } else if (process.platform === 'darwin') {
32
- candidates.push(join(root, 'target', 'x86_64-apple-darwin', 'release', name));
33
- candidates.push(join(root, 'target', 'aarch64-apple-darwin', 'release', name));
39
+ const triples = getTriples();
40
+ const candidates = [join(distDir, name), join(root, 'target', 'release', name)];
41
+ for (const t of triples) {
42
+ candidates.push(join(root, 'target', t, 'release', name));
34
43
  }
35
-
36
44
  for (const c of candidates) {
37
45
  if (existsSync(c)) return c;
38
46
  }
39
47
  return null;
40
48
  }
41
49
 
50
+ function findExistingNativeLib() {
51
+ const triples = getTriples();
52
+ const ext = getLibExt();
53
+ const prefix = platform() === 'win32' ? '' : 'lib';
54
+ for (const t of triples) {
55
+ const specific = join(root, `roxify_native-${t}.node`);
56
+ if (existsSync(specific)) return { path: specific, triple: t };
57
+ }
58
+ for (const t of triples) {
59
+ for (const profile of ['release', 'fastdev']) {
60
+ const paths = [
61
+ join(root, 'target', t, profile, `${prefix}roxify_native.${ext}`),
62
+ join(root, 'target', profile, `${prefix}roxify_native.${ext}`),
63
+ ];
64
+ for (const p of paths) {
65
+ if (existsSync(p)) return { path: p, triple: t };
66
+ }
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+
72
+ function buildNative(target) {
73
+ if (!hasCargo()) return false;
74
+ const args = target ? ` --target ${target}` : '';
75
+ console.log(`roxify: Building native lib${args}...`);
76
+ try {
77
+ execSync(`cargo build --release --lib${args}`, { cwd: root, stdio: 'inherit', timeout: 600000 });
78
+ return true;
79
+ } catch {
80
+ console.log('roxify: Native lib build failed');
81
+ return false;
82
+ }
83
+ }
84
+
42
85
  function buildBinary() {
43
86
  if (!hasCargo()) {
44
- console.log('roxify: Cargo not found, skipping native binary build (TypeScript fallback will be used)');
87
+ console.log('roxify: Cargo not found, skipping native build (TypeScript fallback will be used)');
45
88
  return false;
46
89
  }
47
-
48
- console.log('roxify: Building native CLI binary with Cargo...');
90
+ console.log('roxify: Building native CLI binary...');
49
91
  try {
50
- execSync('cargo build --release --bin roxify_native', {
51
- cwd: root,
52
- stdio: 'inherit',
53
- timeout: 600000,
54
- });
92
+ execSync('cargo build --release --bin roxify_native', { cwd: root, stdio: 'inherit', timeout: 600000 });
55
93
  return true;
56
- } catch (e) {
94
+ } catch {
57
95
  console.log('roxify: Native build failed, TypeScript fallback will be used');
58
96
  return false;
59
97
  }
60
98
  }
61
99
 
62
- function run() {
63
- if (!existsSync(distDir)) {
64
- mkdirSync(distDir, { recursive: true });
65
- }
66
-
100
+ function ensureCliBinary() {
101
+ if (!existsSync(distDir)) mkdirSync(distDir, { recursive: true });
67
102
  const dest = join(distDir, getBinaryName());
68
- if (existsSync(dest)) {
69
- return;
70
- }
103
+ if (existsSync(dest)) return;
71
104
 
72
105
  const existing = findExistingBinary();
73
106
  if (existing && existing !== dest) {
74
107
  copyFileSync(existing, dest);
75
- if (process.platform !== 'win32') {
76
- try { require('fs').chmodSync(dest, 0o755); } catch { }
108
+ if (platform() !== 'win32') {
109
+ try { require('fs').chmodSync(dest, 0o755); } catch {}
77
110
  }
78
- console.log(`roxify: Copied native binary from ${existing}`);
111
+ console.log(`roxify: Copied CLI binary from ${existing}`);
79
112
  return;
80
113
  }
81
-
82
114
  if (existing) return;
83
-
84
- if (process.env.ROXIFY_SKIP_BUILD === '1') {
85
- console.log('roxify: ROXIFY_SKIP_BUILD=1, skipping native build');
86
- return;
87
- }
115
+ if (process.env.ROXIFY_SKIP_BUILD === '1') return;
88
116
 
89
117
  if (buildBinary()) {
90
118
  const built = join(root, 'target', 'release', getBinaryName());
91
119
  if (existsSync(built)) {
92
120
  copyFileSync(built, dest);
93
- if (process.platform !== 'win32') {
94
- try { require('fs').chmodSync(dest, 0o755); } catch { }
121
+ if (platform() !== 'win32') {
122
+ try { require('fs').chmodSync(dest, 0o755); } catch {}
95
123
  }
96
- console.log('roxify: Native binary built and copied to dist/');
124
+ console.log('roxify: CLI binary built and copied to dist/');
125
+ }
126
+ }
127
+ }
128
+
129
+ function ensureNativeLib() {
130
+ const triples = getTriples();
131
+ if (!triples.length) return;
132
+
133
+ for (const t of triples) {
134
+ if (existsSync(join(root, `roxify_native-${t}.node`))) return;
135
+ }
136
+
137
+ const found = findExistingNativeLib();
138
+ if (found) {
139
+ const dest = join(root, `roxify_native-${found.triple}.node`);
140
+ copyFileSync(found.path, dest);
141
+ console.log(`roxify: Copied native lib → ${dest}`);
142
+ return;
143
+ }
144
+
145
+ if (process.env.ROXIFY_SKIP_BUILD === '1') return;
146
+
147
+ const triple = triples[0];
148
+ if (buildNative(null)) {
149
+ const ext = getLibExt();
150
+ const prefix = platform() === 'win32' ? '' : 'lib';
151
+ const built = join(root, 'target', 'release', `${prefix}roxify_native.${ext}`);
152
+ if (existsSync(built)) {
153
+ const dest = join(root, `roxify_native-${triple}.node`);
154
+ copyFileSync(built, dest);
155
+ console.log(`roxify: Native lib built → ${dest}`);
97
156
  }
98
157
  }
99
158
  }
100
159
 
101
- run();
160
+ ensureCliBinary();
161
+ ensureNativeLib();
Binary file