react-native-fs-turbo 0.3.6 → 0.4.0

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.
Files changed (66) hide show
  1. package/README.md +128 -27
  2. package/RNFSTurbo.podspec +2 -2
  3. package/android/CMakeLists.txt +63 -10
  4. package/android/build.gradle +80 -3
  5. package/android/gradle.properties +5 -5
  6. package/android/src/main/codegen/RNFSTurboSpec.java +17 -0
  7. package/android/src/main/cpp/JNIOnLoad.cpp +18 -0
  8. package/android/src/main/cpp/RNFSTurboLogger.cpp +4 -0
  9. package/android/src/main/cpp/RNFSTurboModule.cpp +44 -0
  10. package/android/src/main/cpp/RNFSTurboModule.h +40 -0
  11. package/android/src/main/cpp/RNFSTurboPlatformHelper.cpp +5 -1
  12. package/android/src/main/java/com/cmpayc/rnfsturbo/JNIOnLoad.java +27 -0
  13. package/android/src/main/java/com/cmpayc/rnfsturbo/{RNFSTurboPlatformContextModule.java → RNFSTurboModule.java} +62 -11
  14. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPackage.java +11 -9
  15. package/cpp/RNFSTurboHostObject.cpp +138 -15
  16. package/cpp/RNFSTurboHostObject.h +12 -4
  17. package/cpp/RNFSTurboInstall.cpp +27 -0
  18. package/cpp/RNFSTurboInstall.h +20 -0
  19. package/cpp/RNFSTurboLogger.h +4 -0
  20. package/cpp/RNFSTurboPlatformHelper.h +4 -0
  21. package/cpp/algorithms/Krypt/AES.cpp +502 -0
  22. package/cpp/algorithms/Krypt/bytearray.cpp +158 -0
  23. package/cpp/algorithms/Krypt/functions.cpp +137 -0
  24. package/cpp/algorithms/Krypt/mode.cpp +203 -0
  25. package/cpp/algorithms/Krypt/padding.cpp +219 -0
  26. package/cpp/encryption/encryption-utils.cpp +162 -0
  27. package/cpp/encryption/encryption-utils.h +43 -0
  28. package/cpp/filesystem/{helpers.cpp → filesystem-utils.cpp} +5 -1
  29. package/cpp/filesystem/{helpers.h → filesystem-utils.h} +4 -0
  30. package/ios/RNFSTurboLogger.mm +4 -0
  31. package/ios/{RNFSTurboPlatformContextModule.h → RNFSTurboModule.h} +3 -3
  32. package/ios/{RNFSTurboPlatformContextModule.mm → RNFSTurboModule.mm} +22 -5
  33. package/ios/RNFSTurboPlatformHelper.mm +4 -0
  34. package/lib/commonjs/NativeRNFSTurboModule.js +14 -16
  35. package/lib/commonjs/NativeRNFSTurboModule.js.map +1 -1
  36. package/lib/commonjs/createRNFSTurbo.js +3 -2
  37. package/lib/commonjs/createRNFSTurbo.js.map +1 -1
  38. package/lib/commonjs/globals.d.js +6 -0
  39. package/lib/commonjs/globals.d.js.map +1 -0
  40. package/lib/module/NativeRNFSTurboModule.js +14 -16
  41. package/lib/module/NativeRNFSTurboModule.js.map +1 -1
  42. package/lib/module/createRNFSTurbo.js +3 -2
  43. package/lib/module/createRNFSTurbo.js.map +1 -1
  44. package/lib/module/globals.d.js +4 -0
  45. package/lib/module/globals.d.js.map +1 -0
  46. package/lib/typescript/NativeRNFSTurboModule.d.ts +12 -3
  47. package/lib/typescript/NativeRNFSTurboModule.d.ts.map +1 -1
  48. package/lib/typescript/Types.d.ts +11 -0
  49. package/lib/typescript/Types.d.ts.map +1 -1
  50. package/lib/typescript/createRNFSTurbo.d.ts.map +1 -1
  51. package/package.json +6 -3
  52. package/react-native.config.js +1 -5
  53. package/src/NativeRNFSTurboModule.ts +25 -21
  54. package/src/Types.ts +11 -0
  55. package/src/createRNFSTurbo.ts +4 -2
  56. package/src/globals.d.ts +9 -0
  57. package/cpp/NativeRNFSTurboModule.cpp +0 -24
  58. package/cpp/NativeRNFSTurboModule.h +0 -31
  59. package/ios/RNFSTurboOnLoad.mm +0 -25
  60. package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js +0 -22
  61. package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js.map +0 -1
  62. package/lib/module/NativeRNFSTurboPlatformContextModule.js +0 -18
  63. package/lib/module/NativeRNFSTurboPlatformContextModule.js.map +0 -1
  64. package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts +0 -16
  65. package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts.map +0 -1
  66. package/src/NativeRNFSTurboPlatformContextModule.ts +0 -34
@@ -1,35 +1,79 @@
1
-
2
1
  //
3
- // RNFSTurboPlatformContextModule.java
2
+ // RNFSTurboModule.java
4
3
  // react-native-fs-turbo
5
4
  //
6
- // Created by Sergei Kazakov on 16.09.24.
5
+ // Created by Sergei Kazakov on 20.10.25.
7
6
  //
8
7
 
9
8
  package com.cmpayc.rnfsturbo;
10
9
 
11
- import android.content.Context;
12
10
  import android.os.Environment;
13
-
11
+ import android.content.Context;
12
+ import androidx.annotation.Keep;
14
13
  import java.io.File;
15
14
 
15
+ import com.facebook.jni.HybridData;
16
+ import com.facebook.proguard.annotations.DoNotStrip;
16
17
  import com.facebook.react.bridge.ReactApplicationContext;
17
-
18
- public class RNFSTurboPlatformContextModule extends NativeRNFSTurboPlatformContextModuleSpec {
18
+ import com.facebook.react.bridge.ReactMethod;
19
+ import com.facebook.react.common.annotations.FrameworkAPI;
20
+ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
21
+ import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
22
+
23
+ @DoNotStrip
24
+ @Keep
25
+ @FrameworkAPI
26
+ public class RNFSTurboModule extends RNFSTurboSpec {
27
+ private final HybridData mHybridData;
19
28
  private final ReactApplicationContext context;
20
29
 
21
30
  public static Context externalContext;
31
+ public static final String NAME = "RNFSTurboModule";
32
+
33
+ static {
34
+ // Make sure RNFSTurbo's C++ library is loaded
35
+ JNIOnLoad.initializeNativeRNFSTurboModule();
36
+ }
22
37
 
23
- public RNFSTurboPlatformContextModule(ReactApplicationContext reactContext) {
24
- super(reactContext);
25
- context = reactContext;
26
- externalContext = reactContext;
38
+ public RNFSTurboModule(ReactApplicationContext context) {
39
+ super(context);
40
+ this.context = context;
41
+ externalContext = context;
42
+ this.mHybridData = initHybrid();
27
43
  }
28
44
 
29
45
  public static Context getContext() {
30
46
  return externalContext;
31
47
  }
32
48
 
49
+ @Override
50
+ public String getName() {
51
+ return NAME;
52
+ }
53
+
54
+ @Override
55
+ public boolean createRNFSTurbo() {
56
+ try {
57
+ // 1. Get jsi::Runtime pointer
58
+ if (this.context.getJavaScriptContextHolder() == null) {
59
+ return false;
60
+ }
61
+ long jsContext = this.context.getJavaScriptContextHolder().get();
62
+
63
+ // 2. Get CallInvokerHolder
64
+ CallInvokerHolder callInvokerHolderBase = this.context.getJSCallInvokerHolder();
65
+ if (!(callInvokerHolderBase instanceof CallInvokerHolderImpl)) {
66
+ return false;
67
+ }
68
+ CallInvokerHolderImpl callInvokerHolder = (CallInvokerHolderImpl) callInvokerHolderBase;
69
+
70
+ // 3. Create RNFSTurbo instance
71
+ return createRNFSTurbo(jsContext, callInvokerHolder);
72
+ } catch (Throwable e) {
73
+ return false;
74
+ }
75
+ }
76
+
33
77
  @Override
34
78
  public String getMainBundlePath() {
35
79
  return "";
@@ -96,4 +140,11 @@ public class RNFSTurboPlatformContextModule extends NativeRNFSTurboPlatformConte
96
140
  public String getRoamingDirectoryPath() {
97
141
  return "";
98
142
  }
143
+
144
+ private native HybridData initHybrid();
145
+
146
+ private native boolean createRNFSTurbo(
147
+ long jsRuntimePointer,
148
+ CallInvokerHolderImpl callInvokerHolder
149
+ );
99
150
  }
@@ -9,22 +9,24 @@ package com.cmpayc.rnfsturbo;
9
9
 
10
10
  import androidx.annotation.NonNull;
11
11
  import androidx.annotation.Nullable;
12
+ import androidx.annotation.OptIn;
13
+ import java.util.HashMap;
14
+ import java.util.Map;
12
15
 
13
16
  import com.facebook.react.bridge.NativeModule;
14
17
  import com.facebook.react.bridge.ReactApplicationContext;
18
+ import com.facebook.react.common.annotations.FrameworkAPI;
15
19
  import com.facebook.react.module.model.ReactModuleInfo;
16
20
  import com.facebook.react.module.model.ReactModuleInfoProvider;
17
21
  import com.facebook.react.TurboReactPackage;
18
22
 
19
- import java.util.HashMap;
20
- import java.util.Map;
21
-
23
+ @OptIn(markerClass = FrameworkAPI.class)
22
24
  public class RNFSTurboPackage extends TurboReactPackage {
23
25
  @Nullable
24
26
  @Override
25
27
  public NativeModule getModule(String name, @NonNull ReactApplicationContext reactContext) {
26
- if (name.equals(RNFSTurboPlatformContextModule.NAME)) {
27
- return new RNFSTurboPlatformContextModule(reactContext);
28
+ if (name.equals(RNFSTurboModule.NAME)) {
29
+ return new RNFSTurboModule(reactContext);
28
30
  } else {
29
31
  return null;
30
32
  }
@@ -35,13 +37,13 @@ public class RNFSTurboPackage extends TurboReactPackage {
35
37
  return () -> {
36
38
  final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
37
39
  moduleInfos.put(
38
- RNFSTurboPlatformContextModule.NAME,
40
+ RNFSTurboModule.NAME,
39
41
  new ReactModuleInfo(
40
- RNFSTurboPlatformContextModule.NAME,
41
- RNFSTurboPlatformContextModule.NAME,
42
+ RNFSTurboModule.NAME,
43
+ RNFSTurboModule.NAME,
42
44
  false, // canOverrideExistingModule
43
45
  false, // needsEagerInit
44
- true, // hasConstants
46
+ false, // hasConstants
45
47
  false, // isCxxModule
46
48
  true // isTurboModule
47
49
  )
@@ -8,11 +8,14 @@
8
8
  #include "RNFSTurboHostObject.h"
9
9
  #include "RNFSTurboLogger.h"
10
10
 
11
+ namespace cmpayc::rnfsturbo {
12
+
11
13
  using namespace facebook;
12
14
  namespace fs = std::filesystem;
13
15
 
14
- RNFSTurboHostObject::RNFSTurboHostObject() {
16
+ RNFSTurboHostObject::RNFSTurboHostObject(std::shared_ptr<react::CallInvoker> jsInvoker) {
15
17
  RNFSTurboLogger::log("RNFSTurbo", "Initializing RNFSTurbo");
18
+ _jsInvoker = jsInvoker;
16
19
  #ifdef __ANDROID__
17
20
  JNIEnv *env = facebook::jni::Environment::current();
18
21
  platformHelper = new RNFSTurboPlatformHelper(env);
@@ -286,6 +289,15 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
286
289
  offset = arguments[2].asNumber();
287
290
  }
288
291
  std::string encoding{"utf8"};
292
+ #ifdef RNFSTURBO_USE_ENCRYPTION
293
+ bool encrypted{false};
294
+ int passphraseLength{0};
295
+ int ivLength{0};
296
+ std::vector<unsigned char> passphrase;
297
+ std::vector<unsigned char> iv;
298
+ std::string mode{"ecb"};
299
+ std::string padding{"pkcs5/pkcs7"};
300
+ #endif
289
301
  int optionsIndex{-1};
290
302
  bool optionsIsObject{false};
291
303
  if (propName == "read" && count == 4 && arguments[3].isString()) {
@@ -309,10 +321,29 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
309
321
  encoding = encodingOption.asString(runtime).utf8(runtime);
310
322
  }
311
323
  }
324
+ #ifdef RNFSTURBO_USE_ENCRYPTION
325
+ processEncryptionOptions(
326
+ runtime,
327
+ propName,
328
+ optionsObject,
329
+ encrypted,
330
+ passphraseLength,
331
+ passphrase,
332
+ ivLength,
333
+ iv,
334
+ mode,
335
+ padding
336
+ );
337
+ #endif
312
338
  }
313
339
  if (encoding != "utf8" && encoding != "base64" && encoding != "uint8" && encoding != "float32" && encoding != "ascii") {
314
340
  throw jsi::JSError(runtime, RNFSTurboLogger::sprintf("%s: %s: %s", propName.c_str(), "Wrong encoding", encoding.c_str()));
315
341
  }
342
+ #ifdef RNFSTURBO_USE_ENCRYPTION
343
+ if (encrypted && passphraseLength == 0) {
344
+ throw jsi::JSError(runtime, RNFSTurboLogger::sprintf("%s: %s", propName.c_str(), "Passphrase is required for encryption"));
345
+ }
346
+ #endif
316
347
 
317
348
  try {
318
349
  if (propName == "readFileAssets" || propName == "readFileRes") {
@@ -354,12 +385,43 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
354
385
  return res;
355
386
  } else {
356
387
  std::string buffer = readFile(filePath.c_str(), offset, length);
357
- return encoding == "ascii"
358
- ? jsi::String::createFromAscii(runtime, buffer)
359
- : jsi::String::createFromUtf8(
360
- runtime,
361
- encoding == "base64" ? base64::to_base64(buffer) : buffer
388
+ #ifdef RNFSTURBO_USE_ENCRYPTION
389
+ if (encrypted) {
390
+ auto krypt = createCipherMode(
391
+ runtime,
392
+ propName,
393
+ mode,
394
+ padding,
395
+ passphrase.data(),
396
+ passphrase.size()
397
+ );
398
+ ByteArray decryptedBytes = krypt->decrypt(
399
+ reinterpret_cast<unsigned char*>(buffer.data()),
400
+ buffer.size(),
401
+ iv.data()
362
402
  );
403
+
404
+ std::string decryptedContent(
405
+ reinterpret_cast<const char*>(decryptedBytes.array),
406
+ decryptedBytes.length
407
+ );
408
+ return encoding == "ascii"
409
+ ? jsi::String::createFromAscii(runtime, decryptedContent)
410
+ : jsi::String::createFromUtf8(
411
+ runtime,
412
+ encoding == "base64" ? base64::to_base64(decryptedContent) : decryptedContent
413
+ );
414
+ } else {
415
+ #endif
416
+ return encoding == "ascii"
417
+ ? jsi::String::createFromAscii(runtime, buffer)
418
+ : jsi::String::createFromUtf8(
419
+ runtime,
420
+ encoding == "base64" ? base64::to_base64(buffer) : buffer
421
+ );
422
+ #ifdef RNFSTURBO_USE_ENCRYPTION
423
+ }
424
+ #endif
363
425
  }
364
426
  }
365
427
  } catch (const char *error_message) {
@@ -384,6 +446,15 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
384
446
  std::map<std::string, std::string> options;
385
447
  int optionsIndex{-1};
386
448
  bool optionsIsObject{false};
449
+ #ifdef RNFSTURBO_USE_ENCRYPTION
450
+ bool encrypted{false};
451
+ std::string mode{"ecb"};
452
+ std::string padding{"pkcs5/pkcs7"};
453
+ int passphraseLength{0};
454
+ int ivLength{0};
455
+ std::vector<unsigned char> passphrase;
456
+ std::vector<unsigned char> iv;
457
+ #endif
387
458
  if (propName == "write" && count == 4 && arguments[3].isString()) {
388
459
  optionsIndex = 3;
389
460
  } else if (propName != "write" && count == 3 && arguments[2].isString()) {
@@ -405,6 +476,20 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
405
476
  encoding = encodingOption.asString(runtime).utf8(runtime);
406
477
  }
407
478
  }
479
+ #ifdef RNFSTURBO_USE_ENCRYPTION
480
+ processEncryptionOptions(
481
+ runtime,
482
+ propName,
483
+ optionsObject,
484
+ encrypted,
485
+ passphraseLength,
486
+ passphrase,
487
+ ivLength,
488
+ iv,
489
+ mode,
490
+ padding
491
+ );
492
+ #endif
408
493
  #ifdef __APPLE__
409
494
  if (optionsObject.hasProperty(runtime, "NSFileProtectionKey")) {
410
495
  auto protectionOption = optionsObject.getProperty(runtime, "NSFileProtectionKey");
@@ -425,6 +510,11 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
425
510
  if ((propName == "write" && count > 4) || (propName != "write" && count > 3)) [[unlikely]] {
426
511
  throw jsi::JSError(runtime, RNFSTurboLogger::sprintf("%s: %s", propName.c_str(), "Too many arguments"));
427
512
  }
513
+ #ifdef RNFSTURBO_USE_ENCRYPTION
514
+ if (encrypted && passphraseLength == 0) {
515
+ throw jsi::JSError(runtime, RNFSTurboLogger::sprintf("%s: %s", propName.c_str(), "Passphrase is required for encryption"));
516
+ }
517
+ #endif
428
518
  int offset{-1};
429
519
  if (propName == "write" && count > 2 && arguments[2].isNumber()) {
430
520
  offset = arguments[2].asNumber();
@@ -500,6 +590,32 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
500
590
  content,
501
591
  offset
502
592
  );
593
+ #ifdef RNFSTURBO_USE_ENCRYPTION
594
+ } else if (encrypted) {
595
+ auto krypt = createCipherMode(
596
+ runtime,
597
+ propName,
598
+ mode,
599
+ padding,
600
+ passphrase.data(),
601
+ passphrase.size()
602
+ );
603
+ ByteArray cipher = krypt->encrypt(
604
+ reinterpret_cast<unsigned char*>(content.data()),
605
+ content.size(),
606
+ iv.data()
607
+ );
608
+
609
+ std::string encryptedContent(
610
+ reinterpret_cast<const char*>(cipher.array),
611
+ cipher.length
612
+ );
613
+ writeFile(
614
+ filePath.c_str(),
615
+ encryptedContent,
616
+ propName == "appendFile" || (propName == "write" && offset == -1)
617
+ );
618
+ #endif
503
619
  } else {
504
620
  writeFile(
505
621
  filePath.c_str(),
@@ -1147,7 +1263,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1147
1263
  int jobId = RNFSTurboPlatformHelper::jobId;
1148
1264
 
1149
1265
  RNFSTurboCompleteDownloadCallback completeCallback = [&runtime, completeFunc, this](int jobId, int statusCode, float bytesWritten) -> void {
1150
- jsInvoker->invokeAsync([&runtime, completeFunc, jobId, statusCode, bytesWritten]() {
1266
+ _jsInvoker->invokeAsync([&runtime, completeFunc, jobId, statusCode, bytesWritten]() {
1151
1267
  jsi::Object result = jsi::Object(runtime);
1152
1268
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1153
1269
  result.setProperty(runtime, "statusCode", jsi::Value(statusCode));
@@ -1157,7 +1273,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1157
1273
  };
1158
1274
 
1159
1275
  RNFSTurboErrorCallback errorCallback = [&runtime, errorFunc, this](int jobId, const char* errorMessage) -> void {
1160
- jsInvoker->invokeAsync([&runtime, errorFunc, jobId, errorMessage]() {
1276
+ _jsInvoker->invokeAsync([&runtime, errorFunc, jobId, errorMessage]() {
1161
1277
  errorFunc->call(runtime, jsi::String::createFromUtf8(runtime, RNFSTurboLogger::sprintf("%s: %s", "downloadFile", errorMessage)));
1162
1278
  });
1163
1279
  };
@@ -1165,7 +1281,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1165
1281
  std::optional<RNFSTurboBeginDownloadCallback> beginCallback = std::nullopt;
1166
1282
  if (beginCallbackFunc) {
1167
1283
  beginCallback = [&runtime, beginCallbackFunc, this](int jobId, int statusCode, float contentLength, std::map<std::string, std::string> headers) -> void {
1168
- jsInvoker->invokeAsync([&runtime, beginCallbackFunc, jobId, statusCode, contentLength, headers]() {
1284
+ _jsInvoker->invokeAsync([&runtime, beginCallbackFunc, jobId, statusCode, contentLength, headers]() {
1169
1285
  jsi::Object result = jsi::Object(runtime);
1170
1286
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1171
1287
  result.setProperty(runtime, "statusCode", jsi::Value(statusCode));
@@ -1182,7 +1298,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1182
1298
  std::optional<RNFSTurboProgressDownloadCallback> progressCallback = std::nullopt;
1183
1299
  if (progressCallbackFunc) {
1184
1300
  progressCallback = [&runtime, progressCallbackFunc, this](int jobId, float contentLength, float bytesWritten) -> void {
1185
- jsInvoker->invokeAsync([&runtime, progressCallbackFunc, jobId, contentLength, bytesWritten]() {
1301
+ _jsInvoker->invokeAsync([&runtime, progressCallbackFunc, jobId, contentLength, bytesWritten]() {
1186
1302
  jsi::Object result = jsi::Object(runtime);
1187
1303
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1188
1304
  result.setProperty(runtime, "contentLength", jsi::Value(contentLength));
@@ -1194,7 +1310,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1194
1310
  std::optional<RNFSTurboResumableDownloadCallback> resumableCallback = std::nullopt;
1195
1311
  if (resumableCallbackFunc) {
1196
1312
  resumableCallback = [&runtime, resumableCallbackFunc, this](int jobId) -> void {
1197
- jsInvoker->invokeAsync([&runtime, resumableCallbackFunc, jobId]() {
1313
+ _jsInvoker->invokeAsync([&runtime, resumableCallbackFunc, jobId]() {
1198
1314
  resumableCallbackFunc->call(runtime, jsi::Value(jobId));
1199
1315
  });
1200
1316
  };
@@ -1446,7 +1562,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1446
1562
  };
1447
1563
 
1448
1564
  RNFSTurboErrorCallback errorCallback = [&runtime, errorFunc, this](int jobId, const char* errorMessage) -> void {
1449
- jsInvoker->invokeAsync([&runtime, errorFunc, errorMessage]() {
1565
+ _jsInvoker->invokeAsync([&runtime, errorFunc, errorMessage]() {
1450
1566
  errorFunc->call(runtime, jsi::String::createFromUtf8(runtime, RNFSTurboLogger::sprintf("%s: %s", "uploadFiles", errorMessage)));
1451
1567
  });
1452
1568
  };
@@ -1454,7 +1570,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1454
1570
  std::optional<RNFSTurboBeginUploadCallback> beginCallback = std::nullopt;
1455
1571
  if (beginCallbackFunc) {
1456
1572
  beginCallback = [&runtime, beginCallbackFunc, this](int jobId) -> void {
1457
- jsInvoker->invokeAsync([&runtime, beginCallbackFunc, jobId]() {
1573
+ _jsInvoker->invokeAsync([&runtime, beginCallbackFunc, jobId]() {
1458
1574
  jsi::Object result = jsi::Object(runtime);
1459
1575
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1460
1576
  beginCallbackFunc->call(runtime, std::move(result));
@@ -1464,7 +1580,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1464
1580
  std::optional<RNFSTurboProgressUploadCallback> progressCallback = std::nullopt;
1465
1581
  if (progressCallbackFunc) {
1466
1582
  progressCallback = [&runtime, progressCallbackFunc, this](int jobId, float totalBytesExpectedToSend, float totalBytesSent) -> void {
1467
- jsInvoker->invokeAsync([&runtime, progressCallbackFunc, jobId, totalBytesExpectedToSend, totalBytesSent]() {
1583
+ _jsInvoker->invokeAsync([&runtime, progressCallbackFunc, jobId, totalBytesExpectedToSend, totalBytesSent]() {
1468
1584
  jsi::Object result = jsi::Object(runtime);
1469
1585
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1470
1586
  result.setProperty(runtime, "totalBytesExpectedToSend", jsi::Value(totalBytesExpectedToSend));
@@ -1535,6 +1651,11 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1535
1651
  if (fsInfo.freeSpaceEx.has_value()) {
1536
1652
  result.setProperty(runtime, "freeSpaceEx", jsi::Value(static_cast<float>(fsInfo.freeSpaceEx.value())));
1537
1653
  }
1654
+ #ifdef RNFSTURBO_USE_ENCRYPTION
1655
+ result.setProperty(runtime, "encryptionEnabled", jsi::Value(true));
1656
+ #else
1657
+ result.setProperty(runtime, "encryptionEnabled", jsi::Value(false));
1658
+ #endif
1538
1659
 
1539
1660
  return result;
1540
1661
  } catch (const char* error_message) {
@@ -1568,7 +1689,7 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1568
1689
  int jobId = RNFSTurboPlatformHelper::jobId;
1569
1690
 
1570
1691
  RNFSTurboScanCallback scanCallback = [&runtime, scanFunc, this](int jobId, std::string path) -> void {
1571
- jsInvoker->invokeAsync([&runtime, scanFunc, jobId, path]() {
1692
+ _jsInvoker->invokeAsync([&runtime, scanFunc, jobId, path]() {
1572
1693
  jsi::Object result = jsi::Object(runtime);
1573
1694
  result.setProperty(runtime, "jobId", jsi::Value(jobId));
1574
1695
  result.setProperty(runtime, "path", jsi::String::createFromUtf8(runtime, path));
@@ -1657,3 +1778,5 @@ jsi::Value RNFSTurboHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID
1657
1778
 
1658
1779
  return jsi::Value::undefined();
1659
1780
  }
1781
+
1782
+ }
@@ -17,6 +17,7 @@
17
17
  #include <thread>
18
18
  #include <utime.h>
19
19
  #include <vector>
20
+ #include <ReactCommon/CallInvoker.h>
20
21
  #ifdef __ANDROID__
21
22
  #include <fbjni/fbjni.h>
22
23
  #include <jni.h>
@@ -28,22 +29,29 @@
28
29
  #include "algorithms/sha256.h"
29
30
  #include "algorithms/sha384.h"
30
31
  #include "algorithms/sha512.h"
31
- #include "filesystem/helpers.h"
32
- #include "NativeRNFSTurboModule.h"
32
+ #ifdef RNFSTURBO_USE_ENCRYPTION
33
+ #include "algorithms/Krypt/aes-config.hpp"
34
+ #include "encryption/encryption-utils.h"
35
+ #endif
36
+ #include "filesystem/filesystem-utils.h"
33
37
  #include "RNFSTurboPlatformHelper.h"
34
38
 
39
+ namespace cmpayc::rnfsturbo {
40
+
35
41
  using namespace facebook;
36
42
 
37
43
  class RNFSTurboHostObject : public jsi::HostObject {
38
44
  public:
39
- RNFSTurboHostObject();
45
+ RNFSTurboHostObject(std::shared_ptr<react::CallInvoker> jsInvoker);
40
46
  ~RNFSTurboHostObject();
41
47
 
42
48
  public:
43
49
  jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
44
50
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
45
- std::shared_ptr<facebook::react::CallInvoker> jsInvoker;
51
+ std::shared_ptr<react::CallInvoker> _jsInvoker;
46
52
 
47
53
  private:
48
54
  RNFSTurboPlatformHelper* platformHelper;
49
55
  };
56
+
57
+ }
@@ -0,0 +1,27 @@
1
+ //
2
+ // RNFSTurboInstall.cpp
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25
6
+ //
7
+
8
+ #include "RNFSTurboInstall.h"
9
+ #include "RNFSTurboHostObject.h"
10
+
11
+ namespace cmpayc::rnfsturbo {
12
+
13
+ bool install(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker>& callInvoker) {
14
+ if (runtime.global().hasProperty(runtime, "RNFSTurboProxy")) [[unlikely]] {
15
+ return true;
16
+ }
17
+
18
+ std::shared_ptr<RNFSTurboHostObject> instance = std::make_shared<RNFSTurboHostObject>(callInvoker);
19
+
20
+ jsi::Object result = jsi::Object::createFromHostObject(runtime, instance);
21
+
22
+ runtime.global().setProperty(runtime, "RNFSTurboProxy", std::move(result));
23
+
24
+ return true;
25
+ }
26
+
27
+ } // namespace cmpayc::rnfsturbo
@@ -0,0 +1,20 @@
1
+ //
2
+ // RNFSTurboInstall.h
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <jsi/jsi.h>
11
+ #include <memory>
12
+ #include <ReactCommon/CallInvoker.h>
13
+
14
+ namespace cmpayc::rnfsturbo {
15
+
16
+ using namespace facebook;
17
+
18
+ bool install(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker>& callInvoker);
19
+
20
+ } // namespace cmpayc::rnfsturbo
@@ -9,6 +9,8 @@
9
9
 
10
10
  #include <string>
11
11
 
12
+ namespace cmpayc::rnfsturbo {
13
+
12
14
  class RNFSTurboLogger {
13
15
  private:
14
16
  RNFSTurboLogger() = delete;
@@ -45,3 +47,5 @@ public:
45
47
  return sprintf(formattedString);
46
48
  }
47
49
  };
50
+
51
+ }
@@ -13,6 +13,8 @@
13
13
  #include <string>
14
14
  #include <thread>
15
15
 
16
+ namespace cmpayc::rnfsturbo {
17
+
16
18
  typedef std::function<void (int jobId, int statusCode, float bytesWritten)> RNFSTurboCompleteDownloadCallback;
17
19
 
18
20
  typedef std::function<void (int jobId, const char* errorMessage)> RNFSTurboErrorCallback;
@@ -155,3 +157,5 @@ public:
155
157
 
156
158
  void setResourceValue(const char* path, const char* optionType, const char* optionValue);
157
159
  };
160
+
161
+ }