├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── build.gradle ├── dotenv.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── xreactnative │ └── envconfig │ ├── XRNEnvConfigModule.java │ └── XRNEnvConfigPackage.java ├── index.d.ts ├── index.js ├── ios ├── BuildDotenvConfig.rb ├── BuildXCConfig.rb ├── ReadDotEnv.rb ├── XRNEnvConfig.h ├── XRNEnvConfig.m ├── XRNEnvConfig.xcodeproj │ └── project.pbxproj └── XRNEnvConfig.xcworkspace │ └── contents.xcworkspacedata ├── package-lock.json ├── package.json ├── readme-pics ├── 1.ios_new_file.png ├── 2.ios_file_type.png └── 3.ios_apply_config.png └── x-react-native-env-config.podspec /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # node.js 6 | # 7 | node_modules/ 8 | npm-debug.log 9 | yarn-error.log 10 | 11 | # Xcode 12 | # 13 | build/ 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | *.xccheckout 24 | *.moved-aside 25 | DerivedData 26 | *.hmap 27 | *.ipa 28 | *.xcuserstate 29 | project.xcworkspace 30 | 31 | # Android/IntelliJ 32 | # 33 | build/ 34 | .idea 35 | .gradle 36 | local.properties 37 | *.iml 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### Upcoming 4 | 5 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.7...master) 6 | 7 | ### 0.11.7 8 | 9 | - Fix envConfigFiles in build.gradle not working (#275) 10 | 11 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.6...v0.11.7) 12 | 13 | ### 0.11.6 14 | 15 | - Updated gradle to v4.4 and gradle-plugin to v3.1.4 (#307) 16 | 17 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.5...v0.11.6) 18 | 19 | ### 0.11.5 20 | 21 | - Fix issue with CRLF (#201) 22 | 23 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.4...v0.11.5) 24 | 25 | ### 0.11.4 26 | 27 | - Another typescript fix, hopefully (ac3510b) 28 | 29 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.3...v0.11.4) 30 | 31 | ### 0.11.3 32 | 33 | - Fix typescript (#204) 34 | 35 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.2...v0.11.3) 36 | 37 | ### 0.11.2 38 | 39 | - Fix env selection in Android (#195) 40 | - Escape env values in Android (195a209) 41 | 42 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.1...v0.11.2) 43 | 44 | ### 0.11.1 45 | 46 | - Fix environment selection in Android (82ee9ad) 47 | 48 | [Diff](https://github.com/luggit/react-native-config/compare/v0.11.0...v0.11.1) 49 | 50 | ### 0.11.0 51 | 52 | - Fix env file selection in iOS (#185) 53 | - Support envfile selection as a system property (#191) 54 | - Typescript support (#186) 55 | 56 | [Diff](https://github.com/luggit/react-native-config/compare/v0.10.0...v0.11.0) 57 | 58 | ### 0.10.0 59 | 60 | - Android setup improvements – allow hooks into variants and fix issues with BuddyBuild (#180) 61 | 62 | [Diff](https://github.com/luggit/react-native-config/compare/v0.9.1...v0.10.0) 63 | 64 | ### 0.9.1 65 | 66 | - Fix unicode support in iOS (#179) 67 | 68 | [Diff](https://github.com/luggit/react-native-config/compare/v0.9.0...v0.9.1) 69 | 70 | ### 0.9.0 71 | 72 | - Fix compatibility with RN 0.49+ (#172) 73 | 74 | [Diff](https://github.com/luggit/react-native-config/compare/v0.8.1...v0.9.0) 75 | 76 | ### 0.8.1 77 | 78 | - Allow to specify env files location as absolute path 79 | 80 | [Diff](https://github.com/luggit/react-native-config/compare/e82ade149b3f940800cb1a1834cd699db3b10658...0b1b91d07858f6f4df1555fa61135725af7ed6a8) 81 | 82 | ### 0.8.0 83 | 84 | - Fixed breaking change for RN 0.48 (#164) 85 | 86 | [Diff](https://github.com/luggit/react-native-config/compare/52733cd5cf3209f5907d26173d75a3c9322f714c...e82ade149b3f940800cb1a1834cd699db3b10658) 87 | 88 | ### 0.7.2 89 | 90 | - Remove json dependecy in ruby 91 | 92 | [Diff](https://github.com/luggit/react-native-config/compare/bf3a97fa7e638795d86b76181a691ffb008f3d71...52733cd5cf3209f5907d26173d75a3c9322f714c) 93 | 94 | ### 0.7.1 95 | 96 | - Fixed iOS 8.0 support issue (#163) 97 | 98 | [Diff](https://github.com/luggit/react-native-config/compare/e354279a6ae24387426cb2b09275809c998ccd01...bf3a97fa7e638795d86b76181a691ffb008f3d71) 99 | 100 | ### 0.7.0 101 | 102 | - Add Pods Public Header path to `HEADER_SEARCH_PATHS` (#140) 103 | - Add support for `ENVFILE` to iOS (#145) 104 | - Update cmd command (#147) 105 | - Update regex examples to clarify treatment of spaces (#149) 106 | - Fixed Android dotenv.gradle quotes matching (#151) 107 | - Change import priority of React/RCTBridgeModule.h (#155) 108 | - Emphasize that variables are stored with your code (#157) 109 | 110 | [Diff](https://github.com/luggit/react-native-config/compare/e4c4a07e6673cceb7609ec6badac6b4dcdaadae6...e354279a6ae24387426cb2b09275809c998ccd01) 111 | 112 | ### 0.6.1 113 | 114 | - Fix backward compatibility for RN < 0.47 (#144) 115 | 116 | [Diff](https://github.com/luggit/react-native-config/compare/3306ea263717d0be579231e1d928df371482f428...e4c4a07e6673cceb7609ec6badac6b4dcdaadae6) 117 | 118 | ### 0.6.0 119 | 120 | - Remove override of 'createJSModules' (#137) 121 | 122 | [Diff](https://github.com/luggit/react-native-config/compare/bd20afa38edad5d31d1f852db51705398a44474b...3306ea263717d0be579231e1d928df371482f428) 123 | 124 | ### 0.5.0 125 | 126 | - Use task names and not task requests args to figure out which env file to use. (#115) 127 | - Docs for setting Env with the Windows cmd and Powershell (#123) 128 | - Allow exported variables in .env (#116) 129 | 130 | [Diff](https://github.com/luggit/react-native-config/compare/701ae6c13cc66d2b3ff03f027aae0694da0f2ccd...bd20afa38edad5d31d1f852db51705398a44474b) 131 | 132 | ### 0.4.2 133 | 134 | - Change dotenv pattern to support lowercase and numbers. (#108) 135 | 136 | [Diff](https://github.com/luggit/react-native-config/compare/5803c20c519a726709acb470b3c1ef880b14145b...701ae6c13cc66d2b3ff03f027aae0694da0f2ccd) 137 | 138 | ### 0.4.1 139 | 140 | - Package: including .podspec file during package installation (#106) 141 | 142 | [Diff](https://github.com/luggit/react-native-config/compare/cfdbaf23922705015f719f6512385724e2f7538b...5803c20c519a726709acb470b3c1ef880b14145b) 143 | 144 | ### 0.4.0 145 | 146 | - Added defaultEnvFile config (#99) 147 | - Support Dotenv with quotes and nested quotes (#98) 148 | - Correct error message (#91) 149 | - Support For Multi Target Applications (#66) 150 | - Add input file to run script to fix build problems on server (#73) 151 | - Add podspec 152 | 153 | [Diff](https://github.com/luggit/react-native-config/compare/5e4abf1da66eb2818276b5b4a9f15f2db652c154...cfdbaf23922705015f719f6512385724e2f7538b) 154 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Lugg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Config variables for React Native apps 2 | 3 | Module to expose config variables to your javascript code in React Native, supporting both iOS and Android. 4 | 5 | Bring some [12 factor](http://12factor.net/config) love to your mobile apps! 6 | 7 | ## Basic Usage 8 | 9 | Create a new file `.env` in the root of your React Native app: 10 | 11 | ``` 12 | API_URL=https://myapi.com 13 | GOOGLE_MAPS_API_KEY=abcdefgh 14 | ``` 15 | 16 | Then access variables defined there from your app: 17 | 18 | ```js 19 | import Config from "react-native-config"; 20 | 21 | Config.API_URL; // 'https://myapi.com' 22 | Config.GOOGLE_MAPS_API_KEY; // 'abcdefgh' 23 | ``` 24 | 25 | Keep in mind this module doesn't obfuscate or encrypt secrets for packaging, so **do not store sensitive keys in `.env`**. It's [basically impossible to prevent users from reverse engineering mobile app secrets](https://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/), so design your app (and APIs) with that in mind. 26 | 27 | ## Setup 28 | 29 | Install the package: 30 | 31 | ``` 32 | $ yarn add react-native-config 33 | ``` 34 | 35 | Link the library: 36 | 37 | ``` 38 | $ react-native link react-native-config 39 | ``` 40 | 41 | if cocoapods are used in the project then pod has to be installed as well: 42 | 43 | ``` 44 | (cd ios; pod install) 45 | ``` 46 | 47 | ### Extra step for Android 48 | 49 | You'll also need to manually apply a plugin to your app, from `android/app/build.gradle`: 50 | 51 | ``` 52 | // 2nd line, add a new apply: 53 | apply from: file("../../node_modules/@x-react-native/env-config/android/dotenv.gradle") 54 | ``` 55 | 56 | #### Advanced Android Setup 57 | 58 | In `android/app/build.gradle`, if you use `applicationIdSuffix` or `applicationId` that is different from the package name indicated in `AndroidManifest.xml` in `` tag, for example, to support different build variants: 59 | Add this in `android/app/build.gradle` 60 | 61 | ``` 62 | defaultConfig { 63 | ... 64 | resValue "string", "build_config_package", "YOUR_PACKAGE_NAME_IN_ANDROIDMANIFEST.XML" 65 | } 66 | ``` 67 | 68 | ## Native Usage 69 | 70 | ### Android 71 | 72 | Config variables set in `.env` are available to your Java classes via `BuildConfig`: 73 | 74 | ```java 75 | public HttpURLConnection getApiClient() { 76 | URL url = new URL(BuildConfig.API_URL); 77 | // ... 78 | } 79 | ``` 80 | 81 | You can also read them from your Gradle configuration: 82 | 83 | ```groovy 84 | defaultConfig { 85 | applicationId project.env.get("APP_ID") 86 | } 87 | ``` 88 | 89 | And use them to configure libraries in `AndroidManifest.xml` and others: 90 | 91 | ```xml 92 | 95 | ``` 96 | 97 | All variables are strings, so you may need to cast them. For instance, in Gradle: 98 | 99 | ``` 100 | versionCode project.env.get("VERSION_CODE").toInteger() 101 | ``` 102 | 103 | Once again, remember variables stored in `.env` are published with your code, so **DO NOT put anything sensitive there like your app `signingConfigs`.** 104 | 105 | ### iOS 106 | 107 | Read variables declared in `.env` from your Obj-C classes like: 108 | 109 | ```objective-c 110 | // import header 111 | #import "ReactNativeConfig.h" 112 | 113 | // then read individual keys like: 114 | NSString *apiUrl = [ReactNativeConfig envFor:@"API_URL"]; 115 | 116 | // or just fetch the whole config 117 | NSDictionary *config = [ReactNativeConfig env]; 118 | ``` 119 | 120 | #### Availability in Build settings and Info.plist 121 | 122 | With one extra step environment values can be exposed to "Info.plist" and Build settings in the native project. 123 | 124 | 1. click on the file tree and create new file of type XCConfig 125 | ![img](./readme-pics/1.ios_new_file.png) 126 | ![img](./readme-pics/2.ios_file_type.png) 127 | 2. save it under `ios` folder as "Config.xcconfig" with the following content: 128 | 129 | ``` 130 | #include? "tmp.xcconfig" 131 | ``` 132 | 133 | 3. add the following to your ".gitignore": 134 | 135 | ``` 136 | # react-native-config codegen 137 | ios/tmp.xcconfig 138 | 139 | ``` 140 | 141 | 4. go to project settings 142 | 5. apply config to your configurations 143 | ![img](./readme-pics/3.ios_apply_config.png) 144 | 6. create new build phase for the scheme which will generate "tmp.xcconfig" before each build exposing values to Build Settings and Info.plist (this snippet has to be placed after "echo ... > tmp/envfile" if [approach explained below](#ios-multi-scheme) is used) 145 | 146 | ``` 147 | "${SRCROOT}/../node_modules/react-native-config/ios/ReactNativeConfig/BuildXCConfig.rb" "${SRCROOT}/.." "${SRCROOT}/tmp.xcconfig" 148 | ``` 149 | 150 | ### Different environments 151 | 152 | Save config for different environments in different files: `.env.staging`, `.env.production`, etc. 153 | 154 | By default react-native-config will read from `.env`, but you can change it when building or releasing your app. 155 | 156 | The simplest approach is to tell it what file to read with an environment variable, like: 157 | 158 | ``` 159 | $ ENVFILE=.env.staging react-native run-ios # bash 160 | $ SET ENVFILE=.env.staging && react-native run-ios # windows 161 | $ env:ENVFILE=".env.staging"; react-native run-ios # powershell 162 | ``` 163 | 164 | This also works for `run-android`. Alternatively, there are platform-specific options below. 165 | 166 | #### Android 167 | 168 | The same environment variable can be used to assemble releases with a different config: 169 | 170 | ``` 171 | $ cd android && ENVFILE=.env.staging ./gradlew assembleRelease 172 | ``` 173 | 174 | Alternatively, you can define a map in `build.gradle` associating builds with env files. Do it before the `apply from` call, and use build cases in lowercase, like: 175 | 176 | ``` 177 | project.ext.envConfigFiles = [ 178 | debug: ".env.development", 179 | release: ".env.production", 180 | anothercustombuild: ".env", 181 | ] 182 | 183 | apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" 184 | ``` 185 | 186 | 187 | 188 | #### iOS 189 | 190 | The basic idea in iOS is to have one scheme per environment file, so you can easily alternate between them. 191 | 192 | Start by creating a new scheme: 193 | 194 | - In the Xcode menu, go to Product > Scheme > Edit Scheme 195 | - Click Duplicate Scheme on the bottom 196 | - Give it a proper name on the top left. For instance: "Myapp (staging)" 197 | 198 | Then edit the newly created scheme to make it use a different env file. From the same "manage scheme" window: 199 | 200 | - Expand the "Build" settings on left 201 | - Click "Pre-actions", and under the plus sign select "New Run Script Action" 202 | - Where it says "Type a script or drag a script file", type: 203 | ``` 204 | echo ".env.staging" > /tmp/envfile # replace .env.staging for your file 205 | ``` 206 | 207 | This is still a bit experimental and dirty – let us know if you have a better idea on how to make iOS use different configurations opening a pull request or issue! 208 | 209 | ## Troubleshooting 210 | 211 | ### Problems with Proguard 212 | 213 | When Proguard is enabled (which it is by default for Android release builds), it can rename the `BuildConfig` Java class in the minification process and prevent React Native Config from referencing it. To avoid this, add an exception to `android/app/proguard-rules.pro`: 214 | 215 | -keep class com.mypackage.BuildConfig { *; } 216 | 217 | `mypackage` should match the `package` value in your `app/src/main/AndroidManifest.xml` file. 218 | 219 | ## Testing 220 | 221 | ### Jest 222 | 223 | For mocking the `Config.FOO_BAR` usage, create a mock at `__mocks__/react-native-config.js`: 224 | 225 | ``` 226 | // __mocks__/react-native-config.js 227 | export default { 228 | FOO_BAR: 'baz', 229 | }; 230 | ``` 231 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // android/build.gradle 2 | 3 | def safeExtGet(prop, fallback) { 4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 5 | } 6 | 7 | buildscript { 8 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 9 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 10 | // module dependency in an application project. 11 | if (project == rootProject) { 12 | repositories { 13 | google() 14 | jcenter() 15 | } 16 | dependencies { 17 | classpath 'com.android.tools.build:gradle:3.4.1' 18 | } 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | apply plugin: 'maven' 24 | 25 | // Matches values in recent template from React Native 0.59 / 0.60 26 | // https://github.com/facebook/react-native/blob/0.59-stable/template/android/build.gradle#L5-L9 27 | // https://github.com/facebook/react-native/blob/0.60-stable/template/android/build.gradle#L5-L9 28 | def DEFAULT_COMPILE_SDK_VERSION = 28 29 | def DEFAULT_BUILD_TOOLS_VERSION = "28.0.3" 30 | def DEFAULT_MIN_SDK_VERSION = 16 31 | def DEFAULT_TARGET_SDK_VERSION = 28 32 | 33 | android { 34 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION) 35 | buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION) 36 | defaultConfig { 37 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION) 38 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION) 39 | versionCode 1 40 | versionName "1.0" 41 | } 42 | lintOptions { 43 | abortOnError false 44 | } 45 | } 46 | 47 | repositories { 48 | mavenLocal() 49 | maven { 50 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 51 | url "$rootDir/../node_modules/react-native/android" 52 | } 53 | maven { 54 | // Android JSC is installed from npm 55 | url "$rootDir/../node_modules/jsc-android/dist" 56 | } 57 | google() 58 | jcenter() 59 | } 60 | 61 | dependencies { 62 | // ref: 63 | // https://github.com/facebook/react-native/blob/0.61-stable/template/android/app/build.gradle#L192 64 | //noinspection GradleDynamicVersion 65 | implementation 'com.facebook.react:react-native:+' // From node_modules 66 | } 67 | 68 | def configureReactNativePom(def pom) { 69 | def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text) 70 | 71 | pom.project { 72 | name packageJson.title 73 | artifactId packageJson.name 74 | version = packageJson.version 75 | group = "com.xreactnative.envconfig" 76 | description packageJson.description 77 | url packageJson.repository.baseUrl 78 | 79 | licenses { 80 | license { 81 | name packageJson.license 82 | url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename 83 | distribution 'repo' 84 | } 85 | } 86 | 87 | developers { 88 | developer { 89 | id packageJson.author.username 90 | name packageJson.author.name 91 | } 92 | } 93 | } 94 | } 95 | 96 | afterEvaluate { project -> 97 | // some Gradle build hooks ref: 98 | // https://www.oreilly.com/library/view/gradle-beyond-the/9781449373801/ch03.html 99 | task androidJavadoc(type: Javadoc) { 100 | source = android.sourceSets.main.java.srcDirs 101 | classpath += files(android.bootClasspath) 102 | classpath += files(project.getConfigurations().getByName('compile').asList()) 103 | include '**/*.java' 104 | } 105 | 106 | task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) { 107 | classifier = 'javadoc' 108 | from androidJavadoc.destinationDir 109 | } 110 | 111 | task androidSourcesJar(type: Jar) { 112 | classifier = 'sources' 113 | from android.sourceSets.main.java.srcDirs 114 | include '**/*.java' 115 | } 116 | 117 | android.libraryVariants.all { variant -> 118 | def name = variant.name.capitalize() 119 | task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) { 120 | from variant.javaCompile.destinationDir 121 | } 122 | } 123 | 124 | artifacts { 125 | archives androidSourcesJar 126 | archives androidJavadocJar 127 | } 128 | 129 | task installArchives(type: Upload) { 130 | configuration = configurations.archives 131 | repositories.mavenDeployer { 132 | // Deploy to react-native-event-bridge/maven, ready to publish to npm 133 | repository url: "file://${projectDir}/../android/maven" 134 | configureReactNativePom pom 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /android/dotenv.gradle: -------------------------------------------------------------------------------- 1 | import java.util.regex.Matcher 2 | import java.util.regex.Pattern 3 | 4 | def getCurrentFlavor() { 5 | Gradle gradle = getGradle() 6 | 7 | // match optional modules followed by the task 8 | // (?:.*:)* is a non-capturing group to skip any :foo:bar: if they exist 9 | // *[a-z]+([A-Za-z]+) will capture the flavor part of the task name onward (e.g., assembleRelease --> Release) 10 | def pattern = Pattern.compile("(?:.*:)*[a-z]+([A-Z][A-Za-z]+)") 11 | def flavor = "" 12 | 13 | gradle.getStartParameter().getTaskNames().any { name -> 14 | Matcher matcher = pattern.matcher(name) 15 | if (matcher.find()) { 16 | flavor = matcher.group(1).toLowerCase() 17 | return true 18 | } 19 | } 20 | 21 | return flavor 22 | } 23 | 24 | def loadDotEnv(flavor = getCurrentFlavor()) { 25 | def envFile = ".env" 26 | 27 | if (System.env['ENVFILE']) { 28 | envFile = System.env['ENVFILE'] 29 | } else if (System.getProperty('ENVFILE')) { 30 | envFile = System.getProperty('ENVFILE') 31 | } else if (project.hasProperty("envConfigFiles")) { 32 | // use startsWith because sometimes the task is "generateDebugSources", so we want to match "debug" 33 | project.ext.envConfigFiles.any { pair -> 34 | if (flavor.startsWith(pair.key)) { 35 | envFile = pair.value 36 | return true 37 | } 38 | } 39 | } else if (project.hasProperty("defaultEnvFile")) { 40 | envFile = project.defaultEnvFile 41 | } 42 | 43 | def env = [:] 44 | println("Reading env from: $envFile") 45 | 46 | File f = new File("$project.rootDir/../$envFile"); 47 | if (!f.exists()) { 48 | f = new File("$envFile"); 49 | } 50 | 51 | if (f.exists()) { 52 | f.eachLine { line -> 53 | def matcher = (line =~ /^\s*(?:export\s+|)([\w\d\.\-_]+)\s*=\s*['"]?(.*?)?['"]?\s*$/) 54 | if (matcher.getCount() == 1 && matcher[0].size() == 3) { 55 | env.put(matcher[0][1], matcher[0][2].replace('"', '\\"')) 56 | } 57 | } 58 | } else { 59 | println("**************************") 60 | println("*** Missing .env file ****") 61 | println("**************************") 62 | } 63 | 64 | project.ext.set("env", env) 65 | } 66 | 67 | loadDotEnv() 68 | 69 | android { 70 | defaultConfig { 71 | project.env.each { k, v -> 72 | def escaped = v.replaceAll("%","\\\\u0025") 73 | buildConfigField "String", k, "\"$v\"" 74 | resValue "string", k, "\"$escaped\"" 75 | } 76 | } 77 | } 78 | 79 | tasks.whenTaskAdded { task -> 80 | if (project.hasProperty("envConfigFiles")) { 81 | project.envConfigFiles.each { envConfigName, envConfigFile -> 82 | if (task.name.toLowerCase() == "generate"+envConfigName+"buildconfig") { 83 | task.doFirst() { 84 | android.applicationVariants.all { variant -> 85 | def variantConfigString = variant.getVariantData().getVariantConfiguration().getFullName() 86 | if (envConfigName.contains(variantConfigString.toLowerCase())) { 87 | loadDotEnv(envConfigName) 88 | project.env.each { k, v -> 89 | def escaped = v.replaceAll("%","\\\\u0025") 90 | variant.buildConfigField "String", k, "\"$v\"" 91 | variant.resValue "string", k, "\"$escaped\"" 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/java/com/xreactnative/envconfig/XRNEnvConfigModule.java: -------------------------------------------------------------------------------- 1 | package com.xreactnative.envconfig; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.util.Log; 6 | 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 9 | 10 | import java.lang.ClassNotFoundException; 11 | import java.lang.IllegalAccessException; 12 | import java.lang.reflect.Field; 13 | import java.util.Map; 14 | import java.util.HashMap; 15 | 16 | public class XRNEnvConfigModule extends ReactContextBaseJavaModule { 17 | 18 | private final ReactApplicationContext reactContext; 19 | 20 | public XRNEnvConfigModule(ReactApplicationContext reactContext) { 21 | super(reactContext); 22 | this.reactContext = reactContext; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "XRNEnvConfig"; 28 | } 29 | 30 | @Override 31 | public Map getConstants() { 32 | final Map constants = new HashMap<>(); 33 | 34 | try { 35 | Context context = getReactApplicationContext(); 36 | int resId = context.getResources().getIdentifier("build_config_package", "string", context.getPackageName()); 37 | String className; 38 | try { 39 | className = context.getString(resId); 40 | } catch (Resources.NotFoundException e) { 41 | className = getReactApplicationContext().getApplicationContext().getPackageName(); 42 | } 43 | Class clazz = Class.forName(className + ".BuildConfig"); 44 | Field[] fields = clazz.getDeclaredFields(); 45 | for(Field f: fields) { 46 | try { 47 | constants.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 | return constants; 59 | }} 60 | -------------------------------------------------------------------------------- /android/src/main/java/com/xreactnative/envconfig/XRNEnvConfigPackage.java: -------------------------------------------------------------------------------- 1 | package com.xreactnative.envconfig; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.bridge.NativeModule; 9 | import com.facebook.react.bridge.ReactApplicationContext; 10 | import com.facebook.react.uimanager.ViewManager; 11 | import com.facebook.react.bridge.JavaScriptModule; 12 | 13 | public class XRNEnvConfigPackage implements ReactPackage { 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Arrays.asList(new XRNEnvConfigModule(reactContext)); 17 | } 18 | 19 | @Override 20 | public List createViewManagers(ReactApplicationContext reactContext) { 21 | return Collections.emptyList(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | export interface NativeConfig { 2 | [name: string]: any 3 | } 4 | export const Config: NativeConfig 5 | export default Config 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native'; 2 | 3 | const { XRNEnvConfig } = NativeModules; 4 | 5 | export default XRNEnvConfig || {}; 6 | -------------------------------------------------------------------------------- /ios/BuildDotenvConfig.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative 'ReadDotEnv' 5 | 6 | envs_root = ARGV[0] 7 | m_output_path = ARGV[1] 8 | puts "reading env file from #{envs_root} and writing .m to #{m_output_path}" 9 | 10 | # Allow utf-8 charactor in config value 11 | # For example, APP_NAME=中文字符 12 | Encoding.default_external = Encoding::UTF_8 13 | Encoding.default_internal = Encoding::UTF_8 14 | 15 | dotenv, custom_env = read_dot_env(envs_root) 16 | puts "read dotenv #{dotenv}" 17 | 18 | # create obj file that sets DOT_ENV as a NSDictionary 19 | dotenv_objc = dotenv.map { |k, v| %(@"#{k}":@"#{v.chomp}") }.join(',') 20 | template = <[[:alnum:]_]+)=((?["'])?(?.*?[^\\])\k?|)$/ 26 | 27 | path = File.expand_path(File.join(envs_root, file.to_s)) 28 | if File.exist?(path) 29 | raw = File.read(path) 30 | elsif File.exist?(file) 31 | raw = File.read(file) 32 | else 33 | defaultEnvPath = File.expand_path(File.join(envs_root, "../#{defaultEnvFile}")) 34 | unless File.exist?(defaultEnvPath) 35 | # try as absolute path 36 | defaultEnvPath = defaultEnvFile 37 | end 38 | defaultRaw = File.read(defaultEnvPath) 39 | raw = defaultRaw + "\n" + raw if defaultRaw 40 | end 41 | 42 | raw.split("\n").inject({}) do |h, line| 43 | m = line.match(dotenv_pattern) 44 | next h if m.nil? 45 | 46 | key = m[:key] 47 | # Ensure string (in case of empty value) and escape any quotes present in the value. 48 | val = m[:val].to_s.gsub('"', '\"') 49 | h.merge(key => val) 50 | end 51 | rescue Errno::ENOENT 52 | puts('**************************') 53 | puts('*** Missing .env file ****') 54 | puts('**************************') 55 | return [{}, false] # set dotenv as an empty hash 56 | end 57 | [dotenv, custom_env] 58 | end 59 | -------------------------------------------------------------------------------- /ios/XRNEnvConfig.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface XRNEnvConfig : NSObject 4 | 5 | + (NSDictionary *)env; 6 | + (NSString *)envFor: (NSString *)key; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /ios/XRNEnvConfig.m: -------------------------------------------------------------------------------- 1 | #import "XRNEnvConfig.h" 2 | #import "GeneratedDotEnv.m" // written during build by BuildDotenvConfig.ruby 3 | 4 | @implementation XRNEnvConfig 5 | 6 | RCT_EXPORT_MODULE() 7 | 8 | + (BOOL)requiresMainQueueSetup 9 | { 10 | return YES; 11 | } 12 | 13 | + (NSDictionary *)env { 14 | return (NSDictionary *)DOT_ENV; 15 | } 16 | 17 | + (NSString *)envFor: (NSString *)key { 18 | NSString *value = (NSString *)[self.env objectForKey:key]; 19 | return value; 20 | } 21 | 22 | - (NSDictionary *)constantsToExport { 23 | return DOT_ENV 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /ios/XRNEnvConfig.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B3E7B58A1CC2AC0600A0062D /* XRNEnvConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* XRNEnvConfig.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = "include/$(PRODUCT_NAME)"; 18 | dstSubfolderSpec = 16; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 0; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 134814201AA4EA6300B7C361 /* libXRNEnvConfig.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libXRNEnvConfig.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | B3E7B5881CC2AC0600A0062D /* XRNEnvConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XRNEnvConfig.h; sourceTree = ""; }; 28 | B3E7B5891CC2AC0600A0062D /* XRNEnvConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XRNEnvConfig.m; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 134814211AA4EA7D00B7C361 /* Products */ = { 43 | isa = PBXGroup; 44 | children = ( 45 | 134814201AA4EA6300B7C361 /* libXRNEnvConfig.a */, 46 | ); 47 | name = Products; 48 | sourceTree = ""; 49 | }; 50 | 58B511D21A9E6C8500147676 = { 51 | isa = PBXGroup; 52 | children = ( 53 | B3E7B5881CC2AC0600A0062D /* XRNEnvConfig.h */, 54 | B3E7B5891CC2AC0600A0062D /* XRNEnvConfig.m */, 55 | 134814211AA4EA7D00B7C361 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | /* End PBXGroup section */ 60 | 61 | /* Begin PBXNativeTarget section */ 62 | 58B511DA1A9E6C8500147676 /* XRNEnvConfig */ = { 63 | isa = PBXNativeTarget; 64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "XRNEnvConfig" */; 65 | buildPhases = ( 66 | 58B511D71A9E6C8500147676 /* Sources */, 67 | 58B511D81A9E6C8500147676 /* Frameworks */, 68 | 58B511D91A9E6C8500147676 /* CopyFiles */, 69 | ); 70 | buildRules = ( 71 | ); 72 | dependencies = ( 73 | ); 74 | name = XRNEnvConfig; 75 | productName = RCTDataManager; 76 | productReference = 134814201AA4EA6300B7C361 /* libXRNEnvConfig.a */; 77 | productType = "com.apple.product-type.library.static"; 78 | }; 79 | /* End PBXNativeTarget section */ 80 | 81 | /* Begin PBXProject section */ 82 | 58B511D31A9E6C8500147676 /* Project object */ = { 83 | isa = PBXProject; 84 | attributes = { 85 | LastUpgradeCheck = 0920; 86 | ORGANIZATIONNAME = Facebook; 87 | TargetAttributes = { 88 | 58B511DA1A9E6C8500147676 = { 89 | CreatedOnToolsVersion = 6.1.1; 90 | }; 91 | }; 92 | }; 93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "XRNEnvConfig" */; 94 | compatibilityVersion = "Xcode 3.2"; 95 | developmentRegion = English; 96 | hasScannedForEncodings = 0; 97 | knownRegions = ( 98 | en, 99 | ); 100 | mainGroup = 58B511D21A9E6C8500147676; 101 | productRefGroup = 58B511D21A9E6C8500147676; 102 | projectDirPath = ""; 103 | projectRoot = ""; 104 | targets = ( 105 | 58B511DA1A9E6C8500147676 /* XRNEnvConfig */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXSourcesBuildPhase section */ 111 | 58B511D71A9E6C8500147676 /* Sources */ = { 112 | isa = PBXSourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | B3E7B58A1CC2AC0600A0062D /* XRNEnvConfig.m in Sources */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXSourcesBuildPhase section */ 120 | 121 | /* Begin XCBuildConfiguration section */ 122 | 58B511ED1A9E6C8500147676 /* Debug */ = { 123 | isa = XCBuildConfiguration; 124 | buildSettings = { 125 | ALWAYS_SEARCH_USER_PATHS = NO; 126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 127 | CLANG_CXX_LIBRARY = "libc++"; 128 | CLANG_ENABLE_MODULES = YES; 129 | CLANG_ENABLE_OBJC_ARC = YES; 130 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 131 | CLANG_WARN_BOOL_CONVERSION = YES; 132 | CLANG_WARN_COMMA = YES; 133 | CLANG_WARN_CONSTANT_CONVERSION = YES; 134 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 135 | CLANG_WARN_EMPTY_BODY = YES; 136 | CLANG_WARN_ENUM_CONVERSION = YES; 137 | CLANG_WARN_INFINITE_RECURSION = YES; 138 | CLANG_WARN_INT_CONVERSION = YES; 139 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 140 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 141 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 142 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 143 | CLANG_WARN_STRICT_PROTOTYPES = YES; 144 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 145 | CLANG_WARN_UNREACHABLE_CODE = YES; 146 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 147 | COPY_PHASE_STRIP = NO; 148 | ENABLE_STRICT_OBJC_MSGSEND = YES; 149 | ENABLE_TESTABILITY = YES; 150 | GCC_C_LANGUAGE_STANDARD = gnu99; 151 | GCC_DYNAMIC_NO_PIC = NO; 152 | GCC_NO_COMMON_BLOCKS = YES; 153 | GCC_OPTIMIZATION_LEVEL = 0; 154 | GCC_PREPROCESSOR_DEFINITIONS = ( 155 | "DEBUG=1", 156 | "$(inherited)", 157 | ); 158 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 159 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 160 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 161 | GCC_WARN_UNDECLARED_SELECTOR = YES; 162 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 163 | GCC_WARN_UNUSED_FUNCTION = YES; 164 | GCC_WARN_UNUSED_VARIABLE = YES; 165 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 166 | MTL_ENABLE_DEBUG_INFO = YES; 167 | ONLY_ACTIVE_ARCH = YES; 168 | SDKROOT = iphoneos; 169 | }; 170 | name = Debug; 171 | }; 172 | 58B511EE1A9E6C8500147676 /* Release */ = { 173 | isa = XCBuildConfiguration; 174 | buildSettings = { 175 | ALWAYS_SEARCH_USER_PATHS = NO; 176 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 177 | CLANG_CXX_LIBRARY = "libc++"; 178 | CLANG_ENABLE_MODULES = YES; 179 | CLANG_ENABLE_OBJC_ARC = YES; 180 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 181 | CLANG_WARN_BOOL_CONVERSION = YES; 182 | CLANG_WARN_COMMA = YES; 183 | CLANG_WARN_CONSTANT_CONVERSION = YES; 184 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 185 | CLANG_WARN_EMPTY_BODY = YES; 186 | CLANG_WARN_ENUM_CONVERSION = YES; 187 | CLANG_WARN_INFINITE_RECURSION = YES; 188 | CLANG_WARN_INT_CONVERSION = YES; 189 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 190 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 191 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 192 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 193 | CLANG_WARN_STRICT_PROTOTYPES = YES; 194 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 195 | CLANG_WARN_UNREACHABLE_CODE = YES; 196 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 197 | COPY_PHASE_STRIP = YES; 198 | ENABLE_NS_ASSERTIONS = NO; 199 | ENABLE_STRICT_OBJC_MSGSEND = YES; 200 | GCC_C_LANGUAGE_STANDARD = gnu99; 201 | GCC_NO_COMMON_BLOCKS = YES; 202 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 203 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 204 | GCC_WARN_UNDECLARED_SELECTOR = YES; 205 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 206 | GCC_WARN_UNUSED_FUNCTION = YES; 207 | GCC_WARN_UNUSED_VARIABLE = YES; 208 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 209 | MTL_ENABLE_DEBUG_INFO = NO; 210 | SDKROOT = iphoneos; 211 | VALIDATE_PRODUCT = YES; 212 | }; 213 | name = Release; 214 | }; 215 | 58B511F01A9E6C8500147676 /* Debug */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | HEADER_SEARCH_PATHS = ( 219 | "$(inherited)", 220 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 221 | "$(SRCROOT)/../../../React/**", 222 | "$(SRCROOT)/../../react-native/React/**", 223 | ); 224 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 225 | OTHER_LDFLAGS = "-ObjC"; 226 | PRODUCT_NAME = XRNEnvConfig; 227 | SKIP_INSTALL = YES; 228 | }; 229 | name = Debug; 230 | }; 231 | 58B511F11A9E6C8500147676 /* Release */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | HEADER_SEARCH_PATHS = ( 235 | "$(inherited)", 236 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 237 | "$(SRCROOT)/../../../React/**", 238 | "$(SRCROOT)/../../react-native/React/**", 239 | ); 240 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 241 | OTHER_LDFLAGS = "-ObjC"; 242 | PRODUCT_NAME = XRNEnvConfig; 243 | SKIP_INSTALL = YES; 244 | }; 245 | name = Release; 246 | }; 247 | /* End XCBuildConfiguration section */ 248 | 249 | /* Begin XCConfigurationList section */ 250 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "XRNEnvConfig" */ = { 251 | isa = XCConfigurationList; 252 | buildConfigurations = ( 253 | 58B511ED1A9E6C8500147676 /* Debug */, 254 | 58B511EE1A9E6C8500147676 /* Release */, 255 | ); 256 | defaultConfigurationIsVisible = 0; 257 | defaultConfigurationName = Release; 258 | }; 259 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "XRNEnvConfig" */ = { 260 | isa = XCConfigurationList; 261 | buildConfigurations = ( 262 | 58B511F01A9E6C8500147676 /* Debug */, 263 | 58B511F11A9E6C8500147676 /* Release */, 264 | ); 265 | defaultConfigurationIsVisible = 0; 266 | defaultConfigurationName = Release; 267 | }; 268 | /* End XCConfigurationList section */ 269 | }; 270 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 271 | } 272 | -------------------------------------------------------------------------------- /ios/XRNEnvConfig.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@x-react-native/env-config", 3 | "version": "0.0.2", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@x-react-native/env-config", 3 | "version": "0.0.1", 4 | "description": "Expose config variables to React Native apps", 5 | "keywords": [ 6 | "env", 7 | "config", 8 | "config-var", 9 | "react-native", 10 | "android", 11 | "ios", 12 | "12factor" 13 | ], 14 | "homepage": "https://github.com/x-react-native/env-config", 15 | "contributors": [ 16 | { 17 | "name": "Drew Miller" 18 | } 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/x-react-native/env-config" 23 | }, 24 | "private": false, 25 | "author": "Pedro Belo", 26 | "files": [ 27 | "android/", 28 | "ios/", 29 | "index.js", 30 | "index.d.ts", 31 | "x-react-native-env-config.podspec" 32 | ], 33 | "types": "./index.d.ts", 34 | "license": "MIT", 35 | "licenseFilename": "LICENSE", 36 | "readmeFilename": "README.md" 37 | } 38 | -------------------------------------------------------------------------------- /readme-pics/1.ios_new_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-react-native/env-config/e7cf53a5984122ed6c1c26d0c45fe82213172a4c/readme-pics/1.ios_new_file.png -------------------------------------------------------------------------------- /readme-pics/2.ios_file_type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-react-native/env-config/e7cf53a5984122ed6c1c26d0c45fe82213172a4c/readme-pics/2.ios_file_type.png -------------------------------------------------------------------------------- /readme-pics/3.ios_apply_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-react-native/env-config/e7cf53a5984122ed6c1c26d0c45fe82213172a4c/readme-pics/3.ios_apply_config.png -------------------------------------------------------------------------------- /x-react-native-env-config.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "x-react-native-env-config" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.description = <<-DESC 10 | x-react-native-env-config 11 | DESC 12 | s.homepage = "https://github.com/x-react-native/env-config" 13 | s.license = { :type => "MIT", :file => "LICENSE" } 14 | s.authors = 'Pedro Belo', "Drew Miller" 15 | s.platforms = { :ios => "9.0", :tvos => "10.0" } 16 | s.source = { :git => "https://github.com/x-react-native/env-config", :tag => "#{s.version}" } 17 | 18 | s.script_phase = { 19 | name: 'Config codegen', 20 | script: %( 21 | set -ex 22 | HOST_PATH="$SRCROOT/../.." 23 | "${PODS_TARGET_SRCROOT}/ios/BuildDotenvConfig.rb" "$HOST_PATH" "${PODS_TARGET_SRCROOT}/ios" 24 | ), 25 | execution_position: :before_compile, 26 | input_files: ['$(SRCROOT)/BuildDotenvConfig.rb'] 27 | } 28 | 29 | s.source_files = 'ios/**/*.{h,m}' 30 | s.requires_arc = true 31 | 32 | s.dependency 'React' 33 | end 34 | --------------------------------------------------------------------------------