roxify 1.7.0 → 1.7.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.
@@ -1,13 +1,44 @@
1
- import { existsSync } from 'fs';
1
+ import { copyFileSync, existsSync } from 'fs';
2
2
  import { createRequire } from 'module';
3
3
  import { arch, platform } from 'os';
4
- import { dirname, join, resolve } from 'path';
4
+ import { dirname, resolve } from 'path';
5
5
  import { fileURLToPath } from 'url';
6
+ /**
7
+ * Returns the Rust target triple(s) for the current OS + architecture.
8
+ * Multiple triples are returned when there are alternative toolchains
9
+ * (e.g. windows-msvc and windows-gnu).
10
+ */
11
+ function getTargetTriples() {
12
+ const os = platform();
13
+ const cpu = arch();
14
+ const map = {
15
+ linux: {
16
+ x64: ['x86_64-unknown-linux-gnu'],
17
+ ia32: ['i686-unknown-linux-gnu'],
18
+ arm64: ['aarch64-unknown-linux-gnu'],
19
+ arm: ['armv7-unknown-linux-gnueabihf'],
20
+ },
21
+ win32: {
22
+ x64: ['x86_64-pc-windows-msvc', 'x86_64-pc-windows-gnu'],
23
+ ia32: ['i686-pc-windows-msvc', 'i686-pc-windows-gnu'],
24
+ arm64: ['aarch64-pc-windows-msvc'],
25
+ },
26
+ darwin: {
27
+ x64: ['x86_64-apple-darwin'],
28
+ arm64: ['aarch64-apple-darwin'],
29
+ },
30
+ };
31
+ const archMap = map[os];
32
+ if (!archMap)
33
+ throw new Error(`Unsupported OS: ${os}`);
34
+ const triples = archMap[cpu];
35
+ if (!triples)
36
+ throw new Error(`Unsupported architecture: ${os}-${cpu}`);
37
+ return triples;
38
+ }
6
39
  function getNativeModule() {
7
40
  let moduleDir;
8
41
  let nativeRequire;
9
- // In ESM, __dirname is not available — derive it from import.meta.url
10
- // which always points to the actual file location on disk.
11
42
  const esmFilename = fileURLToPath(import.meta.url);
12
43
  const esmDirname = dirname(esmFilename);
13
44
  if (typeof __dirname !== 'undefined') {
@@ -24,32 +55,8 @@ function getNativeModule() {
24
55
  }
25
56
  }
26
57
  function getNativePath() {
27
- const platformMap = {
28
- linux: 'x86_64-unknown-linux-gnu',
29
- darwin: arch() === 'arm64' ? 'aarch64-apple-darwin' : 'x86_64-apple-darwin',
30
- win32: 'x86_64-pc-windows-gnu',
31
- };
32
- const platformAltMap = {
33
- win32: 'x86_64-pc-windows-msvc',
34
- };
35
- const extMap = {
36
- linux: 'so',
37
- darwin: 'dylib',
38
- win32: 'node',
39
- };
40
- const currentPlatform = platform();
41
- const target = platformMap[currentPlatform];
42
- const targetAlt = platformAltMap[currentPlatform];
43
- const ext = extMap[currentPlatform];
44
- if (!target || !ext) {
45
- throw new Error(`Unsupported platform: ${currentPlatform}`);
46
- }
47
- const prebuiltPath = join(moduleDir, '../../roxify_native.node');
48
- const prebuiltLibPath = join(moduleDir, '../../libroxify_native.node');
49
- const bundlePath = join(moduleDir, '../roxify_native.node');
50
- const bundleLibPath = join(moduleDir, '../libroxify_native.node');
51
- const bundlePathWithTarget = join(moduleDir, `../roxify_native-${target}.node`);
52
- const bundleLibPathWithTarget = join(moduleDir, `../libroxify_native-${target}.node`);
58
+ const triples = getTargetTriples();
59
+ // Walk up to find repository / package root
53
60
  let root = moduleDir && moduleDir !== '.' ? moduleDir : process.cwd();
54
61
  while (root.length > 1 &&
55
62
  !existsSync(resolve(root, 'package.json')) &&
@@ -59,50 +66,72 @@ function getNativeModule() {
59
66
  break;
60
67
  root = parent;
61
68
  }
62
- const bundleNode = resolve(moduleDir, '../roxify_native.node');
63
- const bundleLibNode = resolve(moduleDir, '../libroxify_native.node');
64
- const bundleNodeWithTarget = resolve(moduleDir, `../roxify_native-${target}.node`);
65
- const bundleLibNodeWithTarget = resolve(moduleDir, `../libroxify_native-${target}.node`);
66
- const repoNode = resolve(root, 'roxify_native.node');
67
- const repoLibNode = resolve(root, 'libroxify_native.node');
68
- const repoNodeWithTarget = resolve(root, `roxify_native-${target}.node`);
69
- const repoLibNodeWithTarget = resolve(root, `libroxify_native-${target}.node`);
70
- const targetNode = resolve(root, 'target/release/roxify_native.node');
71
- const targetSo = resolve(root, 'target/release/roxify_native.so');
72
- const targetLibSo = resolve(root, 'target/release/libroxify_native.so');
73
- const nodeModulesNode = resolve(root, 'node_modules/roxify/roxify_native.node');
74
- const nodeModulesNodeWithTarget = resolve(root, `node_modules/roxify/roxify_native-${target}.node`);
75
- const prebuiltNode = resolve(moduleDir, '../../roxify_native.node');
76
- const prebuiltLibNode = resolve(moduleDir, '../../libroxify_native.node');
77
- const prebuiltNodeWithTarget = resolve(moduleDir, `../../roxify_native-${target}.node`);
78
- const prebuiltLibNodeWithTarget = resolve(moduleDir, `../../libroxify_native-${target}.node`);
79
- // Support multiple possible OS triples (e.g. windows-gnu and windows-msvc)
80
- const targets = targetAlt ? [target, targetAlt] : [target];
69
+ // --- 1. Platform-specific candidates (checked FIRST) ---
70
+ // These are the ONLY safe candidates — they match the current OS+arch.
81
71
  const candidates = [];
82
- for (const t of targets) {
83
- const bundleNodeWithT = resolve(moduleDir, `../roxify_native-${t}.node`);
84
- const bundleLibNodeWithT = resolve(moduleDir, `../libroxify_native-${t}.node`);
85
- const repoNodeWithT = resolve(root, `roxify_native-${t}.node`);
86
- const repoLibNodeWithT = resolve(root, `libroxify_native-${t}.node`);
87
- const nodeModulesNodeWithT = resolve(root, `node_modules/roxify/roxify_native-${t}.node`);
88
- const prebuiltNodeWithT = resolve(moduleDir, `../../roxify_native-${t}.node`);
89
- const prebuiltLibNodeWithT = resolve(moduleDir, `../../libroxify_native-${t}.node`);
90
- candidates.push(bundleLibNodeWithT, bundleNodeWithT, repoLibNodeWithT, repoNodeWithT, nodeModulesNodeWithT, prebuiltLibNodeWithT, prebuiltNodeWithT);
72
+ for (const triple of triples) {
73
+ const name = `roxify_native-${triple}.node`;
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));
91
84
  }
92
- candidates.push(bundleLibNode, bundleNode, repoLibNode, repoNode, targetNode, targetLibSo, targetSo, nodeModulesNode, prebuiltLibNode, prebuiltNode);
85
+ // --- 2. Build output candidates (local dev) ---
86
+ for (const triple of triples) {
87
+ for (const profile of ['release', 'fastdev']) {
88
+ // Unix: libroxify_native.so / .dylib → renamed to .node
89
+ candidates.push(resolve(root, 'target', triple, profile, 'libroxify_native.so'));
90
+ candidates.push(resolve(root, 'target', triple, profile, 'libroxify_native.dylib'));
91
+ // Windows: roxify_native.dll
92
+ candidates.push(resolve(root, 'target', triple, profile, 'roxify_native.dll'));
93
+ }
94
+ // Default (non-cross-compiled) output
95
+ for (const profile of ['release', 'fastdev']) {
96
+ candidates.push(resolve(root, 'target', profile, 'libroxify_native.so'));
97
+ candidates.push(resolve(root, 'target', profile, 'libroxify_native.dylib'));
98
+ candidates.push(resolve(root, 'target', profile, 'roxify_native.dll'));
99
+ candidates.push(resolve(root, 'target', profile, 'roxify_native.node'));
100
+ }
101
+ }
102
+ // --- 3. Generic fallback names ---
103
+ // ONLY used when a platform-specific triple file also exists next to it,
104
+ // or when we are on the SAME platform that built the generic file (dev mode).
105
+ // In production (npm install), the platform-specific files MUST exist.
106
+ // We do NOT blindly load roxify_native.node because it could be a Linux
107
+ // binary loaded on Windows (or vice-versa), causing ERR_DLOPEN_FAILED.
108
+ //
109
+ // Generic names are ONLY safe in local dev (where you just built for your
110
+ // own platform). We keep them but ONLY for target/release/ build outputs.
111
+ // The root-level roxify_native.node is intentionally excluded.
112
+ // Deduplicate
113
+ const seen = new Set();
114
+ const unique = [];
93
115
  for (const c of candidates) {
116
+ if (!seen.has(c)) {
117
+ seen.add(c);
118
+ unique.push(c);
119
+ }
120
+ }
121
+ for (const c of unique) {
94
122
  try {
95
123
  if (!existsSync(c))
96
124
  continue;
97
- if (c.endsWith('.so')) {
98
- const nodeAlias = c.replace(/\.so$/, '.node');
125
+ // .so/.dylib/.dll files need to be aliased as .node for require()
126
+ if (c.endsWith('.so') || c.endsWith('.dylib') || c.endsWith('.dll')) {
127
+ const nodeAlias = c.replace(/\.(so|dylib|dll)$/, '.node');
99
128
  try {
100
129
  if (!existsSync(nodeAlias)) {
101
- require('fs').copyFileSync(c, nodeAlias);
130
+ copyFileSync(c, nodeAlias);
102
131
  }
103
132
  return nodeAlias;
104
133
  }
105
- catch (e) {
134
+ catch {
106
135
  return c;
107
136
  }
108
137
  }
@@ -110,7 +139,7 @@ function getNativeModule() {
110
139
  }
111
140
  catch { }
112
141
  }
113
- throw new Error(`Native module not found for ${currentPlatform}-${arch()}. Checked: ${candidates.join(' ')}`);
142
+ throw new Error(`Native module not found for ${platform()}-${arch()} (triples: ${triples.join(', ')}). Searched ${unique.length} paths:\n${unique.join('\n')}`);
114
143
  }
115
144
  return nativeRequire(getNativePath());
116
145
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roxify",
3
- "version": "1.7.0",
3
+ "version": "1.7.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",
@@ -13,10 +13,20 @@
13
13
  "dist",
14
14
  "roxify_native.node",
15
15
  "libroxify_native.node",
16
- "roxify_native-x86_64-pc-windows-gnu.node",
17
- "roxify_native-x86_64-pc-windows-msvc.node",
18
16
  "roxify_native-x86_64-unknown-linux-gnu.node",
17
+ "roxify_native-i686-unknown-linux-gnu.node",
18
+ "roxify_native-aarch64-unknown-linux-gnu.node",
19
+ "roxify_native-x86_64-apple-darwin.node",
20
+ "roxify_native-aarch64-apple-darwin.node",
21
+ "roxify_native-x86_64-pc-windows-msvc.node",
22
+ "roxify_native-i686-pc-windows-msvc.node",
23
+ "roxify_native-aarch64-pc-windows-msvc.node",
24
+ "roxify_native-x86_64-pc-windows-gnu.node",
19
25
  "libroxify_native-x86_64-unknown-linux-gnu.node",
26
+ "libroxify_native-i686-unknown-linux-gnu.node",
27
+ "libroxify_native-aarch64-unknown-linux-gnu.node",
28
+ "libroxify_native-x86_64-apple-darwin.node",
29
+ "libroxify_native-aarch64-apple-darwin.node",
20
30
  "README.md",
21
31
  "LICENSE"
22
32
  ],
@@ -48,7 +58,7 @@
48
58
  "release:flow": "node scripts/release-flow.cjs",
49
59
  "release:flow:auto": "AUTO_PUBLISH=1 node scripts/release-flow.cjs",
50
60
  "publish": "node scripts/publish.cjs",
51
- "prepublishOnly": "npm run build && npm run build:native && npm run postbuild:native && npm run clean:targets",
61
+ "prepublishOnly": "npm run build",
52
62
  "test": "npm run build && node ./test/run-all-tests.cjs",
53
63
  "test:integration": "node scripts/run-integration-tests.cjs",
54
64
  "cli": "node dist/cli.js"
Binary file