@bennyblader/ddk-rn 0.2.2 → 0.2.4

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.
@@ -2,48 +2,36 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const https = require('https');
6
5
  const { execSync } = require('child_process');
7
6
 
8
7
  const packageRoot = path.join(__dirname, '..');
9
- const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
10
- const version = packageJson.version;
11
8
 
12
- const GITHUB_REPO = 'bennyhodl/ddk-ffi';
13
- const RELEASE_TAG = `v${version}`;
9
+ console.log('šŸ“¦ DDK-RN Post-install: Building native libraries...');
14
10
 
15
- console.log(`šŸ“¦ DDK-RN Post-install: Setting up native binaries for v${version}...`);
11
+ // Check if uniffi-bindgen-react-native is available (prefer npx)
12
+ function hasUniffiBingen() {
13
+ try {
14
+ execSync('npx uniffi-bindgen-react-native --help', { stdio: 'ignore' });
15
+ return true;
16
+ } catch (error) {
17
+ try {
18
+ execSync('uniffi-bindgen-react-native --help', { stdio: 'ignore' });
19
+ return true;
20
+ } catch (error2) {
21
+ return false;
22
+ }
23
+ }
24
+ }
16
25
 
17
- // Define all required files for verification
18
- const requiredFiles = {
19
- 'TypeScript bindings': [
20
- 'src/ddk_ffi.ts',
21
- 'src/ddk_ffi-ffi.ts',
22
- 'src/NativeDdkRn.ts',
23
- 'src/index.tsx'
24
- ],
25
- 'C++ bindings': [
26
- 'cpp/ddk_ffi.hpp',
27
- 'cpp/ddk_ffi.cpp',
28
- 'cpp/bennyblader-ddk-rn.h',
29
- 'cpp/bennyblader-ddk-rn.cpp'
30
- ],
31
- 'Android libraries': [
32
- 'android/src/main/arm64-v8a/libddk_ffi.a',
33
- 'android/src/main/armeabi-v7a/libddk_ffi.a',
34
- 'android/src/main/x86/libddk_ffi.a',
35
- 'android/src/main/x86_64/libddk_ffi.a'
36
- ],
37
- 'iOS framework': [
38
- 'ios/DdkRn.xcframework/Info.plist',
39
- 'ios/DdkRn.xcframework/ios-arm64/libddk_ffi.a',
40
- 'ios/DdkRn.xcframework/ios-arm64-simulator/libddk_ffi.a'
41
- ],
42
- 'JavaScript modules': [
43
- 'lib/commonjs/index.js',
44
- 'lib/module/index.js'
45
- ]
46
- };
26
+ // Get the uniffi command (prefer npx)
27
+ function getUniffiCommand() {
28
+ try {
29
+ execSync('npx uniffi-bindgen-react-native --help', { stdio: 'ignore' });
30
+ return 'npx uniffi-bindgen-react-native';
31
+ } catch (error) {
32
+ return 'uniffi-bindgen-react-native';
33
+ }
34
+ }
47
35
 
48
36
  // Create directories if they don't exist
49
37
  function ensureDir(dir) {
@@ -52,178 +40,209 @@ function ensureDir(dir) {
52
40
  }
53
41
  }
54
42
 
55
- function downloadFile(url, dest) {
56
- return new Promise((resolve, reject) => {
57
- console.log(`ā¬‡ļø Downloading from ${url}...`);
58
-
59
- const file = fs.createWriteStream(dest);
60
-
61
- https.get(url, (response) => {
62
- if (response.statusCode === 302 || response.statusCode === 301) {
63
- // Follow redirect
64
- return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
65
- }
66
-
67
- if (response.statusCode !== 200) {
68
- reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
69
- return;
70
- }
71
-
72
- response.pipe(file);
73
-
74
- file.on('finish', () => {
75
- file.close();
76
- console.log(`āœ… Downloaded ${path.basename(dest)}`);
77
- resolve();
78
- });
79
- }).on('error', (err) => {
80
- fs.unlink(dest, () => {}); // Delete partial file
81
- reject(err);
43
+ // Build iOS libraries and create XCFramework
44
+ function buildIOS() {
45
+ const platform = process.platform;
46
+
47
+ if (platform !== 'darwin') {
48
+ console.log('\nāš ļø Skipping iOS build (not on macOS)');
49
+ return;
50
+ }
51
+
52
+ console.log('\nšŸŽ Building iOS libraries...');
53
+ const uniffiCmd = getUniffiCommand();
54
+
55
+ try {
56
+ const cmd = `${uniffiCmd} build ios --and-generate`;
57
+ console.log(`Running: ${cmd}`);
58
+ execSync(cmd, {
59
+ stdio: 'inherit',
60
+ cwd: packageRoot
82
61
  });
83
- });
62
+ console.log('āœ… iOS libraries built');
63
+ } catch (error) {
64
+ throw new Error(`Failed to build iOS libraries: ${error.message}`);
65
+ }
84
66
  }
85
67
 
86
- function extractTarGz(tarPath, extractDir) {
68
+ // Build Android libraries
69
+ function buildAndroid() {
70
+ console.log('\nšŸ“± Building Android libraries...');
71
+
72
+ // Check if Android NDK is available
73
+ if (!process.env.ANDROID_NDK_ROOT && !process.env.NDK_HOME) {
74
+ console.log('āš ļø Android NDK not found. Skipping Android build.');
75
+ console.log(' Set ANDROID_NDK_ROOT or NDK_HOME to build Android libraries.');
76
+ return;
77
+ }
78
+
79
+ const uniffiCmd = getUniffiCommand();
80
+
87
81
  try {
88
- console.log(`šŸ“‚ Extracting ${path.basename(tarPath)}...`);
89
- execSync(`tar -xzf "${tarPath}" -C "${extractDir}"`, { stdio: 'inherit' });
90
- console.log(`āœ… Extracted to ${extractDir}`);
82
+ const cmd = `${uniffiCmd} build android --and-generate`;
83
+ console.log(`Running: ${cmd}`);
84
+ execSync(cmd, {
85
+ stdio: 'inherit',
86
+ cwd: packageRoot
87
+ });
88
+ console.log('āœ… Android libraries built');
91
89
  } catch (error) {
92
- throw new Error(`Failed to extract ${tarPath}: ${error.message}`);
90
+ console.warn(`āš ļø Android build failed: ${error.message}`);
91
+ console.warn(' This may be due to missing Android NDK or Rust toolchains.');
92
+ }
93
+ }
94
+
95
+ // Fix the C++ include path issue if needed
96
+ function fixCppIncludePath() {
97
+ const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
98
+ if (fs.existsSync(cppFile)) {
99
+ let content = fs.readFileSync(cppFile, 'utf8');
100
+ if (content.includes('#include "/ddk_ffi.hpp"')) {
101
+ content = content.replace('#include "/ddk_ffi.hpp"', '#include "ddk_ffi.hpp"');
102
+ fs.writeFileSync(cppFile, content);
103
+ console.log('šŸ”§ Fixed include path in C++ bindings');
104
+ }
93
105
  }
94
106
  }
95
107
 
108
+ // Verify all required files are present
96
109
  function verifyAllFiles() {
97
- console.log('\nšŸ” Verifying all required files...');
110
+ console.log('\nšŸ” Verifying installation...');
111
+
112
+ const requiredFiles = [
113
+ // Core JSI bindings (shipped with package)
114
+ 'src/ddk_ffi.ts',
115
+ 'src/ddk_ffi-ffi.ts',
116
+ 'cpp/ddk_ffi.hpp',
117
+ 'cpp/ddk_ffi.cpp',
118
+ // Generated turbo module files (shipped with package)
119
+ 'src/NativeDdkRn.ts',
120
+ 'src/index.tsx',
121
+ 'cpp/bennyblader-ddk-rn.cpp',
122
+ 'cpp/bennyblader-ddk-rn.h'
123
+ ];
98
124
 
99
- let allFilesPresent = true;
100
125
  const platform = process.platform;
126
+ let allFilesPresent = true;
101
127
 
102
- for (const [category, files] of Object.entries(requiredFiles)) {
103
- // Skip iOS files on non-macOS platforms
104
- if (category === 'iOS framework' && platform !== 'darwin') {
105
- console.log(`\nāš ļø Skipping ${category} verification (not on macOS)`);
106
- continue;
128
+ // Check required files
129
+ console.log('šŸ“‹ Checking required files...');
130
+ for (const file of requiredFiles) {
131
+ const filePath = path.join(packageRoot, file);
132
+ if (fs.existsSync(filePath)) {
133
+ console.log(` āœ… ${file}`);
134
+ } else {
135
+ console.error(` āŒ Missing: ${file}`);
136
+ allFilesPresent = false;
107
137
  }
108
-
109
- console.log(`\nšŸ“‹ Checking ${category}...`);
110
-
111
- for (const file of files) {
112
- const filePath = path.join(packageRoot, file);
113
- if (fs.existsSync(filePath)) {
114
- console.log(` āœ… ${file}`);
115
- } else {
116
- console.error(` āŒ Missing: ${file}`);
117
- allFilesPresent = false;
118
- }
138
+ }
139
+
140
+ // Check platform-specific files (generated during postinstall)
141
+ if (platform === 'darwin') {
142
+ console.log('šŸ“‹ Checking iOS framework...');
143
+ const iosFramework = path.join(packageRoot, 'ios', 'DdkRn.xcframework', 'Info.plist');
144
+ if (fs.existsSync(iosFramework)) {
145
+ console.log(` āœ… ios/DdkRn.xcframework`);
146
+ } else {
147
+ console.log(` āš ļø iOS framework not built yet (will be built on first use)`);
119
148
  }
120
149
  }
121
150
 
122
- return allFilesPresent;
123
- }
124
-
125
- async function downloadAndExtractBinaries() {
126
- const platform = process.platform;
151
+ console.log('šŸ“‹ Checking Android libraries...');
152
+ const androidLibs = [
153
+ 'android/src/main/arm64-v8a/libddk_ffi.a',
154
+ 'android/src/main/armeabi-v7a/libddk_ffi.a',
155
+ 'android/src/main/x86/libddk_ffi.a',
156
+ 'android/src/main/x86_64/libddk_ffi.a'
157
+ ];
127
158
 
128
- try {
129
- // Download Android native libraries
130
- const androidLibsDir = path.join(packageRoot, 'android', 'src', 'main');
131
- ensureDir(androidLibsDir);
132
-
133
- const androidArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/android-jni-libs.tar.gz`;
134
- const androidTarPath = path.join(packageRoot, 'android-jni-libs.tar.gz');
135
-
136
- console.log('\nšŸ“± Setting up Android native libraries...');
137
- await downloadFile(androidArchiveUrl, androidTarPath);
138
- extractTarGz(androidTarPath, androidLibsDir);
139
- fs.unlinkSync(androidTarPath); // Clean up tar file
140
-
141
- // Download iOS XCFramework (only on macOS)
142
- if (platform === 'darwin') {
143
- const iosFrameworksDir = path.join(packageRoot, 'ios');
144
- ensureDir(iosFrameworksDir);
145
-
146
- const iosArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/ios-xcframeworks.tar.gz`;
147
- const iosTarPath = path.join(packageRoot, 'ios-xcframeworks.tar.gz');
148
-
149
- console.log('\nšŸŽ Setting up iOS framework...');
150
- await downloadFile(iosArchiveUrl, iosTarPath);
151
- extractTarGz(iosTarPath, iosFrameworksDir);
152
- fs.unlinkSync(iosTarPath); // Clean up tar file
153
- } else {
154
- console.log('\nāš ļø Skipping iOS framework (not on macOS)');
159
+ let androidLibsPresent = 0;
160
+ for (const lib of androidLibs) {
161
+ const libPath = path.join(packageRoot, lib);
162
+ if (fs.existsSync(libPath)) {
163
+ androidLibsPresent++;
155
164
  }
156
-
157
- } catch (error) {
158
- console.error('\nāŒ Failed to download native binaries:', error.message);
159
- console.error('');
160
- console.error('šŸ“‹ Manual installation instructions:');
161
- console.error(` 1. Download binaries from: https://github.com/${GITHUB_REPO}/releases/tag/${RELEASE_TAG}`);
162
- console.error(' 2. Extract android-jni-libs.tar.gz to android/src/main/');
163
- console.error(' 3. Extract ios-xcframeworks.tar.gz to ios/ (macOS only)');
164
- console.error('');
165
- console.error('Or report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
166
-
167
- // Don't fail the installation completely
168
- process.exit(0);
169
165
  }
166
+
167
+ if (androidLibsPresent === 0) {
168
+ console.log(' āš ļø Android libraries not built yet (may be due to missing NDK)');
169
+ } else {
170
+ console.log(` āœ… Found ${androidLibsPresent}/${androidLibs.length} Android libraries`);
171
+ }
172
+
173
+ return allFilesPresent;
170
174
  }
171
175
 
172
176
  async function main() {
173
- const platform = process.platform;
174
-
175
177
  // Skip in CI unless explicitly requested
176
- if (process.env.CI && !process.env.DOWNLOAD_BINARIES) {
177
- console.log('āš ļø Skipping binary download in CI environment.');
178
- console.log(' Set DOWNLOAD_BINARIES=1 to force download in CI.');
178
+ if (process.env.CI && !process.env.BUILD_NATIVE_LIBS) {
179
+ console.log('āš ļø Skipping native library builds in CI environment.');
180
+ console.log(' Set BUILD_NATIVE_LIBS=1 to force builds in CI.');
179
181
  process.exit(0);
180
182
  }
181
183
 
182
- // Check if binaries already exist
183
- const androidLibExists = fs.existsSync(path.join(packageRoot, 'android', 'src', 'main', 'arm64-v8a', 'libddk_ffi.a'));
184
- const iosFrameworkExists = fs.existsSync(path.join(packageRoot, 'ios', 'DdkRn.xcframework'));
185
-
186
- let needsDownload = false;
187
-
188
- if (!androidLibExists) {
189
- console.log('šŸ“± Android libraries not found, will download...');
190
- needsDownload = true;
191
- }
192
-
193
- if (platform === 'darwin' && !iosFrameworkExists) {
194
- console.log('šŸŽ iOS framework not found, will download...');
195
- needsDownload = true;
184
+ // Check prerequisites
185
+ if (!hasUniffiBingen()) {
186
+ console.error('āŒ uniffi-bindgen-react-native not found!');
187
+ console.error(' Install it with: npm install -g uniffi-bindgen-react-native');
188
+ console.error(' Or add it as a dependency in your project.');
189
+ process.exit(1);
196
190
  }
197
191
 
198
- if (needsDownload) {
199
- await downloadAndExtractBinaries();
200
- } else {
201
- console.log('āœ… Native binaries already present.');
202
- }
192
+ // Verify source files are present (should be included in NPM package)
193
+ const sourceFiles = [
194
+ 'src/ddk_ffi.ts',
195
+ 'src/ddk_ffi-ffi.ts',
196
+ 'src/NativeDdkRn.ts',
197
+ 'src/index.tsx',
198
+ 'cpp/ddk_ffi.hpp',
199
+ 'cpp/ddk_ffi.cpp',
200
+ 'cpp/bennyblader-ddk-rn.cpp',
201
+ 'cpp/bennyblader-ddk-rn.h'
202
+ ];
203
203
 
204
- // Fix the C++ include path issue if needed
205
- const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
206
- if (fs.existsSync(cppFile)) {
207
- let content = fs.readFileSync(cppFile, 'utf8');
208
- if (content.includes('#include "/ddk_ffi.hpp"')) {
209
- content = content.replace('#include "/ddk_ffi.hpp"', '#include "ddk_ffi.hpp"');
210
- fs.writeFileSync(cppFile, content);
211
- console.log('\nšŸ”§ Fixed include path in C++ bindings');
204
+ console.log('šŸ” Checking source files...');
205
+ for (const file of sourceFiles) {
206
+ const filePath = path.join(packageRoot, file);
207
+ if (!fs.existsSync(filePath)) {
208
+ console.error(`āŒ Missing source file: ${file}`);
209
+ console.error(' This indicates a problem with the NPM package.');
210
+ process.exit(1);
212
211
  }
213
212
  }
213
+ console.log('āœ… All source files present');
214
214
 
215
- // Verify all files are present
216
- const allFilesPresent = verifyAllFiles();
217
-
218
- if (!allFilesPresent) {
219
- console.error('\nāŒ Some required files are missing!');
220
- console.error('The package installation may have failed.');
221
- console.error('Please report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
215
+ try {
216
+ // Fix include path if needed
217
+ fixCppIncludePath();
218
+
219
+ // Build native libraries only (turbo module already generated)
220
+ buildIOS();
221
+ buildAndroid();
222
+
223
+ // Verify all files are present
224
+ const allFilesPresent = verifyAllFiles();
225
+
226
+ if (!allFilesPresent) {
227
+ console.error('\nāŒ Some required files are missing!');
228
+ console.error('The installation may have failed.');
229
+ process.exit(1);
230
+ }
231
+
232
+ console.log('\nāœ… Installation completed successfully!');
233
+ console.log('šŸŽ‰ DDK-RN is ready to use!\n');
234
+
235
+ } catch (error) {
236
+ console.error('\nāŒ Failed to complete installation:', error.message);
237
+ console.error('');
238
+ console.error('šŸ“‹ This may be due to:');
239
+ console.error(' - Missing uniffi-bindgen-react-native (install globally)');
240
+ console.error(' - Missing Android NDK (for Android builds)');
241
+ console.error(' - Missing Xcode/iOS toolchain (for iOS builds on macOS)');
242
+ console.error('');
243
+ console.error('Report issues at: https://github.com/bennyhodl/ddk-ffi/issues');
222
244
  process.exit(1);
223
245
  }
224
-
225
- console.log('\nāœ… All required files verified!');
226
- console.log('šŸŽ‰ DDK-RN is ready to use!\n');
227
246
  }
228
247
 
229
248
  // Run the main function