react-native-debug-toolkit 0.3.1 → 0.4.1

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
@@ -10,6 +10,24 @@ npm install react-native-debug-toolkit
10
10
  yarn add react-native-debug-toolkit
11
11
  ```
12
12
 
13
+ ### iOS Additional Setup
14
+
15
+ This toolkit uses FLEX and DoraemonKit for iOS debugging features. To properly integrate:
16
+
17
+ 1. Make sure CocoaPods is installed in your project
18
+ 2. Add these dependencies to your Podfile:
19
+
20
+ ```ruby
21
+ pod 'FLEX', :configurations => ['Debug']
22
+ pod 'DoraemonKit/Core', :configurations => ['Debug']
23
+ ```
24
+
25
+ 3. Run pod install in your iOS directory:
26
+
27
+ ```bash
28
+ cd ios && pod install
29
+ ```
30
+
13
31
  ## Basic Usage
14
32
 
15
33
  ```javascript
@@ -0,0 +1,30 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ android {
4
+ compileSdkVersion rootProject.ext.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 30
5
+ buildToolsVersion rootProject.ext.hasProperty('buildToolsVersion') ? rootProject.ext.buildToolsVersion : "30.0.3"
6
+
7
+ defaultConfig {
8
+ minSdkVersion rootProject.ext.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 21
9
+ targetSdkVersion rootProject.ext.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 30
10
+ versionCode 1
11
+ versionName "1.0"
12
+ }
13
+
14
+ compileOptions {
15
+ sourceCompatibility JavaVersion.VERSION_1_8
16
+ targetCompatibility JavaVersion.VERSION_1_8
17
+ }
18
+ }
19
+
20
+ repositories {
21
+ mavenCentral()
22
+ maven { url "https://jitpack.io" }
23
+ google()
24
+ }
25
+
26
+ dependencies {
27
+ implementation "com.facebook.react:react-native:+"
28
+ implementation 'io.github.didi.dokit:dokitx:3.7.1'
29
+ implementation 'com.android.volley:volley:1.2.0'
30
+ }
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.reactnative.debuglibs">
4
+
5
+ <uses-permission android:name="android.permission.INTERNET" />
6
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
7
+
8
+ </manifest>
@@ -4,7 +4,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
4
4
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
5
5
  import com.facebook.react.bridge.ReactMethod;
6
6
  import com.facebook.react.bridge.Promise;
7
- import com.facebook.react.bridge.Callback;
8
7
 
9
8
  import java.util.HashMap;
10
9
  import java.util.Map;
@@ -25,36 +24,13 @@ public class BuildTypeModule extends ReactContextBaseJavaModule {
25
24
  @Override
26
25
  public Map<String, Object> getConstants() {
27
26
  final Map<String, Object> constants = new HashMap<>();
28
- constants.put("isDebug", BuildConfig.DEBUG);
27
+ constants.put("buildType", BuildConfig.DEBUG ? "debug" : "release");
29
28
  return constants;
30
29
  }
31
30
 
32
- @ReactMethod
33
- public void isDebugMode(Promise promise) {
34
- try {
35
- promise.resolve(BuildConfig.DEBUG);
36
- } catch (Exception e) {
37
- promise.reject("ERR_UNEXPECTED", e.getMessage(), e);
38
- }
39
- }
40
-
41
- @ReactMethod
42
- public void isReleaseMode(Promise promise) {
43
- try {
44
- promise.resolve(!BuildConfig.DEBUG);
45
- } catch (Exception e) {
46
- promise.reject("ERR_UNEXPECTED", e.getMessage(), e);
47
- }
48
- }
49
-
50
- @ReactMethod(isBlockingSynchronousMethod = true)
51
- public Boolean isDebugModeSync() {
52
- return BuildConfig.DEBUG;
53
- }
54
-
55
31
  @ReactMethod(isBlockingSynchronousMethod = true)
56
- public Boolean isReleaseModeSync() {
57
- return !BuildConfig.DEBUG;
32
+ public String getBuildTypeSync() {
33
+ return BuildConfig.DEBUG ? "debug" : "release";
58
34
  }
59
35
 
60
36
  @ReactMethod
@@ -0,0 +1,68 @@
1
+ package com.reactnative.debuglibs;
2
+
3
+ import android.app.Application;
4
+ import android.widget.Toast;
5
+ import androidx.annotation.NonNull;
6
+
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
9
+ import com.facebook.react.bridge.ReactMethod;
10
+
11
+ import io.github.didi.dokit.DoKit;
12
+ import io.github.didi.dokit.kit.AbstractKit;
13
+
14
+ import java.util.ArrayList;
15
+ import java.util.List;
16
+
17
+ public class RNDebugLibsModule extends ReactContextBaseJavaModule {
18
+ private final ReactApplicationContext reactContext;
19
+
20
+ public RNDebugLibsModule(ReactApplicationContext reactContext) {
21
+ super(reactContext);
22
+ this.reactContext = reactContext;
23
+ }
24
+
25
+ @NonNull
26
+ @Override
27
+ public String getName() {
28
+ return "RNDebugLibs";
29
+ }
30
+
31
+ @ReactMethod
32
+ public void showExplorer() {
33
+ // FLEX is iOS only
34
+ }
35
+
36
+ @ReactMethod
37
+ public void hideExplorer() {
38
+ // FLEX is iOS only
39
+ }
40
+
41
+ @ReactMethod
42
+ public void toggleExplorer() {
43
+ // FLEX is iOS only
44
+ }
45
+
46
+ @ReactMethod
47
+ public void installDoraemonKit(String productId) {
48
+ Application app = (Application) reactContext.getApplicationContext();
49
+ List<AbstractKit> kits = new ArrayList<>();
50
+ // Initialize DoKit with custom kits if needed
51
+ DoKit.Builder(app)
52
+ .productId(productId)
53
+ .customKits(kits)
54
+ .build();
55
+ }
56
+
57
+ @ReactMethod
58
+ public void showDoraemonKit() {
59
+ Toast.makeText(reactContext, "showDoraemonKit被调用", Toast.LENGTH_SHORT).show();
60
+ DoKit.showToolPanel();
61
+ }
62
+
63
+ @ReactMethod
64
+ public void hideDoraemonKit() {
65
+ Toast.makeText(reactContext, "hideDoraemonKit被调用", Toast.LENGTH_SHORT).show();
66
+ DoKit.hideToolPanel();
67
+ }
68
+ }
@@ -0,0 +1,28 @@
1
+ package com.reactnative.debuglibs;
2
+
3
+ import androidx.annotation.NonNull;
4
+
5
+ import com.facebook.react.ReactPackage;
6
+ import com.facebook.react.bridge.NativeModule;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.uimanager.ViewManager;
9
+
10
+ import java.util.ArrayList;
11
+ import java.util.Collections;
12
+ import java.util.List;
13
+
14
+ public class RNDebugLibsPackage implements ReactPackage {
15
+ @NonNull
16
+ @Override
17
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ List<NativeModule> modules = new ArrayList<>();
19
+ modules.add(new RNDebugLibsModule(reactContext));
20
+ return modules;
21
+ }
22
+
23
+ @NonNull
24
+ @Override
25
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
26
+ return Collections.emptyList();
27
+ }
28
+ }
@@ -1,4 +1,9 @@
1
1
  #import <React/RCTBridgeModule.h>
2
2
 
3
+ /**
4
+ * BuildTypeModule
5
+ * Native module that provides information about the current build type (debug or release)
6
+ * Used to conditionally enable debugging tools only in debug builds
7
+ */
3
8
  @interface BuildTypeModule : NSObject <RCTBridgeModule>
4
9
  @end
@@ -12,49 +12,20 @@ RCT_EXPORT_MODULE();
12
12
  - (NSDictionary *)constantsToExport
13
13
  {
14
14
  #ifdef DEBUG
15
- BOOL isDebug = YES;
15
+ NSString *buildType = @"debug";
16
16
  #else
17
- BOOL isDebug = NO;
17
+ NSString *buildType = @"release";
18
18
  #endif
19
19
 
20
- return @{ @"isDebug": @(isDebug) };
20
+ return @{ @"buildType": buildType };
21
21
  }
22
22
 
23
- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isDebugModeSync)
23
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getBuildTypeSync)
24
24
  {
25
25
  #ifdef DEBUG
26
- return @(YES);
26
+ return @"debug";
27
27
  #else
28
- return @(NO);
29
- #endif
30
- }
31
-
32
- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isReleaseModeSync)
33
- {
34
- #ifdef DEBUG
35
- return @(NO);
36
- #else
37
- return @(YES);
38
- #endif
39
- }
40
-
41
- RCT_EXPORT_METHOD(isDebugMode:(RCTPromiseResolveBlock)resolve
42
- rejecter:(RCTPromiseRejectBlock)reject)
43
- {
44
- #ifdef DEBUG
45
- resolve(@(YES));
46
- #else
47
- resolve(@(NO));
48
- #endif
49
- }
50
-
51
- RCT_EXPORT_METHOD(isReleaseMode:(RCTPromiseResolveBlock)resolve
52
- rejecter:(RCTPromiseRejectBlock)reject)
53
- {
54
- #ifdef DEBUG
55
- resolve(@(NO));
56
- #else
57
- resolve(@(YES));
28
+ return @"release";
58
29
  #endif
59
30
  }
60
31
 
@@ -0,0 +1,10 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ /**
4
+ * RNDebugLibs
5
+ * Native module that provides access to FLEX and DoraemonKit debugging tools
6
+ * Note: These debugging tools are only available in DEBUG builds
7
+ */
8
+ @interface RNDebugLibs : NSObject <RCTBridgeModule>
9
+
10
+ @end
@@ -0,0 +1,79 @@
1
+ #import "RNDebugLibs.h"
2
+
3
+ #ifdef DEBUG
4
+ #import "FLEXManager.h"
5
+ #import <DoraemonKit/DoraemonManager.h>
6
+ #endif
7
+
8
+ @implementation RNDebugLibs
9
+
10
+ // Export the module
11
+ RCT_EXPORT_MODULE();
12
+
13
+ RCT_EXPORT_METHOD(showExplorer)
14
+ {
15
+ #ifdef DEBUG
16
+ dispatch_async(dispatch_get_main_queue(), ^{
17
+ [[FLEXManager sharedManager] showExplorer];
18
+ });
19
+ #else
20
+ NSLog(@"[RNDebugLibs] showExplorer is only available in DEBUG builds");
21
+ #endif
22
+ }
23
+
24
+ RCT_EXPORT_METHOD(hideExplorer)
25
+ {
26
+ #ifdef DEBUG
27
+ dispatch_async(dispatch_get_main_queue(), ^{
28
+ [[FLEXManager sharedManager] hideExplorer];
29
+ });
30
+ #else
31
+ NSLog(@"[RNDebugLibs] hideExplorer is only available in DEBUG builds");
32
+ #endif
33
+ }
34
+
35
+ RCT_EXPORT_METHOD(toggleExplorer)
36
+ {
37
+ #ifdef DEBUG
38
+ dispatch_async(dispatch_get_main_queue(), ^{
39
+ [[FLEXManager sharedManager] toggleExplorer];
40
+ });
41
+ #else
42
+ NSLog(@"[RNDebugLibs] toggleExplorer is only available in DEBUG builds");
43
+ #endif
44
+ }
45
+
46
+ RCT_EXPORT_METHOD(installDoraemonKit:(NSString *)productId)
47
+ {
48
+ #ifdef DEBUG
49
+ dispatch_async(dispatch_get_main_queue(), ^{
50
+ [[DoraemonManager shareInstance] installWithPid:productId];
51
+ });
52
+ #else
53
+ NSLog(@"[RNDebugLibs] installDoraemonKit is only available in DEBUG builds");
54
+ #endif
55
+ }
56
+
57
+ RCT_EXPORT_METHOD(showDoraemonKit)
58
+ {
59
+ #ifdef DEBUG
60
+ dispatch_async(dispatch_get_main_queue(), ^{
61
+ [[DoraemonManager shareInstance] showDoraemon];
62
+ });
63
+ #else
64
+ NSLog(@"[RNDebugLibs] showDoraemonKit is only available in DEBUG builds");
65
+ #endif
66
+ }
67
+
68
+ RCT_EXPORT_METHOD(hideDoraemonKit)
69
+ {
70
+ #ifdef DEBUG
71
+ dispatch_async(dispatch_get_main_queue(), ^{
72
+ [[DoraemonManager shareInstance] hiddenDoraemon];
73
+ });
74
+ #else
75
+ NSLog(@"[RNDebugLibs] hideDoraemonKit is only available in DEBUG builds");
76
+ #endif
77
+ }
78
+
79
+ @end
@@ -0,0 +1,55 @@
1
+ import { NativeModules, Platform } from 'react-native'
2
+
3
+ // 添加调试日志,查看是否正确获取了RNDebugLibs模块
4
+ const { RNDebugLibs } = NativeModules
5
+ console.log('Available Native Modules:', Object.keys(NativeModules))
6
+ console.log('RNDebugLibs module loaded:', !!RNDebugLibs)
7
+
8
+ export default class NativeDebugLibs {
9
+ // FLEX methods (iOS only)
10
+ static showExplorer() {
11
+ if (Platform.OS === 'ios' && RNDebugLibs) {
12
+ RNDebugLibs.showExplorer()
13
+ }
14
+ }
15
+
16
+ static hideExplorer() {
17
+ if (Platform.OS === 'ios' && RNDebugLibs) {
18
+ RNDebugLibs.hideExplorer()
19
+ }
20
+ }
21
+
22
+ static toggleExplorer() {
23
+ if (Platform.OS === 'ios' && RNDebugLibs) {
24
+ RNDebugLibs.toggleExplorer()
25
+ }
26
+ }
27
+
28
+ // DoraemonKit/DoKit methods
29
+ static installDoraemonKit(productId) {
30
+ console.log('Calling installDoraemonKit with:', productId)
31
+ if (RNDebugLibs) {
32
+ RNDebugLibs.installDoraemonKit(productId)
33
+ } else {
34
+ console.warn('RNDebugLibs module not available')
35
+ }
36
+ }
37
+
38
+ static showDoraemonKit() {
39
+ console.log('Calling showDoraemonKit')
40
+ if (RNDebugLibs) {
41
+ RNDebugLibs.showDoraemonKit()
42
+ } else {
43
+ console.warn('RNDebugLibs module not available')
44
+ }
45
+ }
46
+
47
+ static hideDoraemonKit() {
48
+ console.log('Calling hideDoraemonKit')
49
+ if (RNDebugLibs) {
50
+ RNDebugLibs.hideDoraemonKit()
51
+ } else {
52
+ console.warn('RNDebugLibs module not available')
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,65 @@
1
+ import { Platform } from 'react-native';
2
+ import NativeDebugLibs from '../NativeDebugLibs';
3
+
4
+ // Define available third-party debug libraries
5
+ const availableLibs = [
6
+ {
7
+ id: 'flex',
8
+ name: 'FLEX',
9
+ description: 'In-app debugging and exploration tool for iOS',
10
+ platform: 'ios',
11
+ icon: 'tools',
12
+ actions: [
13
+ { id: 'showExplorer', label: 'Show Explorer', method: NativeDebugLibs.showExplorer },
14
+ { id: 'hideExplorer', label: 'Hide Explorer', method: NativeDebugLibs.hideExplorer },
15
+ ]
16
+ },
17
+ {
18
+ id: 'doraemonkit',
19
+ name: 'DoraemonKit',
20
+ description: 'A full-featured iOS & Android development assistant',
21
+ platform: 'both',
22
+ icon: 'box',
23
+ actions: [
24
+ { id: 'showDoraemonKit', label: 'Show DoraemonKit', method: NativeDebugLibs.showDoraemonKit },
25
+ { id: 'hideDoraemonKit', label: 'Hide DoraemonKit', method: NativeDebugLibs.hideDoraemonKit },
26
+ ]
27
+ }
28
+ ];
29
+
30
+ // Get libraries available for current platform
31
+ const getPlatformLibs = () => {
32
+ const currentPlatform = Platform.OS;
33
+ return availableLibs.filter(lib =>
34
+ lib.platform === 'both' || lib.platform === currentPlatform
35
+ );
36
+ };
37
+
38
+ // Setup function is minimal since we're just presenting UI options
39
+ const setup = () => {
40
+ if (!__DEV__) {
41
+ return;
42
+ }
43
+ // No additional setup needed beyond initialization
44
+ };
45
+
46
+ // Get data - return available libraries for this platform
47
+ const getData = () => {
48
+ return getPlatformLibs();
49
+ };
50
+
51
+ // Cleanup function (if needed)
52
+ const cleanup = () => {
53
+ // Nothing specific to clean up
54
+ };
55
+
56
+ // Export the feature factory function
57
+ export const createThirdPartyLibsFeature = () => {
58
+ return {
59
+ name: 'thirdPartyLibs',
60
+ label: 'Debug Libraries',
61
+ setup,
62
+ getData,
63
+ cleanup
64
+ };
65
+ };
package/lib/index.js CHANGED
@@ -4,6 +4,8 @@ import { createPerformanceFeature} from './features/PerformanceFeature'
4
4
  import { createConsoleLogFeature } from './features/ConsoleLogFeature'
5
5
  import { createZustandLogFeature, zustandLogMiddleware } from './features/ZustandLogFeature'
6
6
  import { createNavigationLogFeature, addNavigationLog } from './features/NavigationLogFeature'
7
+ import { createThirdPartyLibsFeature } from './features/ThirdPartyLibsFeature'
8
+ import NativeDebugLibs from './NativeDebugLibs'
7
9
 
8
10
  // Registry mapping feature names (strings) to their creator functions
9
11
  const featureRegistry = {
@@ -12,24 +14,31 @@ const featureRegistry = {
12
14
  performance: createPerformanceFeature,
13
15
  zustand: createZustandLogFeature,
14
16
  navigation: createNavigationLogFeature,
17
+ thirdPartyLibs: createThirdPartyLibsFeature,
15
18
  // Add other built-in features here
16
19
  // 'storage': createStorageFeature,
17
20
  }
18
21
 
19
22
  // List of default features (can use strings now)
20
- const defaultFeatures = ['network', 'console', 'zustand', 'navigation']
23
+ const defaultFeatures = ['network', 'console', 'zustand', 'navigation', 'thirdPartyLibs']
21
24
 
22
25
  /**
23
26
  * Initializes and shows the Debug ToolKit panel with specified features.
24
27
  * Only runs in development mode (__DEV__ === true).
25
28
  * Features can be specified as strings (e.g., 'network') or creator functions.
26
29
  * @param {Array<string|Function>} features - Array of feature names (strings) or creator functions. Defaults to standard features.
30
+ * @param {Object} options - Additional options like doraemonProductId for third-party debug libraries
27
31
  */
28
- export function initializeDebugToolkit(features = defaultFeatures) {
32
+ export function initializeDebugToolkit(features = defaultFeatures, options = {}) {
29
33
 
30
34
  try {
31
35
  const debugToolKit = new DebugToolKit();
32
36
 
37
+ // Initialize third-party debug libraries if configured
38
+ if (options.doraemonProductId) {
39
+ NativeDebugLibs.installDoraemonKit(options.doraemonProductId);
40
+ }
41
+
33
42
  features.forEach(featureIdentifier => {
34
43
  let feature = null;
35
44
  let featureCreator = null;
@@ -84,6 +93,7 @@ export {
84
93
  createConsoleLogFeature,
85
94
  createZustandLogFeature,
86
95
  createNavigationLogFeature,
96
+ createThirdPartyLibsFeature,
87
97
  addNavigationLog,
88
98
  zustandLogMiddleware, // Export middleware for use in Zustand stores
89
99
  featureRegistry
@@ -20,6 +20,7 @@ import SubViewPerformance from './SubViewPerformance'
20
20
  import SubViewConsoleLogs from './SubViewConsoleLogs'
21
21
  import SubViewZustandLogs from './SubViewZustandLogs'
22
22
  import SubViewNavigationLogs from './SubViewNavigationLogs'
23
+ import SubViewThirdPartyLibs from './SubViewThirdPartyLibs'
23
24
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window')
24
25
 
25
26
  export default class FloatPanelView extends Component {
@@ -319,6 +320,10 @@ export default class FloatPanelView extends Component {
319
320
  if (feature.name === 'navigation') {
320
321
  return <SubViewNavigationLogs logs={data} />
321
322
  }
323
+
324
+ if (feature.name === 'thirdPartyLibs') {
325
+ return <SubViewThirdPartyLibs libraries={data} />
326
+ }
322
327
 
323
328
  // Generic fallback for other feature types
324
329
  return (
@@ -0,0 +1,239 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ FlatList,
7
+ TouchableOpacity,
8
+ TextInput,
9
+ Platform,
10
+ } from 'react-native';
11
+
12
+ const SubViewThirdPartyLibs = ({ libraries = [] }) => {
13
+ const [expandedLibs, setExpandedLibs] = useState(new Set());
14
+ const [actionParams, setActionParams] = useState({});
15
+
16
+ // Set all libraries to expanded by default and set default product ID
17
+ useEffect(() => {
18
+ // Create a set of all library IDs to set them as expanded
19
+ const allLibIds = new Set(libraries.map(lib => lib.id));
20
+ setExpandedLibs(allLibIds);
21
+
22
+ // Initialize default product ID for all actions that might need it
23
+ const defaultParams = {};
24
+ libraries.forEach(lib => {
25
+ lib.actions.forEach(action => {
26
+ if (action.hasParam) {
27
+ defaultParams[`${lib.id}_${action.id}`] = 'default';
28
+ }
29
+ });
30
+ });
31
+ setActionParams(defaultParams);
32
+ }, [libraries]);
33
+
34
+ // Handle lib expansion/collapse
35
+ const toggleLibExpand = (libId) => {
36
+ setExpandedLibs(prev => {
37
+ const newSet = new Set(prev);
38
+ if (newSet.has(libId)) {
39
+ newSet.delete(libId);
40
+ } else {
41
+ newSet.add(libId);
42
+ }
43
+ return newSet;
44
+ });
45
+ };
46
+
47
+ // Execute library action
48
+ const executeAction = (action, libId) => {
49
+ try {
50
+ if (action.hasParam) {
51
+ // Get parameter value (if needed)
52
+ const paramValue = actionParams[`${libId}_${action.id}`] || 'default';
53
+ action.method(paramValue);
54
+ } else {
55
+ action.method();
56
+ }
57
+ // No alerts shown as per requirement
58
+ } catch (error) {
59
+ // Silent error handling as per requirement
60
+ console.error(`Failed to execute ${action.label}:`, error);
61
+ }
62
+ };
63
+
64
+ // Handle param input change
65
+ const handleParamChange = (libId, actionId, value) => {
66
+ setActionParams({
67
+ ...actionParams,
68
+ [`${libId}_${actionId}`]: value,
69
+ });
70
+ };
71
+
72
+ // Render a single library card
73
+ const renderLibraryItem = ({ item }) => {
74
+ const isExpanded = expandedLibs.has(item.id);
75
+ const isPlatformSupported = item.platform === 'both' ||
76
+ item.platform === Platform.OS;
77
+
78
+ if (!isPlatformSupported) return null;
79
+
80
+ return (
81
+ <View style={styles.libraryCard}>
82
+ <TouchableOpacity
83
+ style={styles.libraryHeader}
84
+ onPress={() => toggleLibExpand(item.id)}>
85
+ <View style={styles.libraryTitle}>
86
+ <Text style={styles.libraryName}>{item.name}</Text>
87
+ <Text style={styles.platformBadge}>
88
+ {item.platform === 'both' ? 'iOS & Android' : item.platform}
89
+ </Text>
90
+ </View>
91
+ <Text style={styles.expandIcon}>{isExpanded ? '▼' : '▶'}</Text>
92
+ </TouchableOpacity>
93
+
94
+ <Text style={styles.libraryDescription}>{item.description}</Text>
95
+
96
+ {isExpanded && (
97
+ <View style={styles.actionsContainer}>
98
+ {item.actions.map((action) => (
99
+ <View key={action.id} style={styles.actionItem}>
100
+ {action.hasParam && (
101
+ <TextInput
102
+ style={styles.paramInput}
103
+ placeholder={action.paramPlaceholder || 'Parameter'}
104
+ value={actionParams[`${item.id}_${action.id}`] || 'default'}
105
+ onChangeText={(text) =>
106
+ handleParamChange(item.id, action.id, text)
107
+ }
108
+ />
109
+ )}
110
+ <TouchableOpacity
111
+ style={styles.actionButton}
112
+ onPress={() => executeAction(action, item.id)}>
113
+ <Text style={styles.actionButtonText}>{action.label}</Text>
114
+ </TouchableOpacity>
115
+ </View>
116
+ ))}
117
+ </View>
118
+ )}
119
+ </View>
120
+ );
121
+ };
122
+
123
+ // Filter platform-supported libraries
124
+ const supportedLibraries = libraries.filter(
125
+ lib => lib.platform === 'both' || lib.platform === Platform.OS
126
+ );
127
+
128
+ return (
129
+ <View style={styles.container}>
130
+ {supportedLibraries.length === 0 ? (
131
+ <Text style={styles.emptyText}>
132
+ No debug libraries available for this platform
133
+ </Text>
134
+ ) : (
135
+ <FlatList
136
+ data={supportedLibraries}
137
+ renderItem={renderLibraryItem}
138
+ keyExtractor={(item) => item.id}
139
+ contentContainerStyle={styles.listContent}
140
+ />
141
+ )}
142
+ </View>
143
+ );
144
+ };
145
+
146
+ const styles = StyleSheet.create({
147
+ container: {
148
+ flex: 1,
149
+ backgroundColor: '#fff',
150
+ },
151
+ listContent: {
152
+ padding: 12,
153
+ },
154
+ emptyText: {
155
+ textAlign: 'center',
156
+ color: '#999',
157
+ marginTop: 20,
158
+ fontSize: 16,
159
+ },
160
+ libraryCard: {
161
+ backgroundColor: '#f8f9fa',
162
+ borderRadius: 8,
163
+ borderWidth: 1,
164
+ borderColor: '#e9ecef',
165
+ marginBottom: 16,
166
+ padding: 12,
167
+ elevation: 1,
168
+ shadowColor: '#000',
169
+ shadowOffset: { width: 0, height: 1 },
170
+ shadowOpacity: 0.1,
171
+ shadowRadius: 1,
172
+ },
173
+ libraryHeader: {
174
+ flexDirection: 'row',
175
+ justifyContent: 'space-between',
176
+ alignItems: 'center',
177
+ },
178
+ libraryTitle: {
179
+ flexDirection: 'row',
180
+ alignItems: 'center',
181
+ flex: 1,
182
+ },
183
+ libraryName: {
184
+ fontSize: 18,
185
+ fontWeight: 'bold',
186
+ color: '#333',
187
+ marginRight: 8,
188
+ },
189
+ platformBadge: {
190
+ fontSize: 12,
191
+ color: '#666',
192
+ backgroundColor: '#e9ecef',
193
+ paddingHorizontal: 8,
194
+ paddingVertical: 2,
195
+ borderRadius: 12,
196
+ overflow: 'hidden',
197
+ },
198
+ expandIcon: {
199
+ fontSize: 14,
200
+ color: '#666',
201
+ },
202
+ libraryDescription: {
203
+ marginTop: 8,
204
+ marginBottom: 12,
205
+ color: '#666',
206
+ fontSize: 14,
207
+ lineHeight: 20,
208
+ },
209
+ actionsContainer: {
210
+ marginTop: 8,
211
+ borderTopWidth: 1,
212
+ borderTopColor: '#eee',
213
+ paddingTop: 12,
214
+ },
215
+ actionItem: {
216
+ marginBottom: 8,
217
+ },
218
+ paramInput: {
219
+ borderWidth: 1,
220
+ borderColor: '#ddd',
221
+ borderRadius: 4,
222
+ padding: 8,
223
+ marginBottom: 8,
224
+ fontSize: 14,
225
+ },
226
+ actionButton: {
227
+ backgroundColor: '#0D96F2',
228
+ padding: 10,
229
+ borderRadius: 4,
230
+ alignItems: 'center',
231
+ },
232
+ actionButtonText: {
233
+ color: '#fff',
234
+ fontWeight: '500',
235
+ fontSize: 14,
236
+ },
237
+ });
238
+
239
+ export default SubViewThirdPartyLibs;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "react-native-debug-toolkit",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "A simple yet powerful debugging toolkit for React Native with a convenient floating UI for development",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
+ "podspec": "react-native-debug-toolkit.podspec",
7
8
  "scripts": {
8
9
  "test": "echo \"Error: no test specified\" && exit 1",
9
10
  "bundle": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output dist/main.jsbundle --assets-dest dist"
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3
+
4
+ Pod::Spec.new do |s|
5
+ s.name = "react-native-debug-toolkit"
6
+ s.version = package['version']
7
+ s.summary = package['description']
8
+ s.homepage = package['repository']['url']
9
+ s.license = package['license']
10
+ s.author = package['author']
11
+ s.platform = :ios, "11.0"
12
+ s.source = { :git => package['repository']['url'], :tag => "#{s.version}" }
13
+ s.source_files = "ios/**/*.{h,m}"
14
+
15
+ s.dependency "React-Core"
16
+
17
+ # FLEX is only needed for debug builds
18
+ s.dependency "FLEX", "~> 5.0"
19
+
20
+ # DoraemonKit is only needed for debug builds
21
+ s.dependency "DoraemonKit/Core", "~> 3.0"
22
+
23
+ # This ensures FLEX and DoraemonKit are only included in debug builds
24
+ s.pod_target_xcconfig = { 'OTHER_CFLAGS' => '-DDebug=$(CONFIGURATION)' }
25
+ end
@@ -2,4 +2,17 @@
2
2
 
3
3
  module.exports = {
4
4
  // Let React Native's auto-linking handle all dependencies normally
5
+ dependencies: {
6
+ "react-native-debug-toolkit": {
7
+ platforms: {
8
+ ios: {
9
+ podspecPath: "./react-native-debug-toolkit.podspec",
10
+ sourceDir: "./ios"
11
+ },
12
+ android: {
13
+ sourceDir: "./android"
14
+ }
15
+ }
16
+ }
17
+ }
5
18
  };