diffx-js 0.5.1 → 0.5.3

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/README.md CHANGED
@@ -8,7 +8,18 @@ A Node.js wrapper for the `diffx` CLI tool.
8
8
  npm install diffx-js
9
9
  ```
10
10
 
11
- This will automatically download the appropriate `diffx` binary for your system from GitHub Releases.
11
+ This package includes pre-compiled `diffx` binaries for all supported platforms (Linux x64, macOS x64/ARM64, Windows x64), enabling **completely offline installation** with no external downloads required.
12
+
13
+ ### Supported Platforms
14
+
15
+ - **Linux x64** - Intel/AMD 64-bit
16
+ - **macOS x64** - Intel-based Macs
17
+ - **macOS ARM64** - Apple Silicon Macs (M1/M2/M3)
18
+ - **Windows x64** - 64-bit Windows
19
+
20
+ The appropriate binary is automatically selected at runtime based on your system.
21
+
22
+ **Note:** Due to bundling all platform binaries, this package is larger (~20MB) than typical npm packages but provides complete offline functionality.
12
23
 
13
24
  ## Usage
14
25
 
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -4,21 +4,37 @@ const { spawn } = require('child_process');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
6
 
7
- // Determine the platform-specific binary name
8
- let binaryName = 'diffx';
9
- if (process.platform === 'win32') {
10
- binaryName = 'diffx.exe';
7
+ // Determine the platform-specific binary name and directory
8
+ function getPlatformInfo() {
9
+ const platform = process.platform;
10
+ const arch = process.arch;
11
+
12
+ if (platform === 'win32') {
13
+ return { subdir: 'win32-x64', binaryName: 'diffx.exe' };
14
+ } else if (platform === 'darwin') {
15
+ if (arch === 'arm64') {
16
+ return { subdir: 'darwin-arm64', binaryName: 'diffx' };
17
+ } else {
18
+ return { subdir: 'darwin-x64', binaryName: 'diffx' };
19
+ }
20
+ } else if (platform === 'linux') {
21
+ return { subdir: 'linux-x64', binaryName: 'diffx' };
22
+ } else {
23
+ throw new Error(`Unsupported platform: ${platform}-${arch}`);
24
+ }
11
25
  }
12
26
 
13
- // Construct the path to the binary
14
- // In a real scenario, this would involve downloading the binary
15
- // For now, we assume it's in a 'bin' directory relative to this script
16
- const binaryPath = path.join(__dirname, 'bin', binaryName);
27
+ // Get platform-specific binary path
28
+ const platformInfo = getPlatformInfo();
29
+ const binaryPath = path.join(__dirname, 'bin', platformInfo.subdir, platformInfo.binaryName);
17
30
 
18
31
  // Check if the binary exists
19
32
  if (!fs.existsSync(binaryPath)) {
20
33
  console.error(`Error: Binary not found at ${binaryPath}`);
21
- console.error('Please ensure diffx is properly installed or built for your platform.');
34
+ console.error(`Platform: ${process.platform}-${process.arch}`);
35
+ console.error('Expected platform-specific binary not found.');
36
+ console.error('This might indicate a packaging issue. Please report this at:');
37
+ console.error('https://github.com/kako-jun/diffx/issues');
22
38
  process.exit(1);
23
39
  }
24
40
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "diffx-js",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "A Node.js wrapper for the diffx CLI tool - semantic diffing of JSON, YAML, TOML, XML, INI, and CSV files. Focuses on structural meaning rather than formatting.",
5
5
  "keywords": [
6
6
  "diff",
7
- "json",
7
+ "json",
8
8
  "yaml",
9
9
  "toml",
10
10
  "xml",
@@ -25,11 +25,11 @@
25
25
  "diffx": "./index.js"
26
26
  },
27
27
  "scripts": {
28
- "postinstall": "node scripts/download-binary.js",
29
28
  "test": "node test.js",
30
29
  "examples": "node examples.js",
31
30
  "verify": "node index.js --help",
32
- "prepublish": "npm run verify"
31
+ "prepublish": "npm run verify",
32
+ "download-binaries": "node scripts/download-all-binaries.js"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=12.0.0"
@@ -38,13 +38,21 @@
38
38
  "index.js",
39
39
  "lib.js",
40
40
  "scripts/download-binary.js",
41
+ "scripts/download-all-binaries.js",
41
42
  "bin/",
42
43
  "README.md",
43
44
  "examples.js",
44
45
  "test.js"
45
46
  ],
46
- "os": ["linux", "darwin", "win32"],
47
- "cpu": ["x64", "arm64"],
47
+ "os": [
48
+ "linux",
49
+ "darwin",
50
+ "win32"
51
+ ],
52
+ "cpu": [
53
+ "x64",
54
+ "arm64"
55
+ ],
48
56
  "author": "kako-jun",
49
57
  "license": "MIT",
50
58
  "homepage": "https://github.com/kako-jun/diffx",
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const https = require('https');
6
+ const { execSync } = require('child_process');
7
+
8
+ const DIFFX_VERSION = require('../package.json').version;
9
+ const BINARY_DIR = path.join(__dirname, '..', 'bin');
10
+
11
+ // All platform configurations
12
+ const PLATFORMS = [
13
+ {
14
+ name: 'linux-x64',
15
+ file: 'diffx-linux-x86_64.tar.gz',
16
+ binaryName: 'diffx',
17
+ subdir: 'linux-x64'
18
+ },
19
+ {
20
+ name: 'darwin-x64',
21
+ file: 'diffx-macos-x86_64.tar.gz',
22
+ binaryName: 'diffx',
23
+ subdir: 'darwin-x64'
24
+ },
25
+ {
26
+ name: 'darwin-arm64',
27
+ file: 'diffx-macos-aarch64.tar.gz',
28
+ binaryName: 'diffx',
29
+ subdir: 'darwin-arm64'
30
+ },
31
+ {
32
+ name: 'win32-x64',
33
+ file: 'diffx-windows-x86_64.zip',
34
+ binaryName: 'diffx.exe',
35
+ subdir: 'win32-x64'
36
+ }
37
+ ];
38
+
39
+ function downloadFile(url, dest) {
40
+ return new Promise((resolve, reject) => {
41
+ console.log(`Downloading ${path.basename(dest)}...`);
42
+ const file = fs.createWriteStream(dest);
43
+
44
+ https.get(url, (response) => {
45
+ if (response.statusCode === 302 || response.statusCode === 301) {
46
+ // Follow redirect
47
+ downloadFile(response.headers.location, dest).then(resolve).catch(reject);
48
+ return;
49
+ }
50
+
51
+ if (response.statusCode !== 200) {
52
+ reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
53
+ return;
54
+ }
55
+
56
+ response.pipe(file);
57
+
58
+ file.on('finish', () => {
59
+ file.close();
60
+ resolve();
61
+ });
62
+
63
+ file.on('error', (err) => {
64
+ fs.unlink(dest, () => {}); // Delete the file async
65
+ reject(err);
66
+ });
67
+ }).on('error', (err) => {
68
+ reject(err);
69
+ });
70
+ });
71
+ }
72
+
73
+ async function extractArchive(archivePath, extractDir) {
74
+ if (archivePath.endsWith('.zip')) {
75
+ // Use Node.js built-in for cross-platform ZIP extraction
76
+ const { execSync } = require('child_process');
77
+ try {
78
+ // Try with PowerShell on Windows
79
+ if (process.platform === 'win32') {
80
+ execSync(`powershell -command "Expand-Archive -Path '${archivePath}' -DestinationPath '${extractDir}' -Force"`, { stdio: 'inherit' });
81
+ } else {
82
+ // For Linux/macOS, use Python's zipfile module (more widely available than unzip)
83
+ execSync(`python3 -c "import zipfile; zipfile.ZipFile('${archivePath}').extractall('${extractDir}')"`, { stdio: 'inherit' });
84
+ }
85
+ } catch (error) {
86
+ // Fallback to manual extraction using Node.js modules
87
+ const AdmZip = require('adm-zip');
88
+ const zip = new AdmZip(archivePath);
89
+ zip.extractAllTo(extractDir, true);
90
+ }
91
+ } else if (archivePath.endsWith('.tar.gz')) {
92
+ execSync(`tar -xzf "${archivePath}" -C "${extractDir}"`, { stdio: 'inherit' });
93
+ }
94
+ }
95
+
96
+ async function downloadPlatformBinary(platform) {
97
+ const downloadUrl = `https://github.com/kako-jun/diffx/releases/download/v${DIFFX_VERSION}/${platform.file}`;
98
+ const platformDir = path.join(BINARY_DIR, platform.subdir);
99
+ const archivePath = path.join(platformDir, platform.file);
100
+
101
+ // Create platform-specific directory
102
+ if (!fs.existsSync(platformDir)) {
103
+ fs.mkdirSync(platformDir, { recursive: true });
104
+ }
105
+
106
+ // Check if binary already exists
107
+ const binaryPath = path.join(platformDir, platform.binaryName);
108
+ if (fs.existsSync(binaryPath)) {
109
+ console.log(`Binary for ${platform.name} already exists, skipping download.`);
110
+ return;
111
+ }
112
+
113
+ try {
114
+ // Download archive
115
+ await downloadFile(downloadUrl, archivePath);
116
+
117
+ // Extract binary
118
+ console.log(`Extracting ${platform.name} binary...`);
119
+ await extractArchive(archivePath, platformDir);
120
+
121
+ // Clean up archive
122
+ fs.unlinkSync(archivePath);
123
+
124
+ // Make binary executable on Unix systems
125
+ if (platform.binaryName !== 'diffx.exe') {
126
+ fs.chmodSync(binaryPath, '755');
127
+ }
128
+
129
+ console.log(`SUCCESS: ${platform.name} binary installed at ${binaryPath}`);
130
+
131
+ } catch (error) {
132
+ console.error(`ERROR: Failed to download ${platform.name} binary:`, error.message);
133
+ throw error;
134
+ }
135
+ }
136
+
137
+ async function main() {
138
+ try {
139
+ console.log(`Downloading diffx v${DIFFX_VERSION} binaries for all platforms...`);
140
+
141
+ // Create main bin directory
142
+ if (!fs.existsSync(BINARY_DIR)) {
143
+ fs.mkdirSync(BINARY_DIR, { recursive: true });
144
+ }
145
+
146
+ // Download all platform binaries
147
+ for (const platform of PLATFORMS) {
148
+ await downloadPlatformBinary(platform);
149
+ }
150
+
151
+ console.log('\nšŸŽ‰ All platform binaries downloaded successfully!');
152
+ console.log('\nBinary structure:');
153
+ console.log('bin/');
154
+ for (const platform of PLATFORMS) {
155
+ console.log(` └── ${platform.subdir}/${platform.binaryName}`);
156
+ }
157
+
158
+ } catch (error) {
159
+ console.error('ERROR: Failed to download platform binaries:', error.message);
160
+ process.exit(1);
161
+ }
162
+ }
163
+
164
+ if (require.main === module) {
165
+ main();
166
+ }
package/test.js CHANGED
@@ -118,12 +118,12 @@ async function runTests() {
118
118
  'test2.json'
119
119
  ]);
120
120
 
121
- if (diffResult.code === 0 &&
121
+ if (diffResult.code === 1 &&
122
122
  diffResult.stdout.includes('version') &&
123
123
  diffResult.stdout.includes('debug')) {
124
124
  success('Basic JSON diff works correctly');
125
125
  } else {
126
- error(`JSON diff failed: ${diffResult.stderr}`);
126
+ error(`JSON diff failed. Code: ${diffResult.code}, Stdout: ${diffResult.stdout}, Stderr: ${diffResult.stderr}`);
127
127
  throw new Error('JSON diff failed');
128
128
  }
129
129
 
@@ -137,7 +137,7 @@ async function runTests() {
137
137
  'json'
138
138
  ]);
139
139
 
140
- if (jsonOutputResult.code === 0) {
140
+ if (jsonOutputResult.code === 1) {
141
141
  try {
142
142
  const output = JSON.parse(jsonOutputResult.stdout);
143
143
  if (Array.isArray(output) && output.length > 0) {
@@ -166,7 +166,7 @@ async function runTests() {
166
166
  'test2.yaml'
167
167
  ]);
168
168
 
169
- if (yamlResult.code === 0 && yamlResult.stdout.includes('version')) {
169
+ if (yamlResult.code === 1 && yamlResult.stdout.includes('version')) {
170
170
  success('YAML diff works correctly');
171
171
  } else {
172
172
  error(`YAML diff failed: ${yamlResult.stderr}`);
@@ -220,8 +220,34 @@ async function runTests() {
220
220
  throw new Error('Error handling failed');
221
221
  }
222
222
 
223
- // Test 8: API functionality with new options
224
- info('Test 8: Testing API functionality with new options...');
223
+ // Test 8: Platform-specific binary verification
224
+ info('Test 8: Testing platform-specific binary verification...');
225
+
226
+ const platform = process.platform;
227
+ const arch = process.arch;
228
+ let expectedBinaryPath;
229
+
230
+ if (platform === 'win32') {
231
+ expectedBinaryPath = path.join(__dirname, 'bin', 'win32-x64', 'diffx.exe');
232
+ } else if (platform === 'darwin') {
233
+ if (arch === 'arm64') {
234
+ expectedBinaryPath = path.join(__dirname, 'bin', 'darwin-arm64', 'diffx');
235
+ } else {
236
+ expectedBinaryPath = path.join(__dirname, 'bin', 'darwin-x64', 'diffx');
237
+ }
238
+ } else if (platform === 'linux') {
239
+ expectedBinaryPath = path.join(__dirname, 'bin', 'linux-x64', 'diffx');
240
+ }
241
+
242
+ if (fs.existsSync(expectedBinaryPath)) {
243
+ success(`Platform-specific binary found: ${expectedBinaryPath}`);
244
+ } else {
245
+ error(`Platform-specific binary not found: ${expectedBinaryPath}`);
246
+ throw new Error('Platform binary missing');
247
+ }
248
+
249
+ // Test 9: API functionality with new options
250
+ info('Test 9: Testing API functionality with new options...');
225
251
 
226
252
  // Test ignore case option
227
253
  try {