Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/react-native-permissions/.eslintrc.js
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');
36 changes: 36 additions & 0 deletions packages/react-native-permissions/README.md
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.
1 change: 1 addition & 0 deletions packages/react-native-permissions/app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./build/withReactNativePermissions");
39 changes: 39 additions & 0 deletions packages/react-native-permissions/package.json
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[]) {
Copy link
Collaborator

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.

return `
permissions_path = '../node_modules/react-native-permissions/ios'
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 react-native-permissions/package.json then you get a string like ../node_modules/react-native-permissions/package.json which you can then append ../ios to. This will allow the module to live anywhere and keep the package working in most cases.

${pods
.map(
(pod) => `pod 'Permission-${pod}', :path => "#{permissions_path}/${pod}"`
)
.join("\n ")}
`;
}

export default createRunOncePlugin(
withReactNativePermissions,
"react-native-permissions"
);
8 changes: 8 additions & 0 deletions packages/react-native-permissions/tsconfig.json
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__/*"]
}