react-native-config 1.5.9 → 1.6.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.
@@ -9,7 +9,14 @@ buildscript {
9
9
  }
10
10
  }
11
11
 
12
+ def isNewArchitectureEnabled() {
13
+ return project.hasProperty("newArchEnabled") && (project.newArchEnabled == "true" || project.newArchEnabled == true)
14
+ }
15
+
12
16
  apply plugin: 'com.android.library'
17
+ if (isNewArchitectureEnabled()) {
18
+ apply plugin: 'com.facebook.react'
19
+ }
13
20
 
14
21
  def safeExtGet(prop, fallback) {
15
22
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
@@ -44,10 +51,32 @@ android {
44
51
  targetSdkVersion rootProject.ext.targetSdkVersion
45
52
  versionCode 1
46
53
  versionName "1.0"
54
+
55
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
56
+
57
+ ndk {
58
+ abiFilters(*reactNativeArchitectures())
59
+ }
47
60
  }
48
61
  lintOptions {
49
62
  abortOnError false
50
63
  }
64
+
65
+ sourceSets.main {
66
+ java {
67
+ if (!isNewArchitectureEnabled()) {
68
+ srcDirs += ['src/oldarch/java']
69
+ } else {
70
+ // This should be done by the RN gradle plugin, for some reason it sometimes doesn't work
71
+ srcDirs += ['src/newarch/java']
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ def reactNativeArchitectures() {
78
+ def value = project.getProperties().get("reactNativeArchitectures")
79
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
51
80
  }
52
81
 
53
82
  repositories {
@@ -55,5 +84,5 @@ repositories {
55
84
  }
56
85
 
57
86
  dependencies {
58
- implementation "com.facebook.react:react-native:${safeExtGet("reactNative", "+")}" // from node_modules
87
+ implementation 'com.facebook.react:react-native:+'
59
88
  }
@@ -0,0 +1,90 @@
1
+ package com.lugg.RNCConfig;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.WritableArray;
5
+ import com.facebook.react.bridge.WritableMap;
6
+ import java.util.List;
7
+ import java.util.Map;
8
+
9
+ class MapConverter {
10
+ public static WritableMap convertMapToWritableMap(Map<String, Object> sourceMap) {
11
+ WritableMap writableMap = Arguments.createMap();
12
+ if (sourceMap == null) {
13
+ return writableMap; // Return empty map if source is null
14
+ }
15
+
16
+ for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
17
+ String key = entry.getKey();
18
+ Object value = entry.getValue();
19
+ putValueInMap(writableMap, key, value);
20
+ }
21
+ return writableMap;
22
+ }
23
+
24
+ private static void putValueInMap(WritableMap map, String key, Object value) {
25
+ if (value == null) {
26
+ map.putNull(key);
27
+ } else if (value instanceof String) {
28
+ map.putString(key, (String) value);
29
+ } else if (value instanceof Integer) {
30
+ map.putInt(key, (Integer) value);
31
+ } else if (value instanceof Long) {
32
+ map.putLong(key, (Long) value);
33
+ } else if (value instanceof Double) {
34
+ map.putDouble(key, (Double) value);
35
+ } else if (value instanceof Float) {
36
+ map.putDouble(key, (Float) value); // Float to double
37
+ } else if (value instanceof Boolean) {
38
+ map.putBoolean(key, (Boolean) value);
39
+ } else if (value instanceof Map) {
40
+ @SuppressWarnings("unchecked")
41
+ Map<String, Object> nestedMap = (Map<String, Object>) value;
42
+ map.putMap(key, convertMapToWritableMap(nestedMap));
43
+ } else if (value instanceof List) {
44
+ @SuppressWarnings("unchecked")
45
+ List<Object> list = (List<Object>) value;
46
+ WritableArray writableArray = convertListToWritableArray(list);
47
+ map.putArray(key, writableArray);
48
+ } else {
49
+ // Fallback for unsupported types: convert to string or handle as needed
50
+ map.putString(key, value.toString());
51
+ }
52
+ }
53
+
54
+ private static WritableArray convertListToWritableArray(List<Object> sourceList) {
55
+ WritableArray writableArray = Arguments.createArray();
56
+ if (sourceList == null) {
57
+ return writableArray;
58
+ }
59
+
60
+ for (Object item : sourceList) {
61
+ if (item == null) {
62
+ writableArray.pushNull();
63
+ } else if (item instanceof String) {
64
+ writableArray.pushString((String) item);
65
+ } else if (item instanceof Integer) {
66
+ writableArray.pushInt((Integer) item);
67
+ } else if (item instanceof Long) {
68
+ writableArray.pushInt(((Long) item).intValue()); // Or use custom handling
69
+ } else if (item instanceof Double) {
70
+ writableArray.pushDouble((Double) item);
71
+ } else if (item instanceof Float) {
72
+ writableArray.pushDouble((Float) item);
73
+ } else if (item instanceof Boolean) {
74
+ writableArray.pushBoolean((Boolean) item);
75
+ } else if (item instanceof Map) {
76
+ @SuppressWarnings("unchecked")
77
+ Map<String, Object> nestedMap = (Map<String, Object>) item;
78
+ writableArray.pushMap(convertMapToWritableMap(nestedMap));
79
+ } else if (item instanceof List) {
80
+ @SuppressWarnings("unchecked")
81
+ List<Object> nestedList = (List<Object>) item;
82
+ writableArray.pushArray(convertListToWritableArray(nestedList));
83
+ } else {
84
+ // Fallback
85
+ writableArray.pushString(item.toString());
86
+ }
87
+ }
88
+ return writableArray;
89
+ }
90
+ }
@@ -0,0 +1,62 @@
1
+ package com.lugg.RNCConfig;
2
+
3
+ import android.content.res.Resources;
4
+ import android.util.Log;
5
+ import com.facebook.react.bridge.ReactApplicationContext;
6
+ import com.facebook.react.bridge.WritableMap;
7
+ import java.lang.ClassNotFoundException;
8
+ import java.lang.IllegalAccessException;
9
+ import java.lang.reflect.Field;
10
+ import java.util.Map;
11
+ import java.util.HashMap;
12
+
13
+ public class RNCConfigModuleImpl {
14
+ public static final String NAME = "RNCConfigModule";
15
+
16
+ private ReactApplicationContext context;
17
+
18
+ public RNCConfigModuleImpl(ReactApplicationContext context) {
19
+ this.context = context;
20
+ }
21
+
22
+ public WritableMap getConfig() {
23
+ final Map<String, Object> ret = new HashMap<>();
24
+
25
+ // Codegen ensures that the constants defined in the module spec and in the native module implementation
26
+ // are consistent, which is tad problematic in this case, as the constants are dependant on the `.env`
27
+ // file. The simple workaround is to define a `config` object that will contain actual constants.
28
+ // This way the types between JS and Native side remain consistent, while functionality stays the same.
29
+ // TL;DR:
30
+ // instead of exporting { constant1: "value1", constant2: "value2" }
31
+ // we export { config: { constant1: "value1", constant2: "value2" } }
32
+ // because of type safety on the new arch
33
+ final Map<String, Object> realConstants = new HashMap<>();
34
+
35
+ try {
36
+ int resId = this.context.getResources().getIdentifier("build_config_package", "string", context.getPackageName());
37
+ String className;
38
+ try {
39
+ className = this.context.getString(resId);
40
+ } catch (Resources.NotFoundException e) {
41
+ className = this.context.getApplicationContext().getPackageName();
42
+ }
43
+ Class clazz = Class.forName(className + ".BuildConfig");
44
+ Field[] fields = clazz.getDeclaredFields();
45
+ for(Field f: fields) {
46
+ try {
47
+ realConstants.put(f.getName(), f.get(null));
48
+ }
49
+ catch (IllegalAccessException e) {
50
+ Log.d("ReactNative", "ReactConfig: Could not access BuildConfig field " + f.getName());
51
+ }
52
+ }
53
+ }
54
+ catch (ClassNotFoundException e) {
55
+ Log.d("ReactNative", "ReactConfig: Could not find BuildConfig class");
56
+ }
57
+
58
+ ret.put("config", realConstants);
59
+
60
+ return MapConverter.convertMapToWritableMap(ret);
61
+ }
62
+ }
@@ -1,27 +1,47 @@
1
1
  package com.lugg.RNCConfig;
2
2
 
3
- import com.facebook.react.ReactPackage;
4
- import com.facebook.react.bridge.JavaScriptModule;
3
+ import androidx.annotation.NonNull;
4
+ import com.facebook.react.BaseReactPackage;
5
5
  import com.facebook.react.bridge.NativeModule;
6
6
  import com.facebook.react.bridge.ReactApplicationContext;
7
- import com.facebook.react.uimanager.ViewManager;
8
- import java.util.Arrays;
9
- import java.util.Collections;
10
- import java.util.List;
7
+ import com.facebook.react.module.model.ReactModuleInfo;
8
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
9
+ import java.util.HashMap;
10
+ import java.util.Map;
11
11
 
12
- public class RNCConfigPackage implements ReactPackage {
12
+ public class RNCConfigPackage extends BaseReactPackage {
13
13
 
14
- @Override
15
- public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16
- return Arrays.<NativeModule>asList(new RNCConfigModule(reactContext));
14
+ @Override
15
+ public NativeModule getModule(String name, @NonNull ReactApplicationContext reactContext) {
16
+ if (name.equals(RNCConfigModuleImpl.NAME)) {
17
+ return new RNCConfigModule(reactContext);
18
+ } else {
19
+ return null;
17
20
  }
21
+ }
18
22
 
19
- public List<Class<? extends JavaScriptModule>> createJSModules() {
20
- return Collections.emptyList();
21
- }
22
-
23
- @Override
24
- public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
25
- return Collections.emptyList();
26
- }
23
+ @NonNull
24
+ @Override
25
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
26
+ return new ReactModuleInfoProvider() {
27
+ @NonNull
28
+ @Override
29
+ public Map<String, ReactModuleInfo> getReactModuleInfos() {
30
+ final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
31
+ boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
32
+ moduleInfos.put(
33
+ RNCConfigModule.NAME,
34
+ new ReactModuleInfo(
35
+ RNCConfigModule.NAME,
36
+ RNCConfigModule.NAME,
37
+ false, // canOverrideExistingModule
38
+ false, // needsEagerInit
39
+ false, // hasConstants
40
+ false, // isCxxModule
41
+ isTurboModule // isTurboModule
42
+ ));
43
+ return moduleInfos;
44
+ };
45
+ };
46
+ }
27
47
  }
@@ -0,0 +1,26 @@
1
+ package com.lugg.RNCConfig;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import com.facebook.react.bridge.ReactApplicationContext;
5
+ import com.facebook.react.bridge.WritableMap;
6
+
7
+ public class RNCConfigModule extends NativeConfigModuleSpec {
8
+ private final RNCConfigModuleImpl implementation;
9
+
10
+ public RNCConfigModule(ReactApplicationContext context) {
11
+ super(context);
12
+ implementation = new RNCConfigModuleImpl(context);
13
+ }
14
+
15
+ @Override
16
+ @NonNull
17
+ public String getName() {
18
+ return RNCConfigModuleImpl.NAME;
19
+ }
20
+
21
+
22
+ @Override
23
+ public WritableMap getConfig() {
24
+ return this.implementation.getConfig();
25
+ }
26
+ }
@@ -0,0 +1,27 @@
1
+ package com.lugg.RNCConfig;
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext;
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
5
+ import com.facebook.react.bridge.ReactMethod;
6
+ import com.facebook.react.bridge.WritableMap;
7
+
8
+ public class RNCConfigModule extends ReactContextBaseJavaModule {
9
+ public static final String NAME = "RNCConfigModule";
10
+
11
+ private RNCConfigModuleImpl implementation;
12
+
13
+ public RNCConfigModule(ReactApplicationContext reactContext) {
14
+ super(reactContext);
15
+ this.implementation = new RNCConfigModuleImpl(reactContext);
16
+ }
17
+
18
+ @Override
19
+ public String getName() {
20
+ return RNCConfigModuleImpl.NAME;
21
+ }
22
+
23
+ @ReactMethod(isBlockingSynchronousMethod = true)
24
+ public WritableMap getConfig() {
25
+ return this.implementation.getConfig();
26
+ }
27
+ }
@@ -0,0 +1,11 @@
1
+ // @flow
2
+ import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
3
+ import { TurboModuleRegistry } from "react-native";
4
+
5
+ export interface Spec extends TurboModule {
6
+ +getConfig: () => {|
7
+ config: Object,
8
+ |};
9
+ }
10
+
11
+ export default (TurboModuleRegistry.get<Spec>("RNCConfigModule"): ?Spec);
package/index.js CHANGED
@@ -1,10 +1,5 @@
1
- 'use strict';
2
-
3
- // Bridge to:
4
- // Android: buildConfigField vars set in build.gradle, and exported via ReactConfig
5
- // iOS: config vars set in xcconfig and exposed via RNCConfig.m
6
- import { NativeModules } from 'react-native';
7
-
8
- export const Config = NativeModules.RNCConfigModule || {}
1
+ "use strict";
9
2
 
3
+ export const Config =
4
+ require("./codegen/NativeConfigModule").default.getConfig().config;
10
5
  export default Config;
@@ -1,3 +1,9 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import "RNCConfigSpec.h"
3
+
4
+ @interface RNCConfigModule : NSObject <NativeConfigModuleSpec>
5
+ #else
6
+
1
7
  #if __has_include(<React/RCTBridgeModule.h>)
2
8
  #import <React/RCTBridgeModule.h>
3
9
  #elif __has_include("React/RCTBridgeModule.h")
@@ -7,6 +13,7 @@
7
13
  #endif
8
14
 
9
15
  @interface RNCConfigModule : NSObject <RCTBridgeModule>
16
+ #endif // RCT_NEW_ARCH_ENABLED
10
17
 
11
18
  + (NSDictionary *)env;
12
19
  + (NSString *)envFor: (NSString *)key;
@@ -0,0 +1,38 @@
1
+ #import "RNCConfig.h"
2
+ #import "RNCConfigModule.h"
3
+
4
+ @implementation RNCConfigModule
5
+
6
+ RCT_EXPORT_MODULE()
7
+ RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(getConfig)
8
+
9
+ + (BOOL)requiresMainQueueSetup
10
+ {
11
+ return YES;
12
+ }
13
+
14
+ + (NSDictionary *)env {
15
+ return RNCConfig.env;
16
+ }
17
+
18
+ + (NSString *)envFor: (NSString *)key {
19
+ return [RNCConfig envFor:key];
20
+ }
21
+
22
+ - (NSDictionary *)constantsToExport {
23
+ return @{ @"config": RNCConfig.env };
24
+ }
25
+
26
+ - (NSDictionary *)getConfig {
27
+ return self.constantsToExport;
28
+ }
29
+
30
+ #ifdef RCT_NEW_ARCH_ENABLED
31
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
32
+ (const facebook::react::ObjCTurboModule::InitParams &)params
33
+ {
34
+ return std::make_shared<facebook::react::NativeConfigModuleSpecJSI>(params);
35
+ }
36
+ #endif
37
+
38
+ @end
@@ -7,7 +7,7 @@
7
7
  objects = {
8
8
 
9
9
  /* Begin PBXBuildFile section */
10
- 07BF4DBD2476FBED00E59829 /* RNCConfigModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 07BF4DBC2476FBED00E59829 /* RNCConfigModule.m */; };
10
+ 07BF4DBD2476FBED00E59829 /* RNCConfigModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07BF4DBC2476FBED00E59829 /* RNCConfigModule.mm */; };
11
11
  3DF7F6B6203AA0C200D0EAB7 /* RNCConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = EBE4E8461C7D2456000F8875 /* RNCConfig.m */; };
12
12
  3DF7F6B7203AA0D600D0EAB7 /* RNCConfig.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = EB2648E21C7BE17A00B8F155 /* RNCConfig.h */; };
13
13
  EB2648E31C7BE17A00B8F155 /* RNCConfig.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = EB2648E21C7BE17A00B8F155 /* RNCConfig.h */; };
@@ -58,7 +58,7 @@
58
58
 
59
59
  /* Begin PBXFileReference section */
60
60
  07BF4DBB2476FBED00E59829 /* RNCConfigModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCConfigModule.h; sourceTree = "<group>"; };
61
- 07BF4DBC2476FBED00E59829 /* RNCConfigModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCConfigModule.m; sourceTree = "<group>"; };
61
+ 07BF4DBC2476FBED00E59829 /* RNCConfigModule.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RNCConfigModule.mm; sourceTree = "<group>"; };
62
62
  3DF7F6AC203AA09B00D0EAB7 /* libRNCConfig-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libRNCConfig-tvOS.a"; path = "libReactNativeConfig-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
63
63
  50406729228CAD5A00E0438A /* ReadDotEnv.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = ReadDotEnv.rb; sourceTree = "<group>"; };
64
64
  50830C45228DD3D000CEA8FC /* BuildXCConfig.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = BuildXCConfig.rb; sourceTree = "<group>"; };
@@ -110,7 +110,7 @@
110
110
  EB2648E21C7BE17A00B8F155 /* RNCConfig.h */,
111
111
  EBE4E8461C7D2456000F8875 /* RNCConfig.m */,
112
112
  07BF4DBB2476FBED00E59829 /* RNCConfigModule.h */,
113
- 07BF4DBC2476FBED00E59829 /* RNCConfigModule.m */,
113
+ 07BF4DBC2476FBED00E59829 /* RNCConfigModule.mm */,
114
114
  EBE4E8291C7BF6DD000F8875 /* BuildDotenvConfig.rb */,
115
115
  50406729228CAD5A00E0438A /* ReadDotEnv.rb */,
116
116
  );
@@ -239,7 +239,7 @@
239
239
  isa = PBXSourcesBuildPhase;
240
240
  buildActionMask = 2147483647;
241
241
  files = (
242
- 07BF4DBD2476FBED00E59829 /* RNCConfigModule.m in Sources */,
242
+ 07BF4DBD2476FBED00E59829 /* RNCConfigModule.mm in Sources */,
243
243
  EBE4E8471C7D2456000F8875 /* RNCConfig.m in Sources */,
244
244
  );
245
245
  runOnlyForDeploymentPostprocessing = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-config",
3
- "version": "1.5.9",
3
+ "version": "1.6.0",
4
4
  "description": "Expose config variables to React Native apps",
5
5
  "keywords": [
6
6
  "env",
@@ -27,7 +27,7 @@
27
27
  "android/",
28
28
  "ios/",
29
29
  "windows/",
30
- "src/",
30
+ "codegen/",
31
31
  "index.js",
32
32
  "index.d.ts",
33
33
  "react-native-config.podspec",
@@ -36,18 +36,16 @@
36
36
  "types": "./index.d.ts",
37
37
  "license": "MIT",
38
38
  "devDependencies": {
39
+ "@react-native-community/cli": "^20.0.2",
39
40
  "@semantic-release/git": "^10.0.1",
40
- "semantic-release": "^19.0.5",
41
+ "@types/jest": "^29.5.12",
41
42
  "jest": "^29.7.0",
42
- "@types/jest": "^29.5.12"
43
- },
44
- "dependencies": {
45
- "@babel/core": "^7.25.2",
46
- "@babel/preset-env": "^7.25.0",
47
- "@babel/preset-react": "^7.24.7",
48
- "babel-jest": "^29.7.0"
43
+ "react-native": "^0.79.6",
44
+ "react-native-windows": "^0.79.4"
49
45
  },
50
46
  "peerDependencies": {
47
+ "react": "*",
48
+ "react-native": "*",
51
49
  "react-native-windows": ">=0.61"
52
50
  },
53
51
  "peerDependenciesMeta": {
@@ -56,17 +54,24 @@
56
54
  }
57
55
  },
58
56
  "codegenConfig": {
59
- "name": "RNCConfigModule",
57
+ "name": "RNCConfigSpec",
60
58
  "type": "modules",
61
- "jsSrcsDir": "./src",
59
+ "jsSrcsDir": "./codegen",
62
60
  "android": {
63
- "javaPackageName": "com.luggit.reactnativeconfig"
61
+ "javaPackageName": "com.lugg.RNCConfig"
64
62
  },
65
63
  "ios": {
66
- "prefix": "RNC"
64
+ "modules": {
65
+ "RNCConfig": {
66
+ "className": "RNCConfigModule",
67
+ "unstableRequiresMainQueueSetup": true
68
+ }
69
+ }
67
70
  },
68
71
  "windows": {
69
- "cppNamespace": "RNCConfig"
72
+ "namespace": "RNCConfigCodegen",
73
+ "outputDirectory": "./windows/codegen",
74
+ "separateDataTypes": true
70
75
  }
71
76
  }
72
77
  }
@@ -4,6 +4,8 @@ require 'json'
4
4
 
5
5
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
6
6
 
7
+ fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
8
+
7
9
  Pod::Spec.new do |s|
8
10
  s.name = 'react-native-config'
9
11
  s.version = package['version']
@@ -36,8 +38,13 @@ HOST_PATH="$SRCROOT/../.."
36
38
  s.default_subspec = 'App'
37
39
 
38
40
  s.subspec 'App' do |app|
39
- app.source_files = 'ios/**/*.{h,m}'
40
- app.dependency 'React-Core'
41
+ app.source_files = 'ios/**/*.{h,m,mm}'
42
+
43
+ if fabric_enabled
44
+ install_modules_dependencies(app)
45
+ else
46
+ app.dependency 'React-Core'
47
+ end
41
48
  end
42
49
 
43
50
  # Use this subspec for iOS extensions that cannot use React dependency
@@ -113,7 +113,7 @@
113
113
  <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(SolutionDir)\Generated Files</AdditionalIncludeDirectories>
114
114
  <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(SolutionDir)\Generated Files</AdditionalIncludeDirectories>
115
115
  </ClCompile>
116
- <PreBuildEvent>
116
+ <PreBuildEvent>
117
117
  <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">node $(ProjectDir)\..\code\generate-header.js $(SolutionDir) $(SolutionDir) </Command>
118
118
  </PreBuildEvent>
119
119
  <PreBuildEvent>
@@ -148,6 +148,8 @@
148
148
  </PreBuildEvent>
149
149
  </ItemDefinitionGroup>
150
150
  <ItemGroup>
151
+ <ClInclude Include="..\codegen\NativeConfigModuleDataTypes.g.h" />
152
+ <ClInclude Include="..\codegen\NativeConfigModuleSpec.g.h" />
151
153
  <ClInclude Include="..\code\pch.h" />
152
154
  <ClInclude Include="..\code\ReactPackageProvider.h">
153
155
  <DependentUpon>ReactPackageProvider.idl</DependentUpon>
@@ -195,4 +197,4 @@
195
197
  <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
196
198
  <Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
197
199
  </Target>
198
- </Project>
200
+ </Project>
@@ -19,6 +19,8 @@
19
19
  <ClInclude Include="..\code\pch.h" />
20
20
  <ClInclude Include="..\code\ReactPackageProvider.h" />
21
21
  <ClInclude Include="..\code\RNCConfig.h" />
22
+ <ClInclude Include="..\codegen\NativeConfigModuleDataTypes.g.h" />
23
+ <ClInclude Include="..\codegen\NativeConfigModuleSpec.g.h" />
22
24
  </ItemGroup>
23
25
  <ItemGroup>
24
26
  <None Include="..\code\RNCConfig.def" />
@@ -1,41 +1,19 @@
1
- #include "pch.h"
1
+ #include "pch.h"
2
2
  #include "RNCConfig.h"
3
- #if __has_include("RNCConfigValues.h")
4
- #include "RNCConfigValues.h"
5
- #endif
6
3
  #include <JSValue.h>
7
- using namespace Microsoft::ReactNative;
8
4
 
9
- namespace RNCConfig
5
+ using namespace winrt::Microsoft::ReactNative;
6
+
7
+ namespace winrt::RNCConfig
10
8
  {
11
- JSValueObject RNCConfigModule::getAll() noexcept
9
+ RNCConfigCodegen::ConfigModuleSpec_getConfig_returnType RNCConfigModule::getConfig() noexcept
12
10
  {
13
11
  JSValueObject obj{};
14
12
  #if __has_include("RNCConfigValuesObject.inc.g.h")
15
13
  #include "RNCConfigValuesObject.inc.g.h"
16
14
  #endif
17
- return obj;
18
- }
19
15
 
20
- std::string RNCConfigModule::get(std::string const& key) noexcept
21
- {
22
- #if __has_include("RNCConfigValuesGet.inc.g.h")
23
- #include "RNCConfigValuesGet.inc.g.h"
24
- #endif
25
- return std::string{};
16
+ RNCConfigCodegen::ConfigModuleSpec_getConfig_returnType ret = { std::move(obj)};
17
+ return ret;
26
18
  }
27
-
28
- void RNCConfigModule::ProvideConstants(ReactConstantProvider& provider) noexcept
29
- {
30
- #if __has_include("RNCConfigValuesConstants.inc.g.h")
31
- #include "RNCConfigValuesConstants.inc.g.h"
32
- #endif
33
- }
34
-
35
- std::string RNCConfigModule::compositionInfo() noexcept
36
- {
37
- // No-op informational string; placeholder to indicate Composition can be used in this module
38
- // In a real implementation, you'd create a Compositor and maybe return feature info.
39
- return std::string{"CompositionReady"};
40
- }
41
19
  }
@@ -2,35 +2,31 @@
2
2
 
3
3
  #include "pch.h"
4
4
 
5
- #include <functional>
5
+ #if __has_include("../codegen/NativeConfigModuleDataTypes.g.h")
6
+ #include "../codegen/NativeConfigModuleDataTypes.g.h"
7
+ #endif
8
+ #include "../codegen/NativeConfigModuleSpec.g.h"
6
9
 
7
10
  #include "NativeModules.h"
11
+
12
+ #if __has_include("RNCConfigValues.h")
8
13
  #include "RNCConfigValues.h"
9
- namespace RNCConfig
14
+ #endif
15
+
16
+ namespace winrt::RNCConfig
10
17
  {
11
18
  REACT_MODULE(RNCConfigModule);
12
19
  struct RNCConfigModule
13
20
  {
21
+ using ModuleSpec = RNCConfigCodegen::ConfigModuleSpec;
22
+
14
23
  #if __has_include("RNCConfigValuesModule.inc.g.h")
15
24
  #include "RNCConfigValuesModule.inc.g.h"
16
25
  #else
17
26
  // Generated constants will be included at build-time
18
27
  #endif
19
28
 
20
- // TurboModule-friendly sync APIs
21
- REACT_SYNC_METHOD(getAll);
22
- Microsoft::ReactNative::JSValueObject getAll() noexcept;
23
-
24
- REACT_SYNC_METHOD(get);
25
- std::string get(std::string const& key) noexcept;
26
-
27
- // Keep constants available via the classic constants provider too
28
- REACT_CONSTANT_PROVIDER(ProvideConstants);
29
- void ProvideConstants(Microsoft::ReactNative::ReactConstantProvider& provider) noexcept;
30
-
31
- // Example Windows.UI.Composition usage exposed via a sync method
32
- REACT_SYNC_METHOD(compositionInfo);
33
- std::string compositionInfo() noexcept;
34
- };
29
+ REACT_SYNC_METHOD(getConfig);
30
+ RNCConfigCodegen::ConfigModuleSpec_getConfig_returnType getConfig() noexcept;
31
+ };
35
32
  }
36
-
@@ -36,10 +36,6 @@ function generateFiles(vars) {
36
36
  let rnCode = '';
37
37
  // Snippets for building a JS object with all constants
38
38
  let objectBuilder = '';
39
- // Snippet for a key-based getter switch/if chain
40
- let keyGetter = '';
41
- // Snippet for ReactConstantProvider
42
- let constantsProvider = '';
43
39
  nativeCode += '#include<string>\n'
44
40
  nativeCode += 'namespace ReactNativeConfig {\n'
45
41
  for (let {key, value} of vars) {
@@ -48,15 +44,11 @@ function generateFiles(vars) {
48
44
  rnCode += `REACT_CONSTANT(${key});\n`
49
45
  rnCode += `static inline const std::string ${key} = ${escaped};\n`;
50
46
  objectBuilder += ` obj["${key}"] = ReactNativeConfig::${key};\n`;
51
- keyGetter += ` if (key == "${key}") return ReactNativeConfig::${key};\n`;
52
- constantsProvider += ` provider.Add("${key}", ReactNativeConfig::${key});\n`;
53
47
  }
54
48
  nativeCode +='}\n'
55
49
  updateFile(nativeCode, path.join(outDir, 'RNCConfigValues.h'))
56
50
  updateFile(rnCode, path.join(outDir, 'RNCConfigValuesModule.inc.g.h'))
57
51
  updateFile(objectBuilder, path.join(outDir, 'RNCConfigValuesObject.inc.g.h'))
58
- updateFile(keyGetter, path.join(outDir, 'RNCConfigValuesGet.inc.g.h'))
59
- updateFile(constantsProvider, path.join(outDir, 'RNCConfigValuesConstants.inc.g.h'))
60
52
  }
61
53
 
62
54
  // Escape the string so it will work with C++
@@ -0,0 +1,2 @@
1
+ DisableFormat: true
2
+ SortIncludes: false
@@ -0,0 +1,24 @@
1
+
2
+ /*
3
+ * This file is auto-generated from a NativeModule spec file in js.
4
+ *
5
+ * This is a C++ Spec class that should be used with MakeTurboModuleProvider to register native modules
6
+ * in a way that also verifies at compile time that the native module matches the interface required
7
+ * by the TurboModule JS spec.
8
+ */
9
+ #pragma once
10
+ // clang-format off
11
+
12
+ #include <string>
13
+ #include <optional>
14
+ #include <functional>
15
+ #include <vector>
16
+ #include <JSValue.h>
17
+
18
+ namespace RNCConfigCodegen {
19
+
20
+ struct ConfigModuleSpec_getConfig_returnType {
21
+ winrt::Microsoft::ReactNative::JSValue config;
22
+ };
23
+
24
+ } // namespace RNCConfigCodegen
@@ -0,0 +1,42 @@
1
+
2
+ /*
3
+ * This file is auto-generated from a NativeModule spec file in js.
4
+ *
5
+ * This is a C++ Spec class that should be used with MakeTurboModuleProvider to register native modules
6
+ * in a way that also verifies at compile time that the native module matches the interface required
7
+ * by the TurboModule JS spec.
8
+ */
9
+ #pragma once
10
+ // clang-format off
11
+
12
+ // #include "NativeConfigModuleDataTypes.g.h" before this file to use the generated type definition
13
+ #include <NativeModules.h>
14
+ #include <tuple>
15
+
16
+ namespace RNCConfigCodegen {
17
+
18
+ inline winrt::Microsoft::ReactNative::FieldMap GetStructInfo(ConfigModuleSpec_getConfig_returnType*) noexcept {
19
+ winrt::Microsoft::ReactNative::FieldMap fieldMap {
20
+ {L"config", &ConfigModuleSpec_getConfig_returnType::config},
21
+ };
22
+ return fieldMap;
23
+ }
24
+
25
+ struct ConfigModuleSpec : winrt::Microsoft::ReactNative::TurboModuleSpec {
26
+ static constexpr auto methods = std::tuple{
27
+ SyncMethod<ConfigModuleSpec_getConfig_returnType() noexcept>{0, L"getConfig"},
28
+ };
29
+
30
+ template <class TModule>
31
+ static constexpr void ValidateModule() noexcept {
32
+ constexpr auto methodCheckResults = CheckMethods<TModule, ConfigModuleSpec>();
33
+
34
+ REACT_SHOW_METHOD_SPEC_ERRORS(
35
+ 0,
36
+ "getConfig",
37
+ " REACT_SYNC_METHOD(getConfig) ConfigModuleSpec_getConfig_returnType getConfig() noexcept { /* implementation */ }\n"
38
+ " REACT_SYNC_METHOD(getConfig) static ConfigModuleSpec_getConfig_returnType getConfig() noexcept { /* implementation */ }\n");
39
+ }
40
+ };
41
+
42
+ } // namespace RNCConfigCodegen
@@ -1,51 +0,0 @@
1
- package com.lugg.RNCConfig;
2
-
3
- import android.content.Context;
4
- import android.content.res.Resources;
5
- import android.util.Log;
6
- import com.facebook.react.bridge.ReactApplicationContext;
7
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
- import java.lang.ClassNotFoundException;
9
- import java.lang.IllegalAccessException;
10
- import java.lang.reflect.Field;
11
- import java.util.Map;
12
- import java.util.HashMap;
13
-
14
- public class RNCConfigModule extends ReactContextBaseJavaModule {
15
-
16
- public RNCConfigModule(ReactApplicationContext reactContext) {
17
- super(reactContext);
18
- }
19
-
20
- @Override
21
- public String getName() {
22
- return "RNCConfigModule";
23
- }
24
-
25
- @Override
26
- public Map<String, Object> getConstants() {
27
- final Map<String, Object> constants = new HashMap<>();
28
- try {
29
- Context context = getReactApplicationContext();
30
- int resId = context.getResources().getIdentifier("build_config_package", "string", context.getPackageName());
31
- String className;
32
- try {
33
- className = context.getString(resId);
34
- } catch (Resources.NotFoundException e) {
35
- className = getReactApplicationContext().getApplicationContext().getPackageName();
36
- }
37
- Class clazz = Class.forName(className + ".BuildConfig");
38
- Field[] fields = clazz.getDeclaredFields();
39
- for (Field f : fields) {
40
- try {
41
- constants.put(f.getName(), f.get(null));
42
- } catch (IllegalAccessException e) {
43
- Log.d("ReactNative", "ReactConfig: Could not access BuildConfig field " + f.getName());
44
- }
45
- }
46
- } catch (ClassNotFoundException e) {
47
- Log.d("ReactNative", "ReactConfig: Could not find BuildConfig class");
48
- }
49
- return constants;
50
- }
51
- }
@@ -1,25 +0,0 @@
1
- #import "RNCConfig.h"
2
- #import "RNCConfigModule.h"
3
-
4
- @implementation RNCConfigModule
5
-
6
- RCT_EXPORT_MODULE()
7
-
8
- + (BOOL)requiresMainQueueSetup
9
- {
10
- return YES;
11
- }
12
-
13
- + (NSDictionary *)env {
14
- return RNCConfig.env;
15
- }
16
-
17
- + (NSString *)envFor: (NSString *)key {
18
- return [RNCConfig envFor:key];
19
- }
20
-
21
- - (NSDictionary *)constantsToExport {
22
- return RNCConfig.env;
23
- }
24
-
25
- @end
@@ -1,12 +0,0 @@
1
- import type { TurboModule } from 'react-native';
2
- import { TurboModuleRegistry } from 'react-native';
3
-
4
- export interface Spec extends TurboModule {
5
- // Synchronous getters (supported on Windows TurboModules)
6
- getAll(): { [key: string]: string };
7
- get(key: string): string;
8
- // Optional Composition info hook
9
- compositionInfo?(): string;
10
- }
11
-
12
- export default TurboModuleRegistry.getEnforcing<Spec>('RNCConfigModule');