-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add react-native-permissions config plugin #126
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// @generated by expo-module-scripts | ||
module.exports = require('expo-module-scripts/eslintrc.base.js'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# @config-plugins/react-native-permissions | ||
|
||
Expo Config Plugin to auto-configure [`react-native-permissions`](https://www.npmjs.com/package/react-native-permissions) when the native code is generated (`expo prebuild`). | ||
|
||
## Expo installation | ||
|
||
> Tested against Expo SDK 46 | ||
|
||
This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/). | ||
|
||
- First install the package with yarn, npm, or [`expo install`](https://docs.expo.io/workflow/expo-cli/#expo-install). | ||
|
||
```sh | ||
expo install react-native-permissions @config-plugins/react-native-permissions | ||
``` | ||
|
||
After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js` and provide a list of [permission handlers](https://github.com/zoontek/react-native-permissions#ios) that should be installed: | ||
|
||
> You can omit the `Permission-` prefix from the pod name, eg. `Permission-Camera` should be just `Camera`: | ||
|
||
```json | ||
{ | ||
"expo": { | ||
"plugins": [ | ||
[ | ||
"@config-plugins/react-native-permissions", | ||
{ "pods": ["Camera", "Notifications"] } | ||
] | ||
] | ||
} | ||
} | ||
``` | ||
|
||
Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide. | ||
|
||
⚠️ Please note that this config plugin doesn't handle the configuration of Android permissions since Expo provides a [built-in way](https://docs.expo.dev/guides/permissions/#android) to do that. Same applies for [iOS permission messages](https://docs.expo.dev/guides/permissions/#ios) in your `Info.plist`. You will need to configure those in order to use `react-native-permissions` properly. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require("./build/withReactNativePermissions"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@config-plugins/react-native-permissions", | ||
"version": "1.0.0", | ||
"description": "Config plugin to auto configure react-native-permissions on prebuild", | ||
"main": "build/withReactNativePermissions.js", | ||
"types": "build/withReactNativePermissions.d.ts", | ||
"sideEffects": false, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/expo/config-plugins.git", | ||
"directory": "packages/react-native-permissions" | ||
}, | ||
"scripts": { | ||
"build": "expo-module build", | ||
"clean": "expo-module clean", | ||
"lint": "expo-module lint", | ||
"test": "expo-module test", | ||
"prepare": "expo-module prepare", | ||
"prepublishOnly": "expo-module prepublishOnly", | ||
"expo-module": "expo-module" | ||
}, | ||
"keywords": [ | ||
"react", | ||
"expo", | ||
"config-plugins", | ||
"prebuild", | ||
"react-native-permissions" | ||
], | ||
"jest": { | ||
"preset": "expo-module-scripts" | ||
}, | ||
"peerDependencies": { | ||
"expo": "^46.0.2" | ||
}, | ||
"devDependencies": { | ||
"expo-module-scripts": "^2.0.0" | ||
}, | ||
"upstreamPackage": "react-native-permissions" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { | ||
withDangerousMod, | ||
ConfigPlugin, | ||
createRunOncePlugin, | ||
} from "@expo/config-plugins"; | ||
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode"; | ||
import fs from "fs"; | ||
import path from "path"; | ||
|
||
const withReactNativePermissions: ConfigPlugin<{ pods: string[] }> = ( | ||
config, | ||
{ pods } | ||
) => { | ||
return withDangerousMod(config, [ | ||
"ios", | ||
async (config) => { | ||
const filePath = path.join( | ||
config.modRequest.platformProjectRoot, | ||
"Podfile" | ||
); | ||
|
||
const contents = fs.readFileSync(filePath, "utf-8"); | ||
|
||
const result = mergeContents({ | ||
tag: "react-native-permissions", | ||
src: contents, | ||
newSrc: getPodfileContent(pods), | ||
anchor: /use_native_modules/, | ||
offset: 0, | ||
comment: "#", | ||
}); | ||
|
||
fs.writeFileSync(filePath, result.contents); | ||
|
||
return config; | ||
}, | ||
]); | ||
}; | ||
|
||
function getPodfileContent(pods: string[]) { | ||
return ` | ||
permissions_path = '../node_modules/react-native-permissions/ios' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should use Node module resolution to support monorepos, ex. Basically you use Node.js to search for |
||
${pods | ||
.map( | ||
(pod) => `pod 'Permission-${pod}', :path => "#{permissions_path}/${pod}"` | ||
) | ||
.join("\n ")} | ||
`; | ||
} | ||
|
||
export default createRunOncePlugin( | ||
withReactNativePermissions, | ||
"react-native-permissions" | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"extends": "expo-module-scripts/tsconfig.plugin", | ||
"compilerOptions": { | ||
"outDir": "./build" | ||
}, | ||
"include": ["./src"], | ||
"exclude": ["**/__mocks__/*", "**/__tests__/*"] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be cool if this was a for loop iterating some array in Podfile properties, similar to what we do in ffmpeg.