@vanikya/ota-react-native 0.1.3 → 0.1.5

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
@@ -1,4 +1,6 @@
1
- # @ota-update/react-native
1
+ # @vanikya/ota-react-native
2
+
3
+ > **Beta Notice**: This package is currently in beta. Testing is in progress and APIs may change. Use in production at your own discretion. We welcome feedback and bug reports via [GitHub Issues](https://github.com/vanikya/ota-update/issues).
2
4
 
3
5
  React Native SDK for OTA (Over-The-Air) updates. A self-hosted alternative to CodePush and EAS Updates.
4
6
 
@@ -7,6 +7,7 @@ apply plugin: 'kotlin-android'
7
7
 
8
8
  android {
9
9
  namespace "com.otaupdate"
10
+
10
11
  compileSdkVersion safeExtGet('compileSdkVersion', 34)
11
12
 
12
13
  defaultConfig {
@@ -34,6 +35,10 @@ android {
34
35
  java.srcDirs = ['src/main/java']
35
36
  }
36
37
  }
38
+
39
+ lintOptions {
40
+ abortOnError false
41
+ }
37
42
  }
38
43
 
39
44
  repositories {
package/app.plugin.js ADDED
@@ -0,0 +1,104 @@
1
+ const { withMainApplication, withAppDelegate, withDangerousMod } = require('@expo/config-plugins');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ function withOTAUpdateAndroid(config) {
6
+ return withMainApplication(config, (config) => {
7
+ let contents = config.modResults.contents;
8
+
9
+ // Check if already modified
10
+ if (contents.includes('getJSBundleFile')) {
11
+ return config;
12
+ }
13
+
14
+ // Add imports if not present
15
+ if (!contents.includes('import android.content.SharedPreferences')) {
16
+ contents = contents.replace(
17
+ /^(package .+?\n)/m,
18
+ `$1\nimport android.content.SharedPreferences\nimport java.io.File\n`
19
+ );
20
+ }
21
+
22
+ // For Kotlin-based MainApplication (Expo SDK 50+)
23
+ // Find the ReactNativeHost and add getJSBundleFile override
24
+ const kotlinPattern = /override\s+fun\s+getUseDeveloperSupport\(\):\s+Boolean\s*=\s*BuildConfig\.DEBUG/;
25
+
26
+ if (kotlinPattern.test(contents)) {
27
+ contents = contents.replace(
28
+ kotlinPattern,
29
+ `override fun getJSBundleFile(): String? {
30
+ val prefs: SharedPreferences = applicationContext.getSharedPreferences("OTAUpdate", android.content.Context.MODE_PRIVATE)
31
+ val bundlePath = prefs.getString("BundlePath", null)
32
+ if (bundlePath != null && File(bundlePath).exists()) {
33
+ return bundlePath
34
+ }
35
+ return null
36
+ }
37
+
38
+ override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG`
39
+ );
40
+ }
41
+
42
+ config.modResults.contents = contents;
43
+ return config;
44
+ });
45
+ }
46
+
47
+ function withOTAUpdateIOS(config) {
48
+ return withAppDelegate(config, (config) => {
49
+ let contents = config.modResults.contents;
50
+
51
+ // Check if already modified
52
+ if (contents.includes('OTAUpdateBundlePath')) {
53
+ return config;
54
+ }
55
+
56
+ // For Swift AppDelegate
57
+ if (config.modResults.language === 'swift') {
58
+ // Add helper function before the class closing brace
59
+ const helperFunction = `
60
+ // OTA Update: Check for downloaded bundle
61
+ private func getOTABundleURL() -> URL? {
62
+ let defaults = UserDefaults.standard
63
+ if let bundlePath = defaults.string(forKey: "OTAUpdateBundlePath") {
64
+ let fileURL = URL(fileURLWithPath: bundlePath)
65
+ if FileManager.default.fileExists(atPath: bundlePath) {
66
+ return fileURL
67
+ }
68
+ }
69
+ return nil
70
+ }
71
+ `;
72
+
73
+ // Find bundleURL method and modify it
74
+ const bundleURLPattern = /func\s+bundleURL\(\)\s*->\s*URL\?\s*\{[\s\S]*?\n\s*\}/;
75
+
76
+ if (bundleURLPattern.test(contents)) {
77
+ contents = contents.replace(
78
+ bundleURLPattern,
79
+ `func bundleURL() -> URL? {
80
+ // OTA Update: Check for downloaded bundle first
81
+ if let otaBundle = getOTABundleURL() {
82
+ return otaBundle
83
+ }
84
+ #if DEBUG
85
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
86
+ #else
87
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
88
+ #endif
89
+ }
90
+ ${helperFunction}`
91
+ );
92
+ }
93
+ }
94
+
95
+ config.modResults.contents = contents;
96
+ return config;
97
+ });
98
+ }
99
+
100
+ module.exports = function withOTAUpdate(config) {
101
+ config = withOTAUpdateAndroid(config);
102
+ config = withOTAUpdateIOS(config);
103
+ return config;
104
+ };
@@ -135,7 +135,7 @@ class OTAUpdate: NSObject {
135
135
  @objc
136
136
  func applyBundle(_ bundlePath: String, restart: Bool, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
137
137
  // Store the bundle path for next launch
138
- UserDefaults.standard.set(bundlePath, forKey: "OTAUpdate_BundlePath")
138
+ UserDefaults.standard.set(bundlePath, forKey: "OTAUpdateBundlePath")
139
139
  UserDefaults.standard.synchronize()
140
140
 
141
141
  if restart {
@@ -151,13 +151,13 @@ class OTAUpdate: NSObject {
151
151
 
152
152
  @objc
153
153
  func getPendingBundlePath(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
154
- let path = UserDefaults.standard.string(forKey: "OTAUpdate_BundlePath")
154
+ let path = UserDefaults.standard.string(forKey: "OTAUpdateBundlePath")
155
155
  resolver(path)
156
156
  }
157
157
 
158
158
  @objc
159
159
  func clearPendingBundle(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
160
- UserDefaults.standard.removeObject(forKey: "OTAUpdate_BundlePath")
160
+ UserDefaults.standard.removeObject(forKey: "OTAUpdateBundlePath")
161
161
  UserDefaults.standard.synchronize()
162
162
  resolver(nil)
163
163
  }
@@ -6,16 +6,21 @@ Pod::Spec.new do |s|
6
6
  s.name = "ota-update"
7
7
  s.version = package["version"]
8
8
  s.summary = package["description"]
9
- s.homepage = package["repository"]["url"]
9
+ s.homepage = package["homepage"]
10
10
  s.license = package["license"]
11
- s.authors = { "OTA Update" => "support@ota-update.dev" }
11
+ s.authors = { "Vanikya" => "support@vanikya.com" }
12
12
 
13
13
  s.platforms = { :ios => "13.0" }
14
- s.source = { :git => "https://github.com/your-org/ota-update.git", :tag => "#{s.version}" }
14
+ s.source = { :git => "https://github.com/vanikya/ota-update.git", :tag => "v#{s.version}" }
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm,swift}"
17
17
 
18
- s.dependency "React-Core"
18
+ # Use install_modules_dependencies for new architecture support
19
+ if respond_to?(:install_modules_dependencies, true)
20
+ install_modules_dependencies(s)
21
+ else
22
+ s.dependency "React-Core"
23
+ end
19
24
 
20
25
  s.swift_version = "5.0"
21
26
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanikya/ota-react-native",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "OTA Update SDK for React Native apps - self-hosted CodePush/EAS Updates alternative",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -10,9 +10,11 @@
10
10
  "files": [
11
11
  "src",
12
12
  "lib",
13
- "ios",
14
13
  "android",
14
+ "ios",
15
15
  "*.podspec",
16
+ "react-native.config.js",
17
+ "app.plugin.js",
16
18
  "README.md"
17
19
  ],
18
20
  "scripts": {
@@ -56,7 +58,9 @@
56
58
  },
57
59
  "peerDependencies": {
58
60
  "react": ">=17.0.0",
59
- "react-native": ">=0.70.0"
61
+ "react-native": ">=0.70.0",
62
+ "expo-file-system": ">=15.0.0",
63
+ "expo-crypto": ">=12.0.0"
60
64
  },
61
65
  "peerDependenciesMeta": {
62
66
  "expo-file-system": {
@@ -74,10 +78,5 @@
74
78
  "module",
75
79
  "typescript"
76
80
  ]
77
- },
78
- "codegenConfig": {
79
- "name": "OTAUpdateSpec",
80
- "type": "modules",
81
- "jsSrcsDir": "src"
82
81
  }
83
82
  }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ packageImportPath: 'import com.otaupdate.OTAUpdatePackage;',
6
+ packageInstance: 'new OTAUpdatePackage()',
7
+ },
8
+ ios: {
9
+ // iOS uses Swift, auto-detected
10
+ },
11
+ },
12
+ },
13
+ };