Browse Source

Merge branch 'master' of git://github.com/yonahforst/react-native-permissions into motion-permission-request

Peter Lau 7 years ago
parent
commit
ad1c633a6e
95 changed files with 1719 additions and 805 deletions
  1. 9
    0
      .flowconfig
  2. 74
    0
      .github/CODE_OF_CONDUCT.md
  3. 26
    0
      .github/ISSUE_TEMPLATE.md
  4. 15
    10
      .gitignore
  5. 1
    1
      .npmignore
  6. 3
    0
      .prettierignore
  7. 5
    0
      .prettierrc
  8. 0
    46
      CODE_OF_CONDUCT.md
  9. 0
    12
      Example/__tests__/index.android.js
  10. 0
    12
      Example/__tests__/index.ios.js
  11. 0
    14
      Example/index.android.js
  12. 0
    14
      Example/index.ios.js
  13. 0
    38
      Example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json
  14. 0
    23
      Example/package.json
  15. 239
    167
      README.md
  16. 14
    15
      ReactNativePermissions.podspec
  17. 0
    7
      ReactNativePermissions.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  18. 0
    80
      ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/ReactNativePermissions.xcscheme
  19. 0
    22
      ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/xcschememanagement.plist
  20. 0
    0
      example/.babelrc
  21. 0
    0
      example/.buckconfig
  22. 9
    6
      example/.flowconfig
  23. 0
    0
      example/.gitattributes
  24. 4
    4
      example/.gitignore
  25. 0
    0
      example/.watchmanconfig
  26. 51
    52
      example/App.js
  27. 10
    0
      example/__tests__/index.js
  28. 0
    0
      example/android/app/BUCK
  29. 5
    1
      example/android/app/build.gradle
  30. 0
    0
      example/android/app/proguard-rules.pro
  31. 6
    1
      example/android/app/src/main/AndroidManifest.xml
  32. 0
    0
      example/android/app/src/main/java/com/example/MainActivity.java
  33. 5
    0
      example/android/app/src/main/java/com/example/MainApplication.java
  34. 0
    0
      example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  35. 0
    0
      example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  36. 0
    0
      example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  37. 0
    0
      example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  38. 0
    1
      example/android/app/src/main/res/values/strings.xml
  39. 0
    0
      example/android/app/src/main/res/values/styles.xml
  40. 1
    0
      example/android/build.gradle
  41. 0
    0
      example/android/gradle.properties
  42. 0
    0
      example/android/gradle/wrapper/gradle-wrapper.jar
  43. 1
    2
      example/android/gradle/wrapper/gradle-wrapper.properties
  44. 0
    0
      example/android/gradlew
  45. 0
    0
      example/android/gradlew.bat
  46. 0
    0
      example/android/keystores/BUCK
  47. 0
    0
      example/android/keystores/debug.keystore.properties
  48. 0
    0
      example/android/settings.gradle
  49. 4
    0
      example/app.json
  50. 4
    0
      example/index.js
  51. 0
    0
      example/ios/Example-tvOS/Info.plist
  52. 0
    0
      example/ios/Example-tvOSTests/Info.plist
  53. 217
    34
      example/ios/Example.xcodeproj/project.pbxproj
  54. 0
    0
      example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme
  55. 1
    1
      example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
  56. 0
    0
      example/ios/Example/AppDelegate.h
  57. 1
    1
      example/ios/Example/AppDelegate.m
  58. 0
    0
      example/ios/Example/Base.lproj/LaunchScreen.xib
  59. 38
    0
      example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json
  60. 6
    0
      example/ios/Example/Images.xcassets/Contents.json
  61. 5
    1
      example/ios/Example/Info.plist
  62. 0
    0
      example/ios/Example/main.m
  63. 0
    0
      example/ios/ExampleTests/ExampleTests.m
  64. 0
    0
      example/ios/ExampleTests/Info.plist
  65. 23
    0
      example/package.json
  66. 0
    91
      index.android.js
  67. 0
    70
      index.ios.js
  68. 4
    0
      index.js
  69. 0
    0
      ios/Permissions/RNPAudioVideo.h
  70. 0
    0
      ios/Permissions/RNPAudioVideo.m
  71. 0
    0
      ios/Permissions/RNPBackgroundRefresh.h
  72. 0
    0
      ios/Permissions/RNPBackgroundRefresh.m
  73. 0
    0
      ios/Permissions/RNPBluetooth.h
  74. 0
    0
      ios/Permissions/RNPBluetooth.m
  75. 0
    0
      ios/Permissions/RNPContacts.h
  76. 0
    0
      ios/Permissions/RNPContacts.m
  77. 0
    0
      ios/Permissions/RNPEvent.h
  78. 0
    0
      ios/Permissions/RNPEvent.m
  79. 0
    0
      ios/Permissions/RNPLocation.h
  80. 0
    0
      ios/Permissions/RNPLocation.m
  81. 0
    0
      ios/Permissions/RNPNotification.h
  82. 0
    0
      ios/Permissions/RNPNotification.m
  83. 0
    0
      ios/Permissions/RNPPhoto.h
  84. 0
    0
      ios/Permissions/RNPPhoto.m
  85. 0
    0
      ios/Permissions/RNPSpeechRecognition.h
  86. 0
    0
      ios/Permissions/RNPSpeechRecognition.m
  87. 0
    0
      ios/RCTConvert+RNPStatus.h
  88. 0
    1
      ios/RCTConvert+RNPStatus.m
  89. 0
    1
      ios/ReactNativePermissions.h
  90. 5
    1
      ios/ReactNativePermissions.m
  91. 74
    64
      ios/ReactNativePermissions.xcodeproj/project.pbxproj
  92. 117
    0
      lib/permissions.android.js
  93. 107
    0
      lib/permissions.ios.js
  94. 21
    12
      package.json
  95. 614
    0
      yarn.lock

+ 9
- 0
.flowconfig View File

1
+[ignore]
2
+
3
+[include]
4
+
5
+[libs]
6
+
7
+[lints]
8
+
9
+[options]

+ 74
- 0
.github/CODE_OF_CONDUCT.md View File

1
+# Contributor Covenant Code of Conduct
2
+
3
+## Our Pledge
4
+
5
+In the interest of fostering an open and welcoming environment, we as
6
+contributors and maintainers pledge to making participation in our project and
7
+our community a harassment-free experience for everyone, regardless of age, body
8
+size, disability, ethnicity, gender identity and expression, level of
9
+experience, nationality, personal appearance, race, religion, or sexual identity
10
+and orientation.
11
+
12
+## Our Standards
13
+
14
+Examples of behavior that contributes to creating a positive environment
15
+include:
16
+
17
+* Using welcoming and inclusive language
18
+* Being respectful of differing viewpoints and experiences
19
+* Gracefully accepting constructive criticism
20
+* Focusing on what is best for the community
21
+* Showing empathy towards other community members
22
+
23
+Examples of unacceptable behavior by participants include:
24
+
25
+* The use of sexualized language or imagery and unwelcome sexual attention or
26
+  advances
27
+* Trolling, insulting/derogatory comments, and personal or political attacks
28
+* Public or private harassment
29
+* Publishing others' private information, such as a physical or electronic
30
+  address, without explicit permission
31
+* Other conduct which could reasonably be considered inappropriate in a
32
+  professional setting
33
+
34
+## Our Responsibilities
35
+
36
+Project maintainers are responsible for clarifying the standards of acceptable
37
+behavior and are expected to take appropriate and fair corrective action in
38
+response to any instances of unacceptable behavior.
39
+
40
+Project maintainers have the right and responsibility to remove, edit, or reject
41
+comments, commits, code, wiki edits, issues, and other contributions that are
42
+not aligned to this Code of Conduct, or to ban temporarily or permanently any
43
+contributor for other behaviors that they deem inappropriate, threatening,
44
+offensive, or harmful.
45
+
46
+## Scope
47
+
48
+This Code of Conduct applies both within project spaces and in public spaces
49
+when an individual is representing the project or its community. Examples of
50
+representing a project or community include using an official project e-mail
51
+address, posting via an official social media account, or acting as an appointed
52
+representative at an online or offline event. Representation of a project may be
53
+further defined and clarified by project maintainers.
54
+
55
+## Enforcement
56
+
57
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+reported by contacting the project team at yonaforst@hotmail.com. The project
59
+team will review and investigate all complaints, and will respond in a way that
60
+it deems appropriate to the circumstances. The project team is obligated to
61
+maintain confidentiality with regard to the reporter of an incident. Further
62
+details of specific enforcement policies may be posted separately.
63
+
64
+Project maintainers who do not follow or enforce the Code of Conduct in good
65
+faith may face temporary or permanent repercussions as determined by other
66
+members of the project's leadership.
67
+
68
+## Attribution
69
+
70
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
71
+version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+[homepage]: http://contributor-covenant.org
74
+[version]: http://contributor-covenant.org/version/1/4/

+ 26
- 0
.github/ISSUE_TEMPLATE.md View File

1
+Hello!
2
+
3
+Please read the following carefully before opening a new issue. Your issue may
4
+be closed if it doesn't provide the informations required.
5
+
6
+#### ⚠️ Delete everything above this line
7
+
8
+### Describe your environment
9
+
10
+* React-Native version
11
+* Platform: iOS, Android, both?
12
+* Device (which one?), simulator?
13
+* OS version
14
+* react-native-permissions version
15
+* Devtools: Xcode? Android Studio version?
16
+* (Android only: buildToolsVersion)
17
+
18
+### How to repeat issue and example
19
+
20
+Explain what you did, what you expected to happen, and what actually happens.
21
+Provide some code if needed.
22
+
23
+### Solution
24
+
25
+Do you know what needs to be done to address this issue? Ideally, provide a pull
26
+request with a fix.

+ 15
- 10
.gitignore View File

1
-android/react-native-permissions.iml
2
-android/build
3
-android/.idea
4
-npm-debug.log
5
-gradlew
6
-gradle-wrapper.properties
7
-gradle-wrapper.jar
8
-local.properties
9
-gradlew.bat
10
-android.iml
1
+*.xcworkspace
2
+xcuserdata
3
+
4
+npm-debug.log*
5
+yarn-debug.log*
6
+yarn-error.log*
7
+node_modules/
8
+
9
+*.DS_Store
10
+Thumbs.db
11
+Desktop.ini
12
+
13
+.vscode/
14
+
15
+android/build/

+ 1
- 1
.npmignore View File

1
-Example
1
+example/

+ 3
- 0
.prettierignore View File

1
+android/
2
+ios/
3
+example/node_modules/

+ 5
- 0
.prettierrc View File

1
+{
2
+  "singleQuote": true,
3
+  "trailingComma": "all",
4
+  "semi": false
5
+}

+ 0
- 46
CODE_OF_CONDUCT.md View File

1
-# Contributor Covenant Code of Conduct
2
-
3
-## Our Pledge
4
-
5
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
-
7
-## Our Standards
8
-
9
-Examples of behavior that contributes to creating a positive environment include:
10
-
11
-* Using welcoming and inclusive language
12
-* Being respectful of differing viewpoints and experiences
13
-* Gracefully accepting constructive criticism
14
-* Focusing on what is best for the community
15
-* Showing empathy towards other community members
16
-
17
-Examples of unacceptable behavior by participants include:
18
-
19
-* The use of sexualized language or imagery and unwelcome sexual attention or advances
20
-* Trolling, insulting/derogatory comments, and personal or political attacks
21
-* Public or private harassment
22
-* Publishing others' private information, such as a physical or electronic address, without explicit permission
23
-* Other conduct which could reasonably be considered inappropriate in a professional setting
24
-
25
-## Our Responsibilities
26
-
27
-Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
-
29
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
-
31
-## Scope
32
-
33
-This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
-
35
-## Enforcement
36
-
37
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at yonaforst@hotmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
-
39
-Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
-
41
-## Attribution
42
-
43
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
-
45
-[homepage]: http://contributor-covenant.org
46
-[version]: http://contributor-covenant.org/version/1/4/

+ 0
- 12
Example/__tests__/index.android.js View File

1
-import 'react-native';
2
-import React from 'react';
3
-import Index from '../index.android.js';
4
-
5
-// Note: test renderer must be required after react-native.
6
-import renderer from 'react-test-renderer';
7
-
8
-it('renders correctly', () => {
9
-  const tree = renderer.create(
10
-    <Index />
11
-  );
12
-});

+ 0
- 12
Example/__tests__/index.ios.js View File

1
-import 'react-native';
2
-import React from 'react';
3
-import Index from '../index.ios.js';
4
-
5
-// Note: test renderer must be required after react-native.
6
-import renderer from 'react-test-renderer';
7
-
8
-it('renders correctly', () => {
9
-  const tree = renderer.create(
10
-    <Index />
11
-  );
12
-});

+ 0
- 14
Example/index.android.js View File

1
-/**
2
- * Sample React Native App
3
- * https://github.com/facebook/react-native
4
- * @flow
5
- */
6
-
7
-import React, { Component } from 'react';
8
-import {
9
-  AppRegistry,
10
-} from 'react-native';
11
-
12
-import Example from './Example'
13
-
14
-AppRegistry.registerComponent('Example', () => Example);

+ 0
- 14
Example/index.ios.js View File

1
-/**
2
- * Sample React Native App
3
- * https://github.com/facebook/react-native
4
- * @flow
5
- */
6
-
7
-import React, { Component } from 'react';
8
-import {
9
-  AppRegistry,
10
-} from 'react-native';
11
-
12
-import Example from './Example'
13
-
14
-AppRegistry.registerComponent('Example', () => Example);

+ 0
- 38
Example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json View File

1
-{
2
-  "images" : [
3
-    {
4
-      "idiom" : "iphone",
5
-      "size" : "29x29",
6
-      "scale" : "2x"
7
-    },
8
-    {
9
-      "idiom" : "iphone",
10
-      "size" : "29x29",
11
-      "scale" : "3x"
12
-    },
13
-    {
14
-      "idiom" : "iphone",
15
-      "size" : "40x40",
16
-      "scale" : "2x"
17
-    },
18
-    {
19
-      "idiom" : "iphone",
20
-      "size" : "40x40",
21
-      "scale" : "3x"
22
-    },
23
-    {
24
-      "idiom" : "iphone",
25
-      "size" : "60x60",
26
-      "scale" : "2x"
27
-    },
28
-    {
29
-      "idiom" : "iphone",
30
-      "size" : "60x60",
31
-      "scale" : "3x"
32
-    }
33
-  ],
34
-  "info" : {
35
-    "version" : 1,
36
-    "author" : "xcode"
37
-  }
38
-}

+ 0
- 23
Example/package.json View File

1
-{
2
-  "name": "Example",
3
-  "version": "0.0.1",
4
-  "private": true,
5
-  "scripts": {
6
-    "start": "react-native start",
7
-    "test": "jest"
8
-  },
9
-  "dependencies": {
10
-    "react": "^16.0.0-alpha.12",
11
-    "react-native": "^0.48.4",
12
-    "react-native-permissions": "../"
13
-  },
14
-  "devDependencies": {
15
-    "babel-jest": "18.0.0",
16
-    "babel-preset-react-native": "1.9.1",
17
-    "jest": "18.1.0",
18
-    "react-test-renderer": "15.4.2"
19
-  },
20
-  "jest": {
21
-    "preset": "react-native"
22
-  }
23
-}

+ 239
- 167
README.md View File

1
-# React Native Permissions
2
-Request user permissions from React Native, iOS + Android
1
+# ☝🏼 React Native Permissions
3
 
2
 
4
-The current supported permissions are:
5
-- Location
6
-- Camera
7
-- Microphone
8
-- Photos
9
-- Contacts
10
-- Events
11
-- Reminders *(iOS only)*
12
-- Bluetooth *(iOS only)*
13
-- Push Notifications *(iOS only)*
14
-- Background Refresh *(iOS only)*
15
-- Speech Recognition *(iOS only)*
16
-- Core Motion *(iOS only)*
17
-- Call Phone *(Android Only)*
18
-- Read/Receive SMS *(Android only)*
3
+[![npm version](https://badge.fury.io/js/react-native-permissions.svg)](https://badge.fury.io/js/react-native-permissions)
4
+[![npm](https://img.shields.io/npm/dt/react-native-permissions.svg)](https://www.npmjs.org/package/react-native-permissions)
5
+![Platform - Android and iOS](https://img.shields.io/badge/platform-Android%20%7C%20iOS-yellow.svg)
6
+![MIT](https://img.shields.io/dub/l/vibe-d.svg)
7
+[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
19
 
8
 
9
+Request user permissions from React Native, iOS + Android
20
 
10
 
21
 | Version | React Native Support |
11
 | Version | React Native Support |
22
-|---|---|
23
-| 1.0.1 | 0.40.0 - 0.48.4 |
24
-| 0.2.7 | 0.40.0 - 0.41.0 |
25
-| 0.2.5 | 0.33.0 - 0.39.0 |
26
-*Complies with [react-native-version-support-table](https://github.com/dangnelson/react-native-version-support-table)*
27
-
28
-### Breaking changes in version 1.0.0
29
-  - Now using React Native's own JS PermissionsAndroid library on Android, which is great because now we no longer have to do any additional linking (on Android)
30
-  - Updated API to be closer to RN's PermissionsAndroid
31
-  - Removed `openSettings()` support on Android (to stay linking-free). There are several NPM modules available for this
32
-  - `restricted` status now supported on Android, although it means something different than iOS
33
-
34
-## General Usage
35
-```
12
+| ------- | -------------------- |
13
+| 1.0.6   | 0.40 - 0.51          |
14
+| 0.2.5   | 0.33 - 0.39          |
15
+
16
+_Complies with
17
+[react-native-version-support-table](https://github.com/dangnelson/react-native-version-support-table)_
18
+
19
+## ⚠️ Breaking changes in version 1.0.0
20
+
21
+* Now using React Native's own JS `PermissionsAndroid` module on Android, which
22
+  is great because we no longer have to do any additional linking on Android
23
+* Updated API to be closer to React Native's `PermissionsAndroid`
24
+* Removed `openSettings()` support on Android (to stay linking-free). There are
25
+  several NPM modules available for this
26
+* `restricted` status now supported on Android, although it means something
27
+  different than iOS
28
+
29
+## Setup
30
+
31
+```sh
36
 npm install --save react-native-permissions
32
 npm install --save react-native-permissions
37
-react-native link
33
+# --- or ---
34
+yarn add react-native-permissions
35
+```
36
+
37
+_📌 Don't forget to add permissions to `AndroidManifest.xml` for android and
38
+`Info.plist` for iOS (Xcode >= 8). See [iOS Notes](#ios-notes) or [Android Notes](#android-notes) for more details._
39
+
40
+### Additional iOS setup
41
+
42
+#### Using cocoaPods
43
+
44
+Update the following line with your path to `node_modules/` and add it to your
45
+podfile:
46
+
47
+```ruby
48
+pod 'ReactNativePermissions', :path => '../node_modules/react-native-permissions'
38
 ```
49
 ```
39
 
50
 
40
-Add permissions to manifest for android and info.plist for ios (xcode >=8). See notes below for more details.
51
+#### Using react-native link
52
+
53
+```sh
54
+react-native link react-native-permissions
55
+```
56
+
57
+#### Using manual linking
58
+
59
+1. In the XCode's "Project navigator", right click on your project's Libraries
60
+   folder ➜ `Add Files to <...>`
61
+2. Go to `node_modules` ➜ `react-native-permissions` ➜ select
62
+   `ReactNativePermissions.xcodeproj`
63
+3. Add `libReactNativePermissions.a` to `Build Phases` -> `Link Binary With
64
+   Libraries`
65
+
66
+## Using
41
 
67
 
42
 ```js
68
 ```js
43
-const Permissions = require('react-native-permissions');
69
+import Permissions from 'react-native-permissions'
70
+// OR const Permissions = require('react-native-permissions').default
71
+// if you use CommonJS module system
44
 
72
 
45
 //...
73
 //...
46
-  //check the status of a single permission
74
+
75
+export default class extends React.Component {
76
+  //...
77
+
78
+  // Check the status of a single permission
47
   componentDidMount() {
79
   componentDidMount() {
48
-    Permissions.check('photo')
49
-      .then(response => {
50
-        //response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
51
-        this.setState({ photoPermission: response })
52
-      });
80
+    Permissions.check('photo').then(response => {
81
+      // Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
82
+      this.setState({ photoPermission: response })
83
+    })
53
   }
84
   }
54
 
85
 
55
-  //request permission to access photos
56
-  _requestPermission() {
57
-    Permissions.request('photo')
58
-      .then(response => {
59
-        //returns once the user has chosen to 'allow' or to 'not allow' access
60
-        //response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
61
-        this.setState({ photoPermission: response })
62
-      });
86
+  // Request permission to access photos
87
+  _requestPermission = () => {
88
+    Permissions.request('photo').then(response => {
89
+      // Returns once the user has chosen to 'allow' or to 'not allow' access
90
+      // Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
91
+      this.setState({ photoPermission: response })
92
+    })
63
   }
93
   }
64
 
94
 
65
-  //check the status of multiple permissions
66
-  _checkCameraAndPhotos() {
67
-    Permissions.checkMultiple(['camera', 'photo'])
68
-      .then(response => {
69
-        //response is an object mapping type to permission
70
-        this.setState({
71
-          cameraPermission: response.camera,
72
-          photoPermission: response.photo,
73
-        })
74
-      });
95
+  // Check the status of multiple permissions
96
+  _checkCameraAndPhotos = () => {
97
+    Permissions.checkMultiple(['camera', 'photo']).then(response => {
98
+      //response is an object mapping type to permission
99
+      this.setState({
100
+        cameraPermission: response.camera,
101
+        photoPermission: response.photo,
102
+      })
103
+    })
75
   }
104
   }
76
 
105
 
77
-  // this is a common pattern when asking for permissions.
106
+  // This is a common pattern when asking for permissions.
78
   // iOS only gives you once chance to show the permission dialog,
107
   // iOS only gives you once chance to show the permission dialog,
79
   // after which the user needs to manually enable them from settings.
108
   // after which the user needs to manually enable them from settings.
80
-  // the idea here is to explain why we need access and determine if
109
+  // The idea here is to explain why we need access and determine if
81
   // the user will say no, so that we don't blow our one chance.
110
   // the user will say no, so that we don't blow our one chance.
82
-  // if the user already denied access, we can ask them to enable it from settings.
111
+  // If the user already denied access, we can ask them to enable it from settings.
83
   _alertForPhotosPermission() {
112
   _alertForPhotosPermission() {
84
     Alert.alert(
113
     Alert.alert(
85
       'Can we access your photos?',
114
       'Can we access your photos?',
86
       'We need access so you can set your profile pic',
115
       'We need access so you can set your profile pic',
87
       [
116
       [
88
-        {text: 'No way', onPress: () => console.log('permission denied'), style: 'cancel'},
89
-        this.state.photoPermission == 'undetermined'?
90
-          {text: 'OK', onPress: this._requestPermission.bind(this)}
91
-          : {text: 'Open Settings', onPress: Permissions.openSettings}
92
-      ]
117
+        {
118
+          text: 'No way',
119
+          onPress: () => console.log('Permission denied'),
120
+          style: 'cancel',
121
+        },
122
+        this.state.photoPermission == 'undetermined'
123
+          ? { text: 'OK', onPress: this._requestPermission }
124
+          : { text: 'Open Settings', onPress: Permissions.openSettings },
125
+      ],
93
     )
126
     )
94
   }
127
   }
95
-//...
96
-```
97
-
98
-## API
99
-
100
-### Permission statuses
101
-Promises resolve into one of these statuses
102
-
103
-| Return value | Notes|
104
-|---|---|
105
-|`authorized`| user has authorized this permission |
106
-|`denied`| user has denied this permission at least once. On iOS this means that the user will not be prompted again. Android users can be promted multiple times until they select 'Never ask me again'|
107
-|`restricted`| **iOS** - this means user is not able to grant this permission, either because it's not supported by the device or because it has been blocked by parental controls. **Android** - this means that the user has selected 'Never ask me again' while denying permission |
108
-|`undetermined`| user has not yet been prompted with a permission dialog |
109
-
110
-### Supported permission types
111
-
112
-| Name | iOS | Android |
113
-|---|---|---|
114
-|`location`| ✔️ | ✔ |
115
-|`camera`| ✔️ | ✔ |
116
-|`microphone`| ✔️ | ✔ |
117
-|`photo`| ✔️ | ✔ |
118
-|`contacts`| ✔️ | ✔ |
119
-|`event`| ✔️ | ✔ |
120
-|`bluetooth`| ✔️ | ❌ |
121
-|`reminder`| ✔️ | ❌ |
122
-|`notification`| ✔️ | ❌ |
123
-|`backgroundRefresh`| ✔️ | ❌ |
124
-|`speechRecognition`| ✔️ | ❌ |
125
-|`motion`| ✔️ | ❌ |
126
-|`storage`| ❌️ | ✔ |
127
-|`callPhone`| ❌️ | ✔ |
128
-|`readSms`| ❌️ | ✔ |
129
-|`receiveSms`| ❌️ | ✔ |
130
-
131
-### Methods
132
-| Method Name | Arguments | Notes
133
-|---|---|---|
134
-| `check()` | `type` | - Returns a promise with the permission status. See iOS Notes for special cases |
135
-| `request()` | `type` | - Accepts any permission type except `backgroundRefresh`. If the current status is `undetermined`, shows the permission dialog and returns a promise with the resulting status. Otherwise, immediately return a promise with the current status. See iOS Notes for special cases|
136
-| `checkMultiple()` | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses |
137
-| `getTypes()` | *none* | - Returns an array of valid permission types  |
138
-| `openSettings()` | *none* | - *(iOS only - 8.0 and later)* Switches the user to the settings page of your app |
139
-| `canOpenSettings()` | *none* | - *(iOS only)* Returns a boolean indicating if the device supports switching to the settings page |
140
-
141
-### iOS Notes
142
-- Permission type `bluetooth` represents the status of the `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
143
-- Permission type `location` accepts a second parameter for `request()` and `check()`;  the second parameter is a string, either `always` or `whenInUse`(default).
144
 
128
 
145
-- Permission type `notification` accepts a second parameter for `request()`. The second parameter is an array with the desired alert types. Any combination of `alert`, `badge` and `sound` (default requests all three)
146
-
147
-```js
148
-///example
149
-    Permissions.check('location', 'always')
150
-      .then(response => {
151
-        this.setState({ locationPermission: response })
152
-      })
153
-
154
-    Permissions.request('location', 'always')
155
-      .then(response => {
156
-        this.setState({ locationPermission: response })
157
-      })
158
-
159
-    Permissions.request('notification', ['alert', 'badge'])
160
-      .then(response => {
161
-        this.setState({ notificationPermission: response })
162
-      })
129
+  //...
130
+}
163
 ```
131
 ```
164
 
132
 
165
-You cannot request microphone permissions on the simulator.
133
+## API
166
 
134
 
167
-With Xcode 8, you now need to add usage descriptions for each permission you will request. Open Xcode > Info.plist > Add a key (starting with "Privacy - ...") with your kit specific permission.
135
+### Permissions statuses
168
 
136
 
169
-Example:
170
-If you need Contacts permission you have to add the key "Privacy - Contacts Usage Description".
171
-<img width="338" alt="3cde3b44-7ffd-11e6-918b-63888e33f983" src="https://cloud.githubusercontent.com/assets/1440796/18713019/271be540-8011-11e6-87fb-c3828c172dfc.png">
137
+Promises resolve into one of these statuses:
172
 
138
 
173
-### Android Notes
139
+| Return value   | Notes                                                                                                                                                                                                                                                                  |
140
+| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
141
+| `authorized`   | User has authorized this permission                                                                                                                                                                                                                                    |
142
+| `denied`       | User has denied this permission at least once. On iOS this means that the user will not be prompted again. Android users can be prompted multiple times until they select 'Never ask me again'                                                                          |
143
+| `restricted`   | **iOS** - this means user is not able to grant this permission, either because it's not supported by the device or because it has been blocked by parental controls. **Android** - this means that the user has selected 'Never ask me again' while denying permission |
144
+| `undetermined` | User has not yet been prompted with a permission dialog                                                                                                                                                                                                                |
174
 
145
 
175
-Requires RN >= 0.29.0
146
+### Supported permissions types
176
 
147
 
177
-Uses RN's own `PermissionsAndroid` JS api (http://facebook.github.io/react-native/releases/0.45/docs/permissionsandroid.html)
148
+The current supported permissions are:
178
 
149
 
179
-All required permissions also need to be included in the Manifest before they can be requested. Otherwise `request()` will immediately return `denied`.
150
+|                    | Type                | iOS | Android |
151
+| ------------------ | ------------------- | --- | ------- |
152
+| Location           | `location`          | ✔️  | ✔       |
153
+| Camera             | `camera`            | ✔️  | ✔       |
154
+| Microphone         | `microphone`        | ✔️  | ✔       |
155
+| Photos             | `photo`             | ✔️  | ✔       |
156
+| Contacts           | `contacts`          | ✔️  | ✔       |
157
+| Events             | `event`             | ✔️  | ✔       |
158
+| Bluetooth          | `bluetooth`         | ✔️  | ❌      |
159
+| Reminders          | `reminder`          | ✔️  | ❌      |
160
+| Push Notifications | `notification`      | ✔️  | ❌      |
161
+| Background Refresh | `backgroundRefresh` | ✔️  | ❌      |
162
+| Speech Recognition | `speechRecognition` | ✔️  | ❌      |
163
+| Motion Activity    | `motion`            | ✔️  | ❌      |
164
+| Storage            | `storage`           | ❌️ | ✔       |
165
+| Phone Call         | `callPhone`         | ❌️ | ✔       |
166
+| Read SMS           | `readSms`           | ❌️ | ✔       |
167
+| Receive SMS        | `receiveSms`        | ❌️ | ✔       |
180
 
168
 
181
-Permissions are automatically accepted for targetSdkVersion < 23 but you can still use `check()` to check if the user has disabled them from Settings.
169
+### Methods
182
 
170
 
183
-You can request write access to any of these types by also including the appropriate write permission in the Manifest. Read more here: https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
171
+| Method Name         | Arguments | Notes                                                                                                                                                                                                                                                                            |
172
+| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
173
+| `check()`           | `type`    | - Returns a promise with the permission status. See iOS Notes for special cases                                                                                                                                                                                                  |
174
+| `request()`         | `type`    | - Accepts any permission type except `backgroundRefresh`. If the current status is `undetermined`, shows the permission dialog and returns a promise with the resulting status. Otherwise, immediately return a promise with the current status. See iOS Notes for special cases |
175
+| `checkMultiple()`   | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses                                                                                                                                                                 |
176
+| `getTypes()`        | _none_    | - Returns an array of valid permission types                                                                                                                                                                                                                                     |
177
+| `openSettings()`    | _none_    | - _(iOS only - 8.0 and later)_ Switches the user to the settings page of your app                                                                                                                                                                                                |
178
+| `canOpenSettings()` | _none_    | - _(iOS only)_ Returns a boolean indicating if the device supports switching to the settings page                                                                                                                                                                                |
184
 
179
 
185
-## Setup
180
+### iOS Notes
186
 
181
 
187
-````
188
-npm install --save react-native-permissions
189
-react-native link
190
-````
182
+* Permission type `bluetooth` represents the status of the
183
+  `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
184
+* Permission type `location` accepts a second parameter for `request()` and
185
+  `check()`; the second parameter is a string, either `always` or `whenInUse`
186
+  (default).
187
+* Permission type `notification` accepts a second parameter for `request()`. The
188
+  second parameter is an array with the desired alert types. Any combination of
189
+  `alert`, `badge` and `sound` (default requests all three).
191
 
190
 
192
-### Or manually linking
191
+```js
192
+// example
193
+Permissions.check('location', { type: 'always' }).then(response => {
194
+  this.setState({ locationPermission: response })
195
+})
196
+
197
+Permissions.request('location', { type: 'always' }).then(response => {
198
+  this.setState({ locationPermission: response })
199
+})
200
+
201
+Permissions.request('notification', { type: ['alert', 'badge'] }).then(
202
+  response => {
203
+    this.setState({ notificationPermission: response })
204
+  },
205
+)
206
+```
193
 
207
 
194
-#### iOS
195
-* Run open node_modules/react-native-permissions
196
-* Drag ReactNativePermissions.xcodeproj into the Libraries group of your app's Xcode project
197
-* Add libReactNativePermissions.a to `Build Phases -> Link Binary With Libraries.
208
+* You cannot request microphone permissions on the simulator.
209
+* With Xcode 8, you now need to add usage descriptions for each permission you
210
+  will request. Open Xcode ➜ `Info.plist` ➜ Add a key (starting with "Privacy -
211
+  ...") with your kit specific permission.
198
 
212
 
199
-#### Android
200
-  No additional linking required
213
+Example: If you need Contacts permission you have to add the key `Privacy -
214
+Contacts Usage Description`.
201
 
215
 
202
-## AppStore submission disclaimer
216
+<img width="338" alt="3cde3b44-7ffd-11e6-918b-63888e33f983" src="https://cloud.githubusercontent.com/assets/1440796/18713019/271be540-8011-11e6-87fb-c3828c172dfc.png">
203
 
217
 
204
-If you need to submit you application to the AppStore, you need to add to your `Info.plist` all `*UsageDescription` keys with a string value explaining to the user how the app uses this data. **Even if you don't use them**.
218
+#### App Store submission disclaimer
205
 
219
 
206
-So before submitting your app to the `AppStore`, make sure that in your `Info.plist` you have the following keys:
220
+If you need to submit you application to the AppStore, you need to add to your
221
+`Info.plist` all `*UsageDescription` keys with a string value explaining to the
222
+user how the app uses this data. **Even if you don't use them**.
207
 
223
 
208
-```
224
+So before submitting your app to the App Store, make sure that in your
225
+`Info.plist` you have the following keys:
209
 
226
 
227
+```xml
210
 <key>NSBluetoothPeripheralUsageDescription</key>
228
 <key>NSBluetoothPeripheralUsageDescription</key>
211
 <string>Some description</string>
229
 <string>Some description</string>
212
 <key>NSCalendarsUsageDescription</key>
230
 <key>NSCalendarsUsageDescription</key>
215
 <string>Some description</string>
233
 <string>Some description</string>
216
 <key>NSLocationWhenInUseUsageDescription</key>
234
 <key>NSLocationWhenInUseUsageDescription</key>
217
 <string>Some description</string>
235
 <string>Some description</string>
236
+<key>NSPhotoLibraryAddUsageDescription</key>
237
+<string>Some description</string>
218
 <key>NSPhotoLibraryUsageDescription</key>
238
 <key>NSPhotoLibraryUsageDescription</key>
219
 <string>Some description</string>
239
 <string>Some description</string>
220
 <key>NSSpeechRecognitionUsageDescription</key>
240
 <key>NSSpeechRecognitionUsageDescription</key>
221
 <string>Some description</string>
241
 <string>Some description</string>
222
 <key>NSMotionUsageDescription</key>
242
 <key>NSMotionUsageDescription</key>
223
 <string>Some description</string>
243
 <string>Some description</string>
244
+```
245
+
246
+This is required because during the phase of processing in the App Store
247
+submission, the system detects that you app contains code to request the
248
+permission `X` but don't have the `UsageDescription` key and then it rejects the
249
+build.
250
+
251
+> Please note that it will only be shown to the users the usage descriptions of
252
+> the permissions you really require in your app.
253
+
254
+You can find more information about this issue in #46.
255
+
256
+### Android Notes
257
+
258
+* Uses React Native's own
259
+  [`PermissionsAndroid` JS API](http://facebook.github.io/react-native/docs/permissionsandroid.html).
260
+* All required permissions also need to be included in the `AndroidManifest.xml`
261
+  file before they can be requested. Otherwise `request()` will immediately
262
+  return `denied`.
263
+* You can request write access to any of these types by also including the
264
+  appropriate write permission in the `AndroidManifest.xml` file. Read more
265
+  [here](https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous).
224
 
266
 
267
+* The optional rationale argument will show a dialog prompt.
268
+
269
+```js
270
+// example
271
+Permissions.request('camera', {
272
+  rationale: {
273
+    title: 'Cool Photo App Camera Permission',
274
+    message:
275
+      'Cool Photo App needs access to your camera ' +
276
+      'so you can take awesome pictures.',
277
+  },
278
+}).then(response => {
279
+  this.setState({ cameraPermission: response })
280
+})
225
 ```
281
 ```
226
 
282
 
227
-This is required because during the phase of `processing` in the `AppStore` submission, the system detects that you app contains code to request the permission `X` but don't have the `UsageDescription` key and rejects the build.
283
+* Permissions are automatically accepted for **targetSdkVersion < 23** but you
284
+  can still use `check()` to check if the user has disabled them from Settings.
228
 
285
 
229
-> Please note that it will only be shown to the users the usage descriptions of the permissions you really require in your app.
286
+You might need to elevate the **targetSdkVersion** version in your
287
+`build.gradle`:
230
 
288
 
231
-You can find more informations about this issue in #46.
289
+```groovy
290
+android {
291
+  compileSdkVersion 23 // ← set at least 23
292
+  buildToolsVersion "23.0.1"  // ← set at least 23.0.0
293
+
294
+  defaultConfig {
295
+    minSdkVersion 16
296
+    targetSdkVersion 23 // ← set at least 23
297
+    // ...
298
+```
232
 
299
 
233
 ## Troubleshooting
300
 ## Troubleshooting
234
 
301
 
235
-#### Q: iOS - app crashes as soon as I request permission
236
-A: starting with xcode 8, you need to add permission descriptions. see iOS notes for more details. Thanks to @jesperlndk for discovering this.
302
+#### Q: iOS - App crashes as soon as I request permission
303
+
304
+> A: Starting with Xcode 8, you need to add permission descriptions. See iOS
305
+> notes for more details. Thanks to [@jesperlndk](https://github.com/jesperlndk)
306
+> for discovering this.
307
+
308
+#### Q: iOS - App crashes when I change permission from settings
237
 
309
 
238
-#### Q: iOS - app crashes when I change permissions from settings
239
-A: This is normal. iOS restarts your app when your privacy settings change. Just google "ios crash permission change"
310
+> A: This is normal. iOS restarts your app when your privacy settings change.
311
+> Just google "iOS crash permission change"

+ 14
- 15
ReactNativePermissions.podspec View File

3
 package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3
 package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
 
4
 
5
 Pod::Spec.new do |s|
5
 Pod::Spec.new do |s|
6
-  s.name                = 'ReactNativePermissions'
7
-  s.version             = package['version']
8
-  s.summary             = package['description']
9
-  s.description         = package['description']
10
-  s.homepage            = package['homepage']
11
-  s.license             = package['license']
12
-  s.author              = package['author']
13
-  s.source              = { :git => 'https://github.com/yonahforst/react-native-permissions.git', :tag => s.version }
6
+  s.name                   = 'ReactNativePermissions'
7
+  s.version                = package['version']
8
+  s.summary                = package['description']
9
+  s.description            = package['description']
10
+  s.homepage               = package['homepage']
11
+  s.license                = package['license']
12
+  s.author                 = package['author']
13
+  s.source                 = { :git => 'https://github.com/yonahforst/react-native-permissions.git', :tag => s.version }
14
 
14
 
15
-  s.platform              = :ios, '9.0'
16
-  s.ios.deployment_target = '8.0'
15
+  s.platform               = :ios, '9.0'
16
+  s.ios.deployment_target  = '8.0'
17
 
17
 
18
-  s.dependency 'React'
19
-
20
-  s.preserve_paths      = 'docs', 'CHANGELOG.md', 'LICENSE', 'package.json', 'ReactNativePermissions.ios.js'
21
-  s.source_files        = '**/*.{h,m}'
22
-  s.exclude_files       = 'Example/**/*'
18
+  s.preserve_paths         = 'LICENSE', 'package.json'
19
+  s.source_files           = '**/*.{h,m}'
20
+  s.exclude_files          = 'example/**/*'
21
+  s.dependency               'React'
23
 end
22
 end

+ 0
- 7
ReactNativePermissions.xcodeproj/project.xcworkspace/contents.xcworkspacedata View File

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<Workspace
3
-   version = "1.0">
4
-   <FileRef
5
-      location = "self:ReactNativePermissions.xcodeproj">
6
-   </FileRef>
7
-</Workspace>

+ 0
- 80
ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/ReactNativePermissions.xcscheme View File

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<Scheme
3
-   LastUpgradeVersion = "0710"
4
-   version = "1.3">
5
-   <BuildAction
6
-      parallelizeBuildables = "YES"
7
-      buildImplicitDependencies = "YES">
8
-      <BuildActionEntries>
9
-         <BuildActionEntry
10
-            buildForTesting = "YES"
11
-            buildForRunning = "YES"
12
-            buildForProfiling = "YES"
13
-            buildForArchiving = "YES"
14
-            buildForAnalyzing = "YES">
15
-            <BuildableReference
16
-               BuildableIdentifier = "primary"
17
-               BlueprintIdentifier = "9D23B34E1C767B80008B4819"
18
-               BuildableName = "libReactNativePermissions.a"
19
-               BlueprintName = "ReactNativePermissions"
20
-               ReferencedContainer = "container:ReactNativePermissions.xcodeproj">
21
-            </BuildableReference>
22
-         </BuildActionEntry>
23
-      </BuildActionEntries>
24
-   </BuildAction>
25
-   <TestAction
26
-      buildConfiguration = "Debug"
27
-      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
-      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
-      shouldUseLaunchSchemeArgsEnv = "YES">
30
-      <Testables>
31
-      </Testables>
32
-      <AdditionalOptions>
33
-      </AdditionalOptions>
34
-   </TestAction>
35
-   <LaunchAction
36
-      buildConfiguration = "Debug"
37
-      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
38
-      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
39
-      launchStyle = "0"
40
-      useCustomWorkingDirectory = "NO"
41
-      ignoresPersistentStateOnLaunch = "NO"
42
-      debugDocumentVersioning = "YES"
43
-      debugServiceExtension = "internal"
44
-      allowLocationSimulation = "YES">
45
-      <MacroExpansion>
46
-         <BuildableReference
47
-            BuildableIdentifier = "primary"
48
-            BlueprintIdentifier = "9D23B34E1C767B80008B4819"
49
-            BuildableName = "libReactNativePermissions.a"
50
-            BlueprintName = "ReactNativePermissions"
51
-            ReferencedContainer = "container:ReactNativePermissions.xcodeproj">
52
-         </BuildableReference>
53
-      </MacroExpansion>
54
-      <AdditionalOptions>
55
-      </AdditionalOptions>
56
-   </LaunchAction>
57
-   <ProfileAction
58
-      buildConfiguration = "Release"
59
-      shouldUseLaunchSchemeArgsEnv = "YES"
60
-      savedToolIdentifier = ""
61
-      useCustomWorkingDirectory = "NO"
62
-      debugDocumentVersioning = "YES">
63
-      <MacroExpansion>
64
-         <BuildableReference
65
-            BuildableIdentifier = "primary"
66
-            BlueprintIdentifier = "9D23B34E1C767B80008B4819"
67
-            BuildableName = "libReactNativePermissions.a"
68
-            BlueprintName = "ReactNativePermissions"
69
-            ReferencedContainer = "container:ReactNativePermissions.xcodeproj">
70
-         </BuildableReference>
71
-      </MacroExpansion>
72
-   </ProfileAction>
73
-   <AnalyzeAction
74
-      buildConfiguration = "Debug">
75
-   </AnalyzeAction>
76
-   <ArchiveAction
77
-      buildConfiguration = "Release"
78
-      revealArchiveInOrganizer = "YES">
79
-   </ArchiveAction>
80
-</Scheme>

+ 0
- 22
ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/xcschememanagement.plist View File

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
-<plist version="1.0">
4
-<dict>
5
-	<key>SchemeUserState</key>
6
-	<dict>
7
-		<key>ReactNativePermissions.xcscheme</key>
8
-		<dict>
9
-			<key>orderHint</key>
10
-			<integer>0</integer>
11
-		</dict>
12
-	</dict>
13
-	<key>SuppressBuildableAutocreation</key>
14
-	<dict>
15
-		<key>9D23B34E1C767B80008B4819</key>
16
-		<dict>
17
-			<key>primary</key>
18
-			<true/>
19
-		</dict>
20
-	</dict>
21
-</dict>
22
-</plist>

Example/.babelrc → example/.babelrc View File


Example/.buckconfig → example/.buckconfig View File


Example/.flowconfig → example/.flowconfig View File

12
 ; For RN Apps installed via npm, "Libraries" folder is inside
12
 ; For RN Apps installed via npm, "Libraries" folder is inside
13
 ; "node_modules/react-native" but in the source repo it is in the root
13
 ; "node_modules/react-native" but in the source repo it is in the root
14
 .*/Libraries/react-native/React.js
14
 .*/Libraries/react-native/React.js
15
-.*/Libraries/react-native/ReactNative.js
15
+
16
+; Ignore polyfills
17
+.*/Libraries/polyfills/.*
16
 
18
 
17
 [include]
19
 [include]
18
 
20
 
19
 [libs]
21
 [libs]
20
 node_modules/react-native/Libraries/react-native/react-native-interface.js
22
 node_modules/react-native/Libraries/react-native/react-native-interface.js
21
-node_modules/react-native/flow
22
-flow/
23
+node_modules/react-native/flow/
23
 
24
 
24
 [options]
25
 [options]
25
 emoji=true
26
 emoji=true
32
 
33
 
33
 suppress_type=$FlowIssue
34
 suppress_type=$FlowIssue
34
 suppress_type=$FlowFixMe
35
 suppress_type=$FlowFixMe
36
+suppress_type=$FlowFixMeProps
37
+suppress_type=$FlowFixMeState
35
 suppress_type=$FixMe
38
 suppress_type=$FixMe
36
 
39
 
37
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
38
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
40
+suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
41
+suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
39
 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
42
 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
40
 suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
43
 suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
41
 
44
 
42
 unsafe.enable_getters_and_setters=true
45
 unsafe.enable_getters_and_setters=true
43
 
46
 
44
 [version]
47
 [version]
45
-^0.49.1
48
+^0.56.0

Example/.gitattributes → example/.gitattributes View File


Example/.gitignore → example/.gitignore View File

46
 # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46
 # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47
 # screenshots whenever they are needed.
47
 # screenshots whenever they are needed.
48
 # For more information about the recommended setup visit:
48
 # For more information about the recommended setup visit:
49
-# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
49
+# https://docs.fastlane.tools/best-practices/source-control/
50
 
50
 
51
-fastlane/report.xml
52
-fastlane/Preview.html
53
-fastlane/screenshots
51
+*/fastlane/report.xml
52
+*/fastlane/Preview.html
53
+*/fastlane/screenshots

Example/.watchmanconfig → example/.watchmanconfig View File


Example/Example.js → example/App.js View File

1
-/**
2
- * Sample React Native App
3
- * https://github.com/facebook/react-native
4
- * @flow
5
- */
1
+// @flow
6
 
2
 
7
-import React, { Component } from 'react';
3
+import React, { Component } from 'react'
8
 import {
4
 import {
9
   StyleSheet,
5
   StyleSheet,
10
   TouchableHighlight,
6
   TouchableHighlight,
13
   Alert,
9
   Alert,
14
   AppState,
10
   AppState,
15
   Platform,
11
   Platform,
16
-} from 'react-native';
12
+} from 'react-native'
17
 
13
 
18
 import Permissions from 'react-native-permissions'
14
 import Permissions from 'react-native-permissions'
19
 
15
 
20
-export default class Example extends Component {
16
+export default class App extends Component {
21
   state = {
17
   state = {
22
     types: [],
18
     types: [],
23
     status: {},
19
     status: {},
29
 
25
 
30
     this.setState({ types, canOpenSettings })
26
     this.setState({ types, canOpenSettings })
31
     this._updatePermissions(types)
27
     this._updatePermissions(types)
32
-    AppState.addEventListener('change', this._handleAppStateChange.bind(this));
28
+    AppState.addEventListener('change', this._handleAppStateChange)
33
   }
29
   }
34
 
30
 
35
   componentWillUnmount() {
31
   componentWillUnmount() {
36
-    AppState.removeEventListener('change', this._handleAppStateChange.bind(this));
32
+    AppState.removeEventListener('change', this._handleAppStateChange)
37
   }
33
   }
38
 
34
 
39
   //update permissions when app comes back from settings
35
   //update permissions when app comes back from settings
40
-  _handleAppStateChange(appState) {
36
+  _handleAppStateChange = appState => {
41
     if (appState == 'active') {
37
     if (appState == 'active') {
42
       this._updatePermissions(this.state.types)
38
       this._updatePermissions(this.state.types)
43
     }
39
     }
44
   }
40
   }
45
 
41
 
46
-  _openSettings() {
47
-    return Permissions.openSettings()
48
-      .then(() => alert('back to app!!'))
49
-  }
42
+  _openSettings = () =>
43
+    Permissions.openSettings().then(() => alert('back to app!!'))
50
 
44
 
51
-  _updatePermissions(types) {
45
+  _updatePermissions = types => {
52
     Permissions.checkMultiple(types)
46
     Permissions.checkMultiple(types)
53
       .then(status => {
47
       .then(status => {
54
         if (this.state.isAlways) {
48
         if (this.state.isAlways) {
55
-          return Permissions.check('location', 'always')
56
-            .then(location => ({...status, location}))
49
+          return Permissions.check('location', 'always').then(location => ({
50
+            ...status,
51
+            location,
52
+          }))
57
         }
53
         }
58
         return status
54
         return status
59
       })
55
       })
60
       .then(status => this.setState({ status }))
56
       .then(status => this.setState({ status }))
61
   }
57
   }
62
 
58
 
63
-  _requestPermission(permission) {
59
+  _requestPermission = permission => {
64
     var options
60
     var options
65
 
61
 
66
     if (permission == 'location') {
62
     if (permission == 'location') {
70
     Permissions.request(permission, options)
66
     Permissions.request(permission, options)
71
       .then(res => {
67
       .then(res => {
72
         this.setState({
68
         this.setState({
73
-          status: {...this.state.status, [permission]: res}
69
+          status: { ...this.state.status, [permission]: res },
74
         })
70
         })
75
         if (res != 'authorized') {
71
         if (res != 'authorized') {
76
           var buttons = [{ text: 'Cancel', style: 'cancel' }]
72
           var buttons = [{ text: 'Cancel', style: 'cancel' }]
77
-          if (this.state.canOpenSettings) buttons.push({ text: 'Open Settings', onPress: this._openSettings.bind(this) })
78
-          
73
+          if (this.state.canOpenSettings)
74
+            buttons.push({
75
+              text: 'Open Settings',
76
+              onPress: this._openSettings,
77
+            })
78
+
79
           Alert.alert(
79
           Alert.alert(
80
             'Whoops!',
80
             'Whoops!',
81
-            "There was a problem getting your permission. Please enable it from settings.",
82
-            buttons
81
+            'There was a problem getting your permission. Please enable it from settings.',
82
+            buttons,
83
           )
83
           )
84
         }
84
         }
85
-      }).catch(e => console.warn(e))
85
+      })
86
+      .catch(e => console.warn(e))
86
   }
87
   }
87
 
88
 
88
-  _onLocationSwitchChange() {
89
+  _onLocationSwitchChange = () => {
89
     this.setState({ isAlways: !this.state.isAlways })
90
     this.setState({ isAlways: !this.state.isAlways })
90
     this._updatePermissions(this.state.types)
91
     this._updatePermissions(this.state.types)
91
   }
92
   }
93
   render() {
94
   render() {
94
     return (
95
     return (
95
       <View style={styles.container}>
96
       <View style={styles.container}>
96
-
97
         {this.state.types.map(p => (
97
         {this.state.types.map(p => (
98
-          <TouchableHighlight 
98
+          <TouchableHighlight
99
             style={[styles.button, styles[this.state.status[p]]]}
99
             style={[styles.button, styles[this.state.status[p]]]}
100
             key={p}
100
             key={p}
101
-            onPress={this._requestPermission.bind(this, p)}>
101
+            onPress={() => this._requestPermission(p)}
102
+          >
102
             <View>
103
             <View>
103
               <Text style={styles.text}>
104
               <Text style={styles.text}>
104
-                {Platform.OS == 'ios' && p == 'location' ? `location ${this.state.isAlways ? 'always' : 'whenInUse'}` : p}
105
-              </Text>
106
-              <Text style={styles.subtext}>
107
-                {this.state.status[p]}
105
+                {Platform.OS == 'ios' && p == 'location'
106
+                  ? `location ${this.state.isAlways ? 'always' : 'whenInUse'}`
107
+                  : p}
108
               </Text>
108
               </Text>
109
+              <Text style={styles.subtext}>{this.state.status[p]}</Text>
109
             </View>
110
             </View>
110
           </TouchableHighlight>
111
           </TouchableHighlight>
111
-          )
112
-        )}
112
+        ))}
113
         <View style={styles.footer}>
113
         <View style={styles.footer}>
114
-          <TouchableHighlight 
115
-            style={styles['footer_'+Platform.OS]}
116
-            onPress={this._onLocationSwitchChange.bind(this)}>
114
+          <TouchableHighlight
115
+            style={styles['footer_' + Platform.OS]}
116
+            onPress={this._onLocationSwitchChange}
117
+          >
117
             <Text style={styles.text}>Toggle location type</Text>
118
             <Text style={styles.text}>Toggle location type</Text>
118
           </TouchableHighlight>
119
           </TouchableHighlight>
119
-   
120
-          {
121
-            this.state.canOpenSettings &&
122
-            <TouchableHighlight 
123
-              onPress={this._openSettings.bind(this)}>
120
+
121
+          {this.state.canOpenSettings && (
122
+            <TouchableHighlight onPress={this._openSettings}>
124
               <Text style={styles.text}>Open settings</Text>
123
               <Text style={styles.text}>Open settings</Text>
125
             </TouchableHighlight>
124
             </TouchableHighlight>
126
-          }
127
-
125
+          )}
128
         </View>
126
         </View>
129
 
127
 
130
-
131
-        <Text style={styles['footer_'+Platform.OS]}>
132
-          Note: microphone permissions may not work on iOS simulator. Also, toggling permissions from the settings menu may cause the app to crash. This is normal on iOS. Google "ios crash permission change"
128
+        <Text style={styles['footer_' + Platform.OS]}>
129
+          Note: microphone permissions may not work on iOS simulator. Also,
130
+          toggling permissions from the settings menu may cause the app to
131
+          crash. This is normal on iOS. Google "ios crash permission change"
133
         </Text>
132
         </Text>
134
       </View>
133
       </View>
135
-    );
134
+    )
136
   }
135
   }
137
 }
136
 }
138
 
137
 
169
     backgroundColor: '#ef9a9a',
168
     backgroundColor: '#ef9a9a',
170
   },
169
   },
171
   restricted: {
170
   restricted: {
172
-    backgroundColor: '#ef9a9a'
171
+    backgroundColor: '#ef9a9a',
173
   },
172
   },
174
   footer: {
173
   footer: {
175
     padding: 10,
174
     padding: 10,
179
   footer_android: {
178
   footer_android: {
180
     height: 0,
179
     height: 0,
181
     width: 0,
180
     width: 0,
182
-  }
183
-})
181
+  },
182
+})

+ 10
- 0
example/__tests__/index.js View File

1
+import 'react-native'
2
+import React from 'react'
3
+import Index from '../index.js'
4
+
5
+// Note: test renderer must be required after react-native.
6
+import renderer from 'react-test-renderer'
7
+
8
+it('renders correctly', () => {
9
+  const tree = renderer.create(<Index />)
10
+})

Example/android/app/BUCK → example/android/app/BUCK View File


Example/android/app/build.gradle → example/android/app/build.gradle View File

72
  * ]
72
  * ]
73
  */
73
  */
74
 
74
 
75
+project.ext.react = [
76
+    entryFile: "index.js"
77
+]
78
+
75
 apply from: "../../node_modules/react-native/react.gradle"
79
 apply from: "../../node_modules/react-native/react.gradle"
76
 
80
 
77
 /**
81
 /**
95
 
99
 
96
     defaultConfig {
100
     defaultConfig {
97
         applicationId "com.example"
101
         applicationId "com.example"
98
-        minSdkVersion 21
102
+        minSdkVersion 16
99
         targetSdkVersion 23
103
         targetSdkVersion 23
100
         versionCode 1
104
         versionCode 1
101
         versionName "1.0"
105
         versionName "1.0"

Example/android/app/proguard-rules.pro → example/android/app/proguard-rules.pro View File


Example/android/app/src/main/AndroidManifest.xml → example/android/app/src/main/AndroidManifest.xml View File

8
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
8
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
9
     <uses-permission android:name="android.permission.CAMERA"/>
9
     <uses-permission android:name="android.permission.CAMERA"/>
10
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
10
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
11
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
11
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
12
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
12
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
13
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
13
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
14
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
15
     <uses-permission android:name="android.permission.READ_SMS"/>
16
     <uses-permission android:name="android.permission.READ_SMS"/>
16
     <uses-permission android:name="android.permission.RECEIVE_SMS"/>
17
     <uses-permission android:name="android.permission.RECEIVE_SMS"/>
17
 
18
 
19
+    <uses-sdk
20
+        android:minSdkVersion="16"
21
+        android:targetSdkVersion="23" />
22
+
18
     <application
23
     <application
19
       android:name=".MainApplication"
24
       android:name=".MainApplication"
20
-      android:allowBackup="true"
25
+      android:allowBackup="false"
21
       android:label="@string/app_name"
26
       android:label="@string/app_name"
22
       android:icon="@mipmap/ic_launcher"
27
       android:icon="@mipmap/ic_launcher"
23
       android:theme="@style/AppTheme">
28
       android:theme="@style/AppTheme">

Example/android/app/src/main/java/com/example/MainActivity.java → example/android/app/src/main/java/com/example/MainActivity.java View File


Example/android/app/src/main/java/com/example/MainApplication.java → example/android/app/src/main/java/com/example/MainApplication.java View File

25
           new MainReactPackage()
25
           new MainReactPackage()
26
       );
26
       );
27
     }
27
     }
28
+
29
+    @Override
30
+    protected String getJSMainModuleName() {
31
+      return "index";
32
+    }
28
   };
33
   };
29
 
34
 
30
   @Override
35
   @Override

Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png → example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png View File


Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png → example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png View File


Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png → example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png View File


Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png → example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png View File


Example/android/app/src/main/res/values/strings.xml → example/android/app/src/main/res/values/strings.xml View File

1
 <resources>
1
 <resources>
2
-
3
     <string name="app_name">Example</string>
2
     <string name="app_name">Example</string>
4
 </resources>
3
 </resources>

Example/android/app/src/main/res/values/styles.xml → example/android/app/src/main/res/values/styles.xml View File


Example/android/build.gradle → example/android/build.gradle View File

6
     }
6
     }
7
     dependencies {
7
     dependencies {
8
         classpath 'com.android.tools.build:gradle:2.2.3'
8
         classpath 'com.android.tools.build:gradle:2.2.3'
9
+
9
         // NOTE: Do not place your application dependencies here; they belong
10
         // NOTE: Do not place your application dependencies here; they belong
10
         // in the individual module build.gradle files
11
         // in the individual module build.gradle files
11
     }
12
     }

Example/android/gradle.properties → example/android/gradle.properties View File


Example/android/gradle/wrapper/gradle-wrapper.jar → example/android/gradle/wrapper/gradle-wrapper.jar View File


Example/android/gradle/wrapper/gradle-wrapper.properties → example/android/gradle/wrapper/gradle-wrapper.properties View File

1
-#Fri Feb 03 16:27:32 CET 2017
2
 distributionBase=GRADLE_USER_HOME
1
 distributionBase=GRADLE_USER_HOME
3
 distributionPath=wrapper/dists
2
 distributionPath=wrapper/dists
4
 zipStoreBase=GRADLE_USER_HOME
3
 zipStoreBase=GRADLE_USER_HOME
5
 zipStorePath=wrapper/dists
4
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
5
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

Example/android/gradlew → example/android/gradlew View File


Example/android/gradlew.bat → example/android/gradlew.bat View File


Example/android/keystores/BUCK → example/android/keystores/BUCK View File


Example/android/keystores/debug.keystore.properties → example/android/keystores/debug.keystore.properties View File


Example/android/settings.gradle → example/android/settings.gradle View File


+ 4
- 0
example/app.json View File

1
+{
2
+  "name": "Example",
3
+  "displayName": "Example"
4
+}

+ 4
- 0
example/index.js View File

1
+import { AppRegistry } from 'react-native'
2
+import App from './App'
3
+
4
+AppRegistry.registerComponent('Example', () => App)

Example/ios/Example-tvOS/Info.plist → example/ios/Example-tvOS/Info.plist View File


Example/ios/Example-tvOSTests/Info.plist → example/ios/Example-tvOSTests/Info.plist View File


Example/ios/Example.xcodeproj/project.pbxproj → example/ios/Example.xcodeproj/project.pbxproj View File

25
 		2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
25
 		2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
26
 		2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
26
 		2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
27
 		2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
27
 		2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
28
-		2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */; };
28
+		2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
29
 		2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
29
 		2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
30
 		2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
30
 		2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
31
 		2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
31
 		2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
35
 		2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
35
 		2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
36
 		2DCD954D1E0B4F2C00145EB5 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ExampleTests.m */; };
36
 		2DCD954D1E0B4F2C00145EB5 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ExampleTests.m */; };
37
 		5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
37
 		5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
38
-		6D05A8F55CC4482AACFFC932 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DF4131A2930454297EF564B /* libReactNativePermissions.a */; };
38
+		66AE23241FE44648000AEC3F /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66AE23231FE44628000AEC3F /* libReactNativePermissions.a */; };
39
 		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
39
 		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
40
 		ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; };
40
 		ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; };
41
 /* End PBXBuildFile section */
41
 /* End PBXBuildFile section */
216
 			remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
216
 			remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
217
 			remoteInfo = "RCTAnimation-tvOS";
217
 			remoteInfo = "RCTAnimation-tvOS";
218
 		};
218
 		};
219
+		661E35331FD3107F00C328EA /* PBXContainerItemProxy */ = {
220
+			isa = PBXContainerItemProxy;
221
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
222
+			proxyType = 2;
223
+			remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
224
+			remoteInfo = "third-party";
225
+		};
226
+		661E35351FD3107F00C328EA /* PBXContainerItemProxy */ = {
227
+			isa = PBXContainerItemProxy;
228
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
229
+			proxyType = 2;
230
+			remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
231
+			remoteInfo = "third-party-tvOS";
232
+		};
233
+		661E35371FD3107F00C328EA /* PBXContainerItemProxy */ = {
234
+			isa = PBXContainerItemProxy;
235
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
236
+			proxyType = 2;
237
+			remoteGlobalIDString = 139D7E881E25C6D100323FB7;
238
+			remoteInfo = "double-conversion";
239
+		};
240
+		661E35391FD3107F00C328EA /* PBXContainerItemProxy */ = {
241
+			isa = PBXContainerItemProxy;
242
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
243
+			proxyType = 2;
244
+			remoteGlobalIDString = 3D383D621EBD27B9005632C8;
245
+			remoteInfo = "double-conversion-tvOS";
246
+		};
247
+		661E353B1FD3107F00C328EA /* PBXContainerItemProxy */ = {
248
+			isa = PBXContainerItemProxy;
249
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
250
+			proxyType = 2;
251
+			remoteGlobalIDString = 9936F3131F5F2E4B0010BF04;
252
+			remoteInfo = privatedata;
253
+		};
254
+		661E353D1FD3107F00C328EA /* PBXContainerItemProxy */ = {
255
+			isa = PBXContainerItemProxy;
256
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
257
+			proxyType = 2;
258
+			remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04;
259
+			remoteInfo = "privatedata-tvOS";
260
+		};
261
+		66AE23221FE44628000AEC3F /* PBXContainerItemProxy */ = {
262
+			isa = PBXContainerItemProxy;
263
+			containerPortal = 14B7951690F04106A4A8E60E /* ReactNativePermissions.xcodeproj */;
264
+			proxyType = 2;
265
+			remoteGlobalIDString = 9D23B34F1C767B80008B4819;
266
+			remoteInfo = ReactNativePermissions;
267
+		};
268
+		66F16BED1FC608A800E71FEB /* PBXContainerItemProxy */ = {
269
+			isa = PBXContainerItemProxy;
270
+			containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
271
+			proxyType = 2;
272
+			remoteGlobalIDString = ADD01A681E09402E00F6D226;
273
+			remoteInfo = "RCTBlob-tvOS";
274
+		};
275
+		66F16BFF1FC608A800E71FEB /* PBXContainerItemProxy */ = {
276
+			isa = PBXContainerItemProxy;
277
+			containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
278
+			proxyType = 2;
279
+			remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
280
+			remoteInfo = fishhook;
281
+		};
282
+		66F16C011FC608A800E71FEB /* PBXContainerItemProxy */ = {
283
+			isa = PBXContainerItemProxy;
284
+			containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
285
+			proxyType = 2;
286
+			remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
287
+			remoteInfo = "fishhook-tvOS";
288
+		};
219
 		78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
289
 		78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
220
 			isa = PBXContainerItemProxy;
290
 			isa = PBXContainerItemProxy;
221
 			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
291
 			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
259
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; };
329
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; };
260
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; };
330
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; };
261
 		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
331
 		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
262
-		1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
332
+		14B7951690F04106A4A8E60E /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
263
 		2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
333
 		2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
264
 		2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
334
 		2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
265
-		5DF4131A2930454297EF564B /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = "<group>"; };
266
 		5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
335
 		5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
267
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
336
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
268
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
337
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
295
 				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
364
 				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
296
 				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
365
 				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
297
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
366
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
298
-				6D05A8F55CC4482AACFFC932 /* libReactNativePermissions.a in Frameworks */,
367
+				66AE23241FE44648000AEC3F /* libReactNativePermissions.a in Frameworks */,
299
 			);
368
 			);
300
 			runOnlyForDeploymentPostprocessing = 0;
369
 			runOnlyForDeploymentPostprocessing = 0;
301
 		};
370
 		};
304
 			buildActionMask = 2147483647;
373
 			buildActionMask = 2147483647;
305
 			files = (
374
 			files = (
306
 				2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */,
375
 				2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */,
307
-				2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */,
376
+				2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */,
308
 				2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,
377
 				2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,
309
 				2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,
378
 				2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,
310
 				2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,
379
 				2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,
397
 			children = (
466
 			children = (
398
 				139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
467
 				139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
399
 				3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
468
 				3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
469
+				66F16C001FC608A800E71FEB /* libfishhook.a */,
470
+				66F16C021FC608A800E71FEB /* libfishhook-tvOS.a */,
400
 			);
471
 			);
401
 			name = Products;
472
 			name = Products;
402
 			sourceTree = "<group>";
473
 			sourceTree = "<group>";
426
 				3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
497
 				3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
427
 				3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
498
 				3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
428
 				3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
499
 				3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
429
-				3DAD3EA31DF850E9000B6D8A /* libReact-tvOS.a */,
500
+				661E35341FD3107F00C328EA /* libthird-party.a */,
501
+				661E35361FD3107F00C328EA /* libthird-party.a */,
502
+				661E35381FD3107F00C328EA /* libdouble-conversion.a */,
503
+				661E353A1FD3107F00C328EA /* libdouble-conversion.a */,
504
+				661E353C1FD3107F00C328EA /* libprivatedata.a */,
505
+				661E353E1FD3107F00C328EA /* libprivatedata-tvOS.a */,
430
 			);
506
 			);
431
 			name = Products;
507
 			name = Products;
432
 			sourceTree = "<group>";
508
 			sourceTree = "<group>";
435
 			isa = PBXGroup;
511
 			isa = PBXGroup;
436
 			children = (
512
 			children = (
437
 				5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
513
 				5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
438
-				5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
514
+				5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,
439
 			);
515
 			);
440
 			name = Products;
516
 			name = Products;
441
 			sourceTree = "<group>";
517
 			sourceTree = "<group>";
442
 		};
518
 		};
519
+		66AE22FC1FE44628000AEC3F /* Products */ = {
520
+			isa = PBXGroup;
521
+			children = (
522
+				66AE23231FE44628000AEC3F /* libReactNativePermissions.a */,
523
+			);
524
+			name = Products;
525
+			sourceTree = "<group>";
526
+		};
527
+		66F16C081FC608C600E71FEB /* Frameworks */ = {
528
+			isa = PBXGroup;
529
+			children = (
530
+			);
531
+			name = Frameworks;
532
+			sourceTree = "<group>";
533
+		};
443
 		78C398B11ACF4ADC00677621 /* Products */ = {
534
 		78C398B11ACF4ADC00677621 /* Products */ = {
444
 			isa = PBXGroup;
535
 			isa = PBXGroup;
445
 			children = (
536
 			children = (
464
 				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
555
 				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
465
 				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
556
 				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
466
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
557
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
467
-				1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */,
558
+				14B7951690F04106A4A8E60E /* ReactNativePermissions.xcodeproj */,
468
 			);
559
 			);
469
 			name = Libraries;
560
 			name = Libraries;
470
 			sourceTree = "<group>";
561
 			sourceTree = "<group>";
485
 				832341AE1AAA6A7D00B99B32 /* Libraries */,
576
 				832341AE1AAA6A7D00B99B32 /* Libraries */,
486
 				00E356EF1AD99517003FC87E /* ExampleTests */,
577
 				00E356EF1AD99517003FC87E /* ExampleTests */,
487
 				83CBBA001A601CBA00E9B192 /* Products */,
578
 				83CBBA001A601CBA00E9B192 /* Products */,
579
+				66F16C081FC608C600E71FEB /* Frameworks */,
488
 			);
580
 			);
489
 			indentWidth = 2;
581
 			indentWidth = 2;
490
 			sourceTree = "<group>";
582
 			sourceTree = "<group>";
506
 			isa = PBXGroup;
598
 			isa = PBXGroup;
507
 			children = (
599
 			children = (
508
 				ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,
600
 				ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,
601
+				66F16BEE1FC608A800E71FEB /* libRCTBlob-tvOS.a */,
509
 			);
602
 			);
510
 			name = Products;
603
 			name = Products;
511
 			sourceTree = "<group>";
604
 			sourceTree = "<group>";
591
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
684
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
592
 			isa = PBXProject;
685
 			isa = PBXProject;
593
 			attributes = {
686
 			attributes = {
594
-				LastUpgradeCheck = 820;
687
+				LastUpgradeCheck = 610;
595
 				ORGANIZATIONNAME = Facebook;
688
 				ORGANIZATIONNAME = Facebook;
596
 				TargetAttributes = {
689
 				TargetAttributes = {
597
 					00E356ED1AD99517003FC87E = {
690
 					00E356ED1AD99517003FC87E = {
598
 						CreatedOnToolsVersion = 6.2;
691
 						CreatedOnToolsVersion = 6.2;
599
-						DevelopmentTeam = 66SW7BQ2SM;
692
+						DevelopmentTeam = 745449BDR9;
600
 						TestTargetID = 13B07F861A680F5B00A75B9A;
693
 						TestTargetID = 13B07F861A680F5B00A75B9A;
601
 					};
694
 					};
602
 					13B07F861A680F5B00A75B9A = {
695
 					13B07F861A680F5B00A75B9A = {
603
-						DevelopmentTeam = 66SW7BQ2SM;
696
+						DevelopmentTeam = 745449BDR9;
604
 						SystemCapabilities = {
697
 						SystemCapabilities = {
605
 							com.apple.BackgroundModes = {
698
 							com.apple.BackgroundModes = {
606
 								enabled = 1;
699
 								enabled = 1;
679
 					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
772
 					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
680
 				},
773
 				},
681
 				{
774
 				{
682
-					ProductGroup = 9D140C9F1F068EB400146F6C /* Products */;
683
-					ProjectRef = 1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */;
775
+					ProductGroup = 66AE22FC1FE44628000AEC3F /* Products */;
776
+					ProjectRef = 14B7951690F04106A4A8E60E /* ReactNativePermissions.xcodeproj */;
684
 				},
777
 				},
685
 			);
778
 			);
686
 			projectRoot = "";
779
 			projectRoot = "";
792
 			remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;
885
 			remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;
793
 			sourceTree = BUILT_PRODUCTS_DIR;
886
 			sourceTree = BUILT_PRODUCTS_DIR;
794
 		};
887
 		};
795
-		3DAD3EA31DF850E9000B6D8A /* libReact-tvOS.a */ = {
888
+		3DAD3EA31DF850E9000B6D8A /* libReact.a */ = {
796
 			isa = PBXReferenceProxy;
889
 			isa = PBXReferenceProxy;
797
 			fileType = archive.ar;
890
 			fileType = archive.ar;
798
-			path = "libReact-tvOS.a";
891
+			path = libReact.a;
799
 			remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;
892
 			remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;
800
 			sourceTree = BUILT_PRODUCTS_DIR;
893
 			sourceTree = BUILT_PRODUCTS_DIR;
801
 		};
894
 		};
848
 			remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
941
 			remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
849
 			sourceTree = BUILT_PRODUCTS_DIR;
942
 			sourceTree = BUILT_PRODUCTS_DIR;
850
 		};
943
 		};
851
-		5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
944
+		5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
852
 			isa = PBXReferenceProxy;
945
 			isa = PBXReferenceProxy;
853
 			fileType = archive.ar;
946
 			fileType = archive.ar;
854
-			path = "libRCTAnimation-tvOS.a";
947
+			path = libRCTAnimation.a;
855
 			remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
948
 			remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
856
 			sourceTree = BUILT_PRODUCTS_DIR;
949
 			sourceTree = BUILT_PRODUCTS_DIR;
857
 		};
950
 		};
951
+		661E35341FD3107F00C328EA /* libthird-party.a */ = {
952
+			isa = PBXReferenceProxy;
953
+			fileType = archive.ar;
954
+			path = "libthird-party.a";
955
+			remoteRef = 661E35331FD3107F00C328EA /* PBXContainerItemProxy */;
956
+			sourceTree = BUILT_PRODUCTS_DIR;
957
+		};
958
+		661E35361FD3107F00C328EA /* libthird-party.a */ = {
959
+			isa = PBXReferenceProxy;
960
+			fileType = archive.ar;
961
+			path = "libthird-party.a";
962
+			remoteRef = 661E35351FD3107F00C328EA /* PBXContainerItemProxy */;
963
+			sourceTree = BUILT_PRODUCTS_DIR;
964
+		};
965
+		661E35381FD3107F00C328EA /* libdouble-conversion.a */ = {
966
+			isa = PBXReferenceProxy;
967
+			fileType = archive.ar;
968
+			path = "libdouble-conversion.a";
969
+			remoteRef = 661E35371FD3107F00C328EA /* PBXContainerItemProxy */;
970
+			sourceTree = BUILT_PRODUCTS_DIR;
971
+		};
972
+		661E353A1FD3107F00C328EA /* libdouble-conversion.a */ = {
973
+			isa = PBXReferenceProxy;
974
+			fileType = archive.ar;
975
+			path = "libdouble-conversion.a";
976
+			remoteRef = 661E35391FD3107F00C328EA /* PBXContainerItemProxy */;
977
+			sourceTree = BUILT_PRODUCTS_DIR;
978
+		};
979
+		661E353C1FD3107F00C328EA /* libprivatedata.a */ = {
980
+			isa = PBXReferenceProxy;
981
+			fileType = archive.ar;
982
+			path = libprivatedata.a;
983
+			remoteRef = 661E353B1FD3107F00C328EA /* PBXContainerItemProxy */;
984
+			sourceTree = BUILT_PRODUCTS_DIR;
985
+		};
986
+		661E353E1FD3107F00C328EA /* libprivatedata-tvOS.a */ = {
987
+			isa = PBXReferenceProxy;
988
+			fileType = archive.ar;
989
+			path = "libprivatedata-tvOS.a";
990
+			remoteRef = 661E353D1FD3107F00C328EA /* PBXContainerItemProxy */;
991
+			sourceTree = BUILT_PRODUCTS_DIR;
992
+		};
993
+		66AE23231FE44628000AEC3F /* libReactNativePermissions.a */ = {
994
+			isa = PBXReferenceProxy;
995
+			fileType = archive.ar;
996
+			path = libReactNativePermissions.a;
997
+			remoteRef = 66AE23221FE44628000AEC3F /* PBXContainerItemProxy */;
998
+			sourceTree = BUILT_PRODUCTS_DIR;
999
+		};
1000
+		66F16BEE1FC608A800E71FEB /* libRCTBlob-tvOS.a */ = {
1001
+			isa = PBXReferenceProxy;
1002
+			fileType = archive.ar;
1003
+			path = "libRCTBlob-tvOS.a";
1004
+			remoteRef = 66F16BED1FC608A800E71FEB /* PBXContainerItemProxy */;
1005
+			sourceTree = BUILT_PRODUCTS_DIR;
1006
+		};
1007
+		66F16C001FC608A800E71FEB /* libfishhook.a */ = {
1008
+			isa = PBXReferenceProxy;
1009
+			fileType = archive.ar;
1010
+			path = libfishhook.a;
1011
+			remoteRef = 66F16BFF1FC608A800E71FEB /* PBXContainerItemProxy */;
1012
+			sourceTree = BUILT_PRODUCTS_DIR;
1013
+		};
1014
+		66F16C021FC608A800E71FEB /* libfishhook-tvOS.a */ = {
1015
+			isa = PBXReferenceProxy;
1016
+			fileType = archive.ar;
1017
+			path = "libfishhook-tvOS.a";
1018
+			remoteRef = 66F16C011FC608A800E71FEB /* PBXContainerItemProxy */;
1019
+			sourceTree = BUILT_PRODUCTS_DIR;
1020
+		};
858
 		78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
1021
 		78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
859
 			isa = PBXReferenceProxy;
1022
 			isa = PBXReferenceProxy;
860
 			fileType = archive.ar;
1023
 			fileType = archive.ar;
1010
 			isa = XCBuildConfiguration;
1173
 			isa = XCBuildConfiguration;
1011
 			buildSettings = {
1174
 			buildSettings = {
1012
 				BUNDLE_LOADER = "$(TEST_HOST)";
1175
 				BUNDLE_LOADER = "$(TEST_HOST)";
1013
-				DEVELOPMENT_TEAM = 66SW7BQ2SM;
1176
+				DEVELOPMENT_TEAM = 745449BDR9;
1014
 				GCC_PREPROCESSOR_DEFINITIONS = (
1177
 				GCC_PREPROCESSOR_DEFINITIONS = (
1015
 					"DEBUG=1",
1178
 					"DEBUG=1",
1016
 					"$(inherited)",
1179
 					"$(inherited)",
1017
 				);
1180
 				);
1181
+				HEADER_SEARCH_PATHS = (
1182
+					"$(inherited)",
1183
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1184
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1185
+				);
1018
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1186
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1019
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1187
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1020
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1188
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1021
 				LIBRARY_SEARCH_PATHS = (
1189
 				LIBRARY_SEARCH_PATHS = (
1022
 					"$(inherited)",
1190
 					"$(inherited)",
1023
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1191
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1024
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1025
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1026
 				);
1192
 				);
1027
 				OTHER_LDFLAGS = (
1193
 				OTHER_LDFLAGS = (
1028
 					"-ObjC",
1194
 					"-ObjC",
1038
 			buildSettings = {
1204
 			buildSettings = {
1039
 				BUNDLE_LOADER = "$(TEST_HOST)";
1205
 				BUNDLE_LOADER = "$(TEST_HOST)";
1040
 				COPY_PHASE_STRIP = NO;
1206
 				COPY_PHASE_STRIP = NO;
1041
-				DEVELOPMENT_TEAM = 66SW7BQ2SM;
1207
+				DEVELOPMENT_TEAM = 745449BDR9;
1208
+				HEADER_SEARCH_PATHS = (
1209
+					"$(inherited)",
1210
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1211
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1212
+				);
1042
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1213
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1043
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1214
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1044
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1215
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1045
 				LIBRARY_SEARCH_PATHS = (
1216
 				LIBRARY_SEARCH_PATHS = (
1046
 					"$(inherited)",
1217
 					"$(inherited)",
1047
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1218
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1048
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1049
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1050
 				);
1219
 				);
1051
 				OTHER_LDFLAGS = (
1220
 				OTHER_LDFLAGS = (
1052
 					"-ObjC",
1221
 					"-ObjC",
1063
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1232
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1064
 				CURRENT_PROJECT_VERSION = 1;
1233
 				CURRENT_PROJECT_VERSION = 1;
1065
 				DEAD_CODE_STRIPPING = NO;
1234
 				DEAD_CODE_STRIPPING = NO;
1066
-				DEVELOPMENT_TEAM = 66SW7BQ2SM;
1235
+				DEVELOPMENT_TEAM = 745449BDR9;
1236
+				HEADER_SEARCH_PATHS = (
1237
+					"$(inherited)",
1238
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1239
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1240
+				);
1067
 				INFOPLIST_FILE = Example/Info.plist;
1241
 				INFOPLIST_FILE = Example/Info.plist;
1068
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1242
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1069
 				OTHER_LDFLAGS = (
1243
 				OTHER_LDFLAGS = (
1071
 					"-ObjC",
1245
 					"-ObjC",
1072
 					"-lc++",
1246
 					"-lc++",
1073
 				);
1247
 				);
1248
+				PRODUCT_BUNDLE_IDENTIFIER = com.react.permissions;
1074
 				PRODUCT_NAME = Example;
1249
 				PRODUCT_NAME = Example;
1075
 				VERSIONING_SYSTEM = "apple-generic";
1250
 				VERSIONING_SYSTEM = "apple-generic";
1076
 			};
1251
 			};
1081
 			buildSettings = {
1256
 			buildSettings = {
1082
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1257
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1083
 				CURRENT_PROJECT_VERSION = 1;
1258
 				CURRENT_PROJECT_VERSION = 1;
1084
-				DEVELOPMENT_TEAM = 66SW7BQ2SM;
1259
+				DEVELOPMENT_TEAM = 745449BDR9;
1260
+				HEADER_SEARCH_PATHS = (
1261
+					"$(inherited)",
1262
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1263
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1264
+				);
1085
 				INFOPLIST_FILE = Example/Info.plist;
1265
 				INFOPLIST_FILE = Example/Info.plist;
1086
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1266
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1087
 				OTHER_LDFLAGS = (
1267
 				OTHER_LDFLAGS = (
1089
 					"-ObjC",
1269
 					"-ObjC",
1090
 					"-lc++",
1270
 					"-lc++",
1091
 				);
1271
 				);
1272
+				PRODUCT_BUNDLE_IDENTIFIER = com.react.permissions;
1092
 				PRODUCT_NAME = Example;
1273
 				PRODUCT_NAME = Example;
1093
 				VERSIONING_SYSTEM = "apple-generic";
1274
 				VERSIONING_SYSTEM = "apple-generic";
1094
 			};
1275
 			};
1106
 				DEBUG_INFORMATION_FORMAT = dwarf;
1287
 				DEBUG_INFORMATION_FORMAT = dwarf;
1107
 				ENABLE_TESTABILITY = YES;
1288
 				ENABLE_TESTABILITY = YES;
1108
 				GCC_NO_COMMON_BLOCKS = YES;
1289
 				GCC_NO_COMMON_BLOCKS = YES;
1290
+				HEADER_SEARCH_PATHS = (
1291
+					"$(inherited)",
1292
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1293
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1294
+				);
1109
 				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1295
 				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1110
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1296
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1111
 				LIBRARY_SEARCH_PATHS = (
1297
 				LIBRARY_SEARCH_PATHS = (
1112
 					"$(inherited)",
1298
 					"$(inherited)",
1113
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1299
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1114
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1115
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1116
 				);
1300
 				);
1117
 				OTHER_LDFLAGS = (
1301
 				OTHER_LDFLAGS = (
1118
 					"-ObjC",
1302
 					"-ObjC",
1138
 				COPY_PHASE_STRIP = NO;
1322
 				COPY_PHASE_STRIP = NO;
1139
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1323
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1140
 				GCC_NO_COMMON_BLOCKS = YES;
1324
 				GCC_NO_COMMON_BLOCKS = YES;
1325
+				HEADER_SEARCH_PATHS = (
1326
+					"$(inherited)",
1327
+					"$(SRCROOT)/../node_modules/react-native-permissions",
1328
+					"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
1329
+				);
1141
 				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1330
 				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1142
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1331
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1143
 				LIBRARY_SEARCH_PATHS = (
1332
 				LIBRARY_SEARCH_PATHS = (
1144
 					"$(inherited)",
1333
 					"$(inherited)",
1145
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1334
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1146
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1147
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1148
 				);
1335
 				);
1149
 				OTHER_LDFLAGS = (
1336
 				OTHER_LDFLAGS = (
1150
 					"-ObjC",
1337
 					"-ObjC",
1174
 				LIBRARY_SEARCH_PATHS = (
1361
 				LIBRARY_SEARCH_PATHS = (
1175
 					"$(inherited)",
1362
 					"$(inherited)",
1176
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1363
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1177
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1178
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1179
 				);
1364
 				);
1180
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1365
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1181
 				PRODUCT_NAME = "$(TARGET_NAME)";
1366
 				PRODUCT_NAME = "$(TARGET_NAME)";
1201
 				LIBRARY_SEARCH_PATHS = (
1386
 				LIBRARY_SEARCH_PATHS = (
1202
 					"$(inherited)",
1387
 					"$(inherited)",
1203
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1388
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1204
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1205
-					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1206
 				);
1389
 				);
1207
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1390
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1208
 				PRODUCT_NAME = "$(TARGET_NAME)";
1391
 				PRODUCT_NAME = "$(TARGET_NAME)";

Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme → example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme View File


Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme → example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme View File

1
 <?xml version="1.0" encoding="UTF-8"?>
1
 <?xml version="1.0" encoding="UTF-8"?>
2
 <Scheme
2
 <Scheme
3
-   LastUpgradeVersion = "0820"
3
+   LastUpgradeVersion = "0620"
4
    version = "1.3">
4
    version = "1.3">
5
    <BuildAction
5
    <BuildAction
6
       parallelizeBuildables = "NO"
6
       parallelizeBuildables = "NO"

Example/ios/Example/AppDelegate.h → example/ios/Example/AppDelegate.h View File


Example/ios/Example/AppDelegate.m → example/ios/Example/AppDelegate.m View File

18
 {
18
 {
19
   NSURL *jsCodeLocation;
19
   NSURL *jsCodeLocation;
20
 
20
 
21
-  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
21
+  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
22
 
22
 
23
   RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
23
   RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
24
                                                       moduleName:@"Example"
24
                                                       moduleName:@"Example"

Example/ios/Example/Base.lproj/LaunchScreen.xib → example/ios/Example/Base.lproj/LaunchScreen.xib View File


+ 38
- 0
example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json View File

1
+{
2
+  "images": [
3
+    {
4
+      "idiom": "iphone",
5
+      "size": "29x29",
6
+      "scale": "2x"
7
+    },
8
+    {
9
+      "idiom": "iphone",
10
+      "size": "29x29",
11
+      "scale": "3x"
12
+    },
13
+    {
14
+      "idiom": "iphone",
15
+      "size": "40x40",
16
+      "scale": "2x"
17
+    },
18
+    {
19
+      "idiom": "iphone",
20
+      "size": "40x40",
21
+      "scale": "3x"
22
+    },
23
+    {
24
+      "idiom": "iphone",
25
+      "size": "60x60",
26
+      "scale": "2x"
27
+    },
28
+    {
29
+      "idiom": "iphone",
30
+      "size": "60x60",
31
+      "scale": "3x"
32
+    }
33
+  ],
34
+  "info": {
35
+    "version": 1,
36
+    "author": "xcode"
37
+  }
38
+}

+ 6
- 0
example/ios/Example/Images.xcassets/Contents.json View File

1
+{
2
+  "info": {
3
+    "version": 1,
4
+    "author": "xcode"
5
+  }
6
+}

Example/ios/Example/Info.plist → example/ios/Example/Info.plist View File

4
 <dict>
4
 <dict>
5
 	<key>CFBundleDevelopmentRegion</key>
5
 	<key>CFBundleDevelopmentRegion</key>
6
 	<string>en</string>
6
 	<string>en</string>
7
+	<key>CFBundleDisplayName</key>
8
+	<string>Example</string>
7
 	<key>CFBundleExecutable</key>
9
 	<key>CFBundleExecutable</key>
8
 	<string>$(EXECUTABLE_NAME)</string>
10
 	<string>$(EXECUTABLE_NAME)</string>
9
 	<key>CFBundleIdentifier</key>
11
 	<key>CFBundleIdentifier</key>
10
-	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
12
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+	<key>CFBundleInfoDictionaryVersion</key>
14
+	<string>6.0</string>
11
 	<key>CFBundleName</key>
15
 	<key>CFBundleName</key>
12
 	<string>$(PRODUCT_NAME)</string>
16
 	<string>$(PRODUCT_NAME)</string>
13
 	<key>CFBundlePackageType</key>
17
 	<key>CFBundlePackageType</key>

Example/ios/Example/main.m → example/ios/Example/main.m View File


Example/ios/ExampleTests/ExampleTests.m → example/ios/ExampleTests/ExampleTests.m View File


Example/ios/ExampleTests/Info.plist → example/ios/ExampleTests/Info.plist View File


+ 23
- 0
example/package.json View File

1
+{
2
+  "name": "Example",
3
+  "version": "0.0.1",
4
+  "private": true,
5
+  "scripts": {
6
+    "start": "node node_modules/react-native/local-cli/cli.js start",
7
+    "test": "jest"
8
+  },
9
+  "dependencies": {
10
+    "react": "16.0.0",
11
+    "react-native": "0.50.3",
12
+    "react-native-permissions": "../"
13
+  },
14
+  "devDependencies": {
15
+    "babel-jest": "21.2.0",
16
+    "babel-preset-react-native": "4.0.0",
17
+    "jest": "21.2.1",
18
+    "react-test-renderer": "16.0.0"
19
+  },
20
+  "jest": {
21
+    "preset": "react-native"
22
+  }
23
+}

+ 0
- 91
index.android.js View File

1
-'use strict';
2
-
3
-const ReactNative = require('react-native')
4
-const RNPermissions = ReactNative.PermissionsAndroid;
5
-const AsyncStorage = ReactNative.AsyncStorage
6
-
7
-const RNPTypes = {
8
-	location: RNPermissions.PERMISSIONS.ACCESS_FINE_LOCATION,
9
-	camera: RNPermissions.PERMISSIONS.CAMERA,
10
-	microphone: RNPermissions.PERMISSIONS.RECORD_AUDIO,
11
-	contacts: RNPermissions.PERMISSIONS.READ_CONTACTS,
12
-	event: RNPermissions.PERMISSIONS.READ_CALENDAR,
13
-	storage: RNPermissions.PERMISSIONS.READ_EXTERNAL_STORAGE,
14
-	photo: RNPermissions.PERMISSIONS.READ_EXTERNAL_STORAGE,
15
-	callPhone: RNPermissions.PERMISSIONS.CALL_PHONE,
16
-	readSms: RNPermissions.PERMISSIONS.READ_SMS,
17
-	receiveSms: RNPermissions.PERMISSIONS.RECEIVE_SMS,
18
-}
19
-
20
-const RESULTS = {
21
-	[ RNPermissions.RESULTS.GRANTED ]: 'authorized',
22
-	[ RNPermissions.RESULTS.DENIED ]: 'denied',
23
-	[ RNPermissions.RESULTS.NEVER_ASK_AGAIN ]: 'restricted',
24
-}
25
-
26
-const STORAGE_KEY = '@RNPermissions:didAskPermission:'
27
-
28
-const setDidAskOnce = p => AsyncStorage.setItem(STORAGE_KEY + p, 'true')
29
-const getDidAskOnce = p =>  AsyncStorage.getItem(STORAGE_KEY + p).then(res => !!res)
30
-
31
-class ReactNativePermissions {
32
-	canOpenSettings() {
33
-		return false
34
-	}
35
-
36
-	openSettings() {
37
-		return Promise.reject('\'openSettings\' is Depricated on android')
38
-	}
39
-
40
-	getTypes() {
41
-		return Object.keys(RNPTypes);
42
-	}
43
-
44
-	check(permission) {
45
-		const androidPermission = RNPTypes[permission]
46
-  	if (!androidPermission) return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on Android`);
47
-		
48
-		const shouldShowRationale = ReactNative.NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale;
49
-
50
-		return RNPermissions.check(androidPermission)
51
-			.then(isAuthorized => {
52
-				if (isAuthorized) return 'authorized'
53
-
54
-				return getDidAskOnce(permission)
55
-					.then(didAsk => {
56
-						if (didAsk) {
57
-							return shouldShowRationale(androidPermission)
58
-								.then(shouldShow => shouldShow ? 'denied' : 'restricted')
59
-						}
60
-						return 'undetermined'
61
-					})
62
-			})
63
-	}
64
-
65
-
66
-	request(permission) {
67
-		const androidPermission = RNPTypes[permission]
68
-  	if (!androidPermission) return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on Android`);
69
-
70
-
71
-		return RNPermissions.request(androidPermission)
72
-			.then(res => {
73
-				// RNPermissions.request() to native module resolves to boolean
74
-				// rather than string if running on OS version prior to Android M 
75
-				if (typeof res === 'boolean') return res ? 'authorized' : 'denied';
76
-				return setDidAskOnce(permission)
77
-					.then(() => RESULTS[res])
78
-			});
79
-	}
80
-
81
-	checkMultiple(permissions) {
82
-		return Promise.all(permissions.map(this.check.bind(this)))
83
-			.then(res => res.reduce((pre, cur, i) => {
84
-				var name = permissions[i]
85
-				pre[name] = cur
86
-				return pre
87
-			}, {}))
88
-	}
89
-}
90
-
91
-module.exports = new ReactNativePermissions()

+ 0
- 70
index.ios.js View File

1
-'use strict';
2
-
3
-const ReactNative = require('react-native');
4
-const RNPermissions = ReactNative.NativeModules.ReactNativePermissions;
5
-
6
-const RNPTypes = [
7
-	'location',
8
-	'camera',
9
-	'microphone',
10
-	'photo',
11
-	'contacts',
12
-	'event',
13
-	'reminder',
14
-	'bluetooth',
15
-	'notification',
16
-	'backgroundRefresh',
17
-	'speechRecognition',
18
-]
19
-
20
-const DEFAULTS = {
21
-	'location' : 'whenInUse',
22
-	'notification': ['alert', 'badge', 'sound'],
23
-}
24
-
25
-class ReactNativePermissions {
26
-	canOpenSettings() {
27
-		return RNPermissions.canOpenSettings()
28
-	}
29
-
30
-	openSettings() {
31
-		return RNPermissions.openSettings()
32
-	}
33
-
34
-	getTypes() {
35
-		return RNPTypes;
36
-	}
37
-
38
-	check(permission, type) {
39
-  	if (!RNPTypes.includes(permission)) {
40
-			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on iOS`);
41
-		}
42
-		
43
-		return RNPermissions.getPermissionStatus(permission, type);
44
-	}
45
-
46
-	request(permission, type) {
47
-		if (!RNPTypes.includes(permission)) {
48
-			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on iOS`);
49
-		}
50
-
51
-		if (permission == 'backgroundRefresh') {
52
-			return Promise.reject('ReactNativePermissions: You cannot request backgroundRefresh')
53
-		}
54
-
55
-		type = type || DEFAULTS[permission]
56
-
57
-		return RNPermissions.requestPermission(permission, type)
58
-	}
59
-
60
-	checkMultiple(permissions) {
61
-		return Promise.all(permissions.map(permission => this.check(permission)))
62
-			.then(res => res.reduce((pre, cur, i) => {
63
-				var name = permissions[i]
64
-				pre[name] = cur
65
-				return pre
66
-			}, {}))
67
-	}
68
-}
69
-
70
-module.exports = new ReactNativePermissions()

+ 4
- 0
index.js View File

1
+// @flow
2
+
3
+import Permissions from './lib/permissions'
4
+export default Permissions

permissions/RNPAudioVideo.h → ios/Permissions/RNPAudioVideo.h View File


permissions/RNPAudioVideo.m → ios/Permissions/RNPAudioVideo.m View File


permissions/RNPBackgroundRefresh.h → ios/Permissions/RNPBackgroundRefresh.h View File


permissions/RNPBackgroundRefresh.m → ios/Permissions/RNPBackgroundRefresh.m View File


permissions/RNPBluetooth.h → ios/Permissions/RNPBluetooth.h View File


permissions/RNPBluetooth.m → ios/Permissions/RNPBluetooth.m View File


permissions/RNPContacts.h → ios/Permissions/RNPContacts.h View File


permissions/RNPContacts.m → ios/Permissions/RNPContacts.m View File


permissions/RNPEvent.h → ios/Permissions/RNPEvent.h View File


permissions/RNPEvent.m → ios/Permissions/RNPEvent.m View File


permissions/RNPLocation.h → ios/Permissions/RNPLocation.h View File


permissions/RNPLocation.m → ios/Permissions/RNPLocation.m View File


permissions/RNPNotification.h → ios/Permissions/RNPNotification.h View File


permissions/RNPNotification.m → ios/Permissions/RNPNotification.m View File


permissions/RNPPhoto.h → ios/Permissions/RNPPhoto.h View File


permissions/RNPPhoto.m → ios/Permissions/RNPPhoto.m View File


permissions/RNPSpeechRecognition.h → ios/Permissions/RNPSpeechRecognition.h View File


permissions/RNPSpeechRecognition.m → ios/Permissions/RNPSpeechRecognition.m View File


RCTConvert+RNPStatus.h → ios/RCTConvert+RNPStatus.h View File


RCTConvert+RNPStatus.m → ios/RCTConvert+RNPStatus.m View File

10
 
10
 
11
 @implementation RCTConvert (RNPStatus)
11
 @implementation RCTConvert (RNPStatus)
12
 
12
 
13
-
14
 RCT_ENUM_CONVERTER(RNPType, (@{ @"location" : @(RNPTypeLocation),
13
 RCT_ENUM_CONVERTER(RNPType, (@{ @"location" : @(RNPTypeLocation),
15
                                 @"camera" : @(RNPTypeCamera),
14
                                 @"camera" : @(RNPTypeCamera),
16
                                 @"microphone" : @(RNPTypeMicrophone),
15
                                 @"microphone" : @(RNPTypeMicrophone),

ReactNativePermissions.h → ios/ReactNativePermissions.h View File

16
 
16
 
17
 @interface ReactNativePermissions : NSObject <RCTBridgeModule>
17
 @interface ReactNativePermissions : NSObject <RCTBridgeModule>
18
 
18
 
19
-
20
 @end
19
 @end

ReactNativePermissions.m → ios/ReactNativePermissions.m View File

18
   #import "RCTBridge.h"
18
   #import "RCTBridge.h"
19
 #endif
19
 #endif
20
 
20
 
21
-
22
 #if __has_include(<React/RCTConvert.h>)
21
 #if __has_include(<React/RCTConvert.h>)
23
   #import <React/RCTConvert.h>
22
   #import <React/RCTConvert.h>
24
 #elif __has_include("React/RCTConvert.h")
23
 #elif __has_include("React/RCTConvert.h")
58
 RCT_EXPORT_MODULE();
57
 RCT_EXPORT_MODULE();
59
 @synthesize bridge = _bridge;
58
 @synthesize bridge = _bridge;
60
 
59
 
60
++ (BOOL)requiresMainQueueSetup
61
+{
62
+    return YES;
63
+}
64
+
61
 #pragma mark Initialization
65
 #pragma mark Initialization
62
 
66
 
63
 - (instancetype)init
67
 - (instancetype)init

ReactNativePermissions.xcodeproj/project.pbxproj → ios/ReactNativePermissions.xcodeproj/project.pbxproj View File

7
 	objects = {
7
 	objects = {
8
 
8
 
9
 /* Begin PBXBuildFile section */
9
 /* Begin PBXBuildFile section */
10
-		281CD5911E26B0C8003A72B2 /* RNPSpeechRecognition.m in Sources */ = {isa = PBXBuildFile; fileRef = 281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */; };
11
 		483383101FAB6115005D5777 /* RNPMotion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4833830E1FAB6114005D5777 /* RNPMotion.m */; };
10
 		483383101FAB6115005D5777 /* RNPMotion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4833830E1FAB6114005D5777 /* RNPMotion.m */; };
12
-		9D46283E1D34719100346A5B /* RNPAudioVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46282F1D34719100346A5B /* RNPAudioVideo.m */; };
13
-		9D46283F1D34719100346A5B /* RNPBackgroundRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628311D34719100346A5B /* RNPBackgroundRefresh.m */; };
14
-		9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628331D34719100346A5B /* RNPBluetooth.m */; };
15
-		9D4628411D34719100346A5B /* RNPContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628351D34719100346A5B /* RNPContacts.m */; };
16
-		9D4628421D34719100346A5B /* RNPEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628371D34719100346A5B /* RNPEvent.m */; };
17
-		9D4628431D34719100346A5B /* RNPLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628391D34719100346A5B /* RNPLocation.m */; };
18
-		9D4628441D34719100346A5B /* RNPNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46283B1D34719100346A5B /* RNPNotification.m */; };
19
-		9D4628451D34719100346A5B /* RNPPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46283D1D34719100346A5B /* RNPPhoto.m */; };
20
-		9DE8D2821CA3188D009CE8CC /* ReactNativePermissions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DE8D2811CA3188D009CE8CC /* ReactNativePermissions.m */; };
21
-		9DE8D28B1CA31E95009CE8CC /* RCTConvert+RNPStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DE8D28A1CA31E95009CE8CC /* RCTConvert+RNPStatus.m */; };
11
+		669581F71FE4416B008596CD /* RCTConvert+RNPStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 669581F41FE4416B008596CD /* RCTConvert+RNPStatus.m */; };
12
+		669581F81FE4416B008596CD /* ReactNativePermissions.m in Sources */ = {isa = PBXBuildFile; fileRef = 669581F51FE4416B008596CD /* ReactNativePermissions.m */; };
13
+		6695820D1FE441A8008596CD /* RNPSpeechRecognition.m in Sources */ = {isa = PBXBuildFile; fileRef = 669581FD1FE441A7008596CD /* RNPSpeechRecognition.m */; };
14
+		6695820E1FE441A8008596CD /* RNPLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 669581FE1FE441A7008596CD /* RNPLocation.m */; };
15
+		6695820F1FE441A8008596CD /* RNPBluetooth.m in Sources */ = {isa = PBXBuildFile; fileRef = 669581FF1FE441A7008596CD /* RNPBluetooth.m */; };
16
+		669582101FE441A8008596CD /* RNPBackgroundRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 669582001FE441A7008596CD /* RNPBackgroundRefresh.m */; };
17
+		669582111FE441A8008596CD /* RNPNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 669582011FE441A7008596CD /* RNPNotification.m */; };
18
+		669582121FE441A8008596CD /* RNPPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 669582031FE441A7008596CD /* RNPPhoto.m */; };
19
+		669582131FE441A8008596CD /* RNPAudioVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 669582071FE441A7008596CD /* RNPAudioVideo.m */; };
20
+		669582141FE441A8008596CD /* RNPContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 669582081FE441A8008596CD /* RNPContacts.m */; };
21
+		669582151FE441A8008596CD /* RNPEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 6695820A1FE441A8008596CD /* RNPEvent.m */; };
22
 /* End PBXBuildFile section */
22
 /* End PBXBuildFile section */
23
 
23
 
24
 /* Begin PBXCopyFilesBuildPhase section */
24
 /* Begin PBXCopyFilesBuildPhase section */
34
 /* End PBXCopyFilesBuildPhase section */
34
 /* End PBXCopyFilesBuildPhase section */
35
 
35
 
36
 /* Begin PBXFileReference section */
36
 /* Begin PBXFileReference section */
37
-		281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPSpeechRecognition.m; path = permissions/RNPSpeechRecognition.m; sourceTree = SOURCE_ROOT; };
38
-		281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPSpeechRecognition.h; path = permissions/RNPSpeechRecognition.h; sourceTree = SOURCE_ROOT; };
39
 		4833830E1FAB6114005D5777 /* RNPMotion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPMotion.m; path = permissions/RNPMotion.m; sourceTree = SOURCE_ROOT; };
37
 		4833830E1FAB6114005D5777 /* RNPMotion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPMotion.m; path = permissions/RNPMotion.m; sourceTree = SOURCE_ROOT; };
40
 		4833830F1FAB6115005D5777 /* RNPMotion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPMotion.h; path = permissions/RNPMotion.h; sourceTree = SOURCE_ROOT; };
38
 		4833830F1FAB6115005D5777 /* RNPMotion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPMotion.h; path = permissions/RNPMotion.h; sourceTree = SOURCE_ROOT; };
39
+		669581F31FE4416B008596CD /* ReactNativePermissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReactNativePermissions.h; sourceTree = "<group>"; };
40
+		669581F41FE4416B008596CD /* RCTConvert+RNPStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+RNPStatus.m"; sourceTree = "<group>"; };
41
+		669581F51FE4416B008596CD /* ReactNativePermissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactNativePermissions.m; sourceTree = "<group>"; };
42
+		669581F61FE4416B008596CD /* RCTConvert+RNPStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+RNPStatus.h"; sourceTree = "<group>"; };
43
+		669581FB1FE441A7008596CD /* RNPContacts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPContacts.h; sourceTree = "<group>"; };
44
+		669581FC1FE441A7008596CD /* RNPPhoto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPPhoto.h; sourceTree = "<group>"; };
45
+		669581FD1FE441A7008596CD /* RNPSpeechRecognition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPSpeechRecognition.m; sourceTree = "<group>"; };
46
+		669581FE1FE441A7008596CD /* RNPLocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPLocation.m; sourceTree = "<group>"; };
47
+		669581FF1FE441A7008596CD /* RNPBluetooth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPBluetooth.m; sourceTree = "<group>"; };
48
+		669582001FE441A7008596CD /* RNPBackgroundRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPBackgroundRefresh.m; sourceTree = "<group>"; };
49
+		669582011FE441A7008596CD /* RNPNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPNotification.m; sourceTree = "<group>"; };
50
+		669582021FE441A7008596CD /* RNPLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPLocation.h; sourceTree = "<group>"; };
51
+		669582031FE441A7008596CD /* RNPPhoto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPPhoto.m; sourceTree = "<group>"; };
52
+		669582041FE441A7008596CD /* RNPAudioVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPAudioVideo.h; sourceTree = "<group>"; };
53
+		669582051FE441A7008596CD /* RNPBackgroundRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPBackgroundRefresh.h; sourceTree = "<group>"; };
54
+		669582061FE441A7008596CD /* RNPEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPEvent.h; sourceTree = "<group>"; };
55
+		669582071FE441A7008596CD /* RNPAudioVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPAudioVideo.m; sourceTree = "<group>"; };
56
+		669582081FE441A8008596CD /* RNPContacts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPContacts.m; sourceTree = "<group>"; };
57
+		669582091FE441A8008596CD /* RNPBluetooth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPBluetooth.h; sourceTree = "<group>"; };
58
+		6695820A1FE441A8008596CD /* RNPEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNPEvent.m; sourceTree = "<group>"; };
59
+		6695820B1FE441A8008596CD /* RNPSpeechRecognition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPSpeechRecognition.h; sourceTree = "<group>"; };
60
+		6695820C1FE441A8008596CD /* RNPNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNPNotification.h; sourceTree = "<group>"; };
41
 		9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativePermissions.a; sourceTree = BUILT_PRODUCTS_DIR; };
61
 		9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativePermissions.a; sourceTree = BUILT_PRODUCTS_DIR; };
42
-		9D46282E1D34719100346A5B /* RNPAudioVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPAudioVideo.h; path = permissions/RNPAudioVideo.h; sourceTree = SOURCE_ROOT; };
43
-		9D46282F1D34719100346A5B /* RNPAudioVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPAudioVideo.m; path = permissions/RNPAudioVideo.m; sourceTree = SOURCE_ROOT; };
44
-		9D4628301D34719100346A5B /* RNPBackgroundRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPBackgroundRefresh.h; path = permissions/RNPBackgroundRefresh.h; sourceTree = SOURCE_ROOT; };
45
-		9D4628311D34719100346A5B /* RNPBackgroundRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPBackgroundRefresh.m; path = permissions/RNPBackgroundRefresh.m; sourceTree = SOURCE_ROOT; };
46
-		9D4628321D34719100346A5B /* RNPBluetooth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPBluetooth.h; path = permissions/RNPBluetooth.h; sourceTree = SOURCE_ROOT; };
47
-		9D4628331D34719100346A5B /* RNPBluetooth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPBluetooth.m; path = permissions/RNPBluetooth.m; sourceTree = SOURCE_ROOT; };
48
-		9D4628341D34719100346A5B /* RNPContacts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPContacts.h; path = permissions/RNPContacts.h; sourceTree = SOURCE_ROOT; };
49
-		9D4628351D34719100346A5B /* RNPContacts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPContacts.m; path = permissions/RNPContacts.m; sourceTree = SOURCE_ROOT; };
50
-		9D4628361D34719100346A5B /* RNPEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPEvent.h; path = permissions/RNPEvent.h; sourceTree = SOURCE_ROOT; };
51
-		9D4628371D34719100346A5B /* RNPEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPEvent.m; path = permissions/RNPEvent.m; sourceTree = SOURCE_ROOT; };
52
-		9D4628381D34719100346A5B /* RNPLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPLocation.h; path = permissions/RNPLocation.h; sourceTree = SOURCE_ROOT; };
53
-		9D4628391D34719100346A5B /* RNPLocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPLocation.m; path = permissions/RNPLocation.m; sourceTree = SOURCE_ROOT; };
54
-		9D46283A1D34719100346A5B /* RNPNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPNotification.h; path = permissions/RNPNotification.h; sourceTree = SOURCE_ROOT; };
55
-		9D46283B1D34719100346A5B /* RNPNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPNotification.m; path = permissions/RNPNotification.m; sourceTree = SOURCE_ROOT; };
56
-		9D46283C1D34719100346A5B /* RNPPhoto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPPhoto.h; path = permissions/RNPPhoto.h; sourceTree = SOURCE_ROOT; };
57
-		9D46283D1D34719100346A5B /* RNPPhoto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPPhoto.m; path = permissions/RNPPhoto.m; sourceTree = SOURCE_ROOT; };
58
-		9DE8D2801CA31888009CE8CC /* ReactNativePermissions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactNativePermissions.h; sourceTree = SOURCE_ROOT; };
59
-		9DE8D2811CA3188D009CE8CC /* ReactNativePermissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ReactNativePermissions.m; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
60
-		9DE8D2891CA31E95009CE8CC /* RCTConvert+RNPStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "RCTConvert+RNPStatus.h"; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
61
-		9DE8D28A1CA31E95009CE8CC /* RCTConvert+RNPStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "RCTConvert+RNPStatus.m"; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
62
 /* End PBXFileReference section */
62
 /* End PBXFileReference section */
63
 
63
 
64
 /* Begin PBXFrameworksBuildPhase section */
64
 /* Begin PBXFrameworksBuildPhase section */
72
 /* End PBXFrameworksBuildPhase section */
72
 /* End PBXFrameworksBuildPhase section */
73
 
73
 
74
 /* Begin PBXGroup section */
74
 /* Begin PBXGroup section */
75
-		9D23B3461C767B80008B4819 = {
75
+		669581FA1FE44191008596CD /* Permissions */ = {
76
 			isa = PBXGroup;
76
 			isa = PBXGroup;
77
 			children = (
77
 			children = (
78
-				9D23B3511C767B80008B4819 /* ReactNativePermissions */,
79
-				9D23B3501C767B80008B4819 /* Products */,
78
+				669582041FE441A7008596CD /* RNPAudioVideo.h */,
79
+				669582071FE441A7008596CD /* RNPAudioVideo.m */,
80
+				669582051FE441A7008596CD /* RNPBackgroundRefresh.h */,
81
+				669582001FE441A7008596CD /* RNPBackgroundRefresh.m */,
82
+				669582091FE441A8008596CD /* RNPBluetooth.h */,
83
+				669581FF1FE441A7008596CD /* RNPBluetooth.m */,
84
+				669581FB1FE441A7008596CD /* RNPContacts.h */,
85
+				669582081FE441A8008596CD /* RNPContacts.m */,
86
+				669582061FE441A7008596CD /* RNPEvent.h */,
87
+				6695820A1FE441A8008596CD /* RNPEvent.m */,
88
+				669582021FE441A7008596CD /* RNPLocation.h */,
89
+				669581FE1FE441A7008596CD /* RNPLocation.m */,
90
+				6695820C1FE441A8008596CD /* RNPNotification.h */,
91
+				669582011FE441A7008596CD /* RNPNotification.m */,
92
+				669581FC1FE441A7008596CD /* RNPPhoto.h */,
93
+				669582031FE441A7008596CD /* RNPPhoto.m */,
94
+				6695820B1FE441A8008596CD /* RNPSpeechRecognition.h */,
95
+				669581FD1FE441A7008596CD /* RNPSpeechRecognition.m */,
80
 			);
96
 			);
97
+			path = Permissions;
81
 			sourceTree = "<group>";
98
 			sourceTree = "<group>";
82
 		};
99
 		};
83
-		9D23B3501C767B80008B4819 /* Products */ = {
84
-			isa = PBXGroup;
85
-			children = (
86
-				9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */,
87
-			);
88
-			name = Products;
89
-			sourceTree = "<group>";
90
-		};
91
-		9D23B3511C767B80008B4819 /* ReactNativePermissions */ = {
100
+		9D23B3461C767B80008B4819 = {
92
 			isa = PBXGroup;
101
 			isa = PBXGroup;
93
 			children = (
102
 			children = (
94
-				9D4628091D33C1EC00346A5B /* permissions */,
95
-				9DE8D2891CA31E95009CE8CC /* RCTConvert+RNPStatus.h */,
96
-				9DE8D28A1CA31E95009CE8CC /* RCTConvert+RNPStatus.m */,
97
-				9DE8D2801CA31888009CE8CC /* ReactNativePermissions.h */,
98
-				9DE8D2811CA3188D009CE8CC /* ReactNativePermissions.m */,
103
+				669581FA1FE44191008596CD /* Permissions */,
104
+				669581F61FE4416B008596CD /* RCTConvert+RNPStatus.h */,
105
+				669581F41FE4416B008596CD /* RCTConvert+RNPStatus.m */,
106
+				669581F31FE4416B008596CD /* ReactNativePermissions.h */,
107
+				669581F51FE4416B008596CD /* ReactNativePermissions.m */,
108
+				9D23B3501C767B80008B4819 /* Products */,
99
 			);
109
 			);
100
-			path = ReactNativePermissions;
101
 			sourceTree = "<group>";
110
 			sourceTree = "<group>";
102
 		};
111
 		};
103
-		9D4628091D33C1EC00346A5B /* permissions */ = {
112
+		9D23B3501C767B80008B4819 /* Products */ = {
104
 			isa = PBXGroup;
113
 			isa = PBXGroup;
105
 			children = (
114
 			children = (
106
 				4833830F1FAB6115005D5777 /* RNPMotion.h */,
115
 				4833830F1FAB6115005D5777 /* RNPMotion.h */,
123
 				9D46283D1D34719100346A5B /* RNPPhoto.m */,
132
 				9D46283D1D34719100346A5B /* RNPPhoto.m */,
124
 				281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */,
133
 				281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */,
125
 				281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */,
134
 				281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */,
135
+				9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */,
126
 			);
136
 			);
127
-			name = permissions;
137
+			name = Products;
128
 			sourceTree = "<group>";
138
 			sourceTree = "<group>";
129
 		};
139
 		};
130
 /* End PBXGroup section */
140
 /* End PBXGroup section */
183
 			isa = PBXSourcesBuildPhase;
193
 			isa = PBXSourcesBuildPhase;
184
 			buildActionMask = 2147483647;
194
 			buildActionMask = 2147483647;
185
 			files = (
195
 			files = (
186
-				9D46283F1D34719100346A5B /* RNPBackgroundRefresh.m in Sources */,
187
-				9D4628451D34719100346A5B /* RNPPhoto.m in Sources */,
188
-				281CD5911E26B0C8003A72B2 /* RNPSpeechRecognition.m in Sources */,
189
-				9D4628431D34719100346A5B /* RNPLocation.m in Sources */,
190
-				9D46283E1D34719100346A5B /* RNPAudioVideo.m in Sources */,
191
-				9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */,
192
-				9DE8D28B1CA31E95009CE8CC /* RCTConvert+RNPStatus.m in Sources */,
193
-				9D4628421D34719100346A5B /* RNPEvent.m in Sources */,
194
 				483383101FAB6115005D5777 /* RNPMotion.m in Sources */,
196
 				483383101FAB6115005D5777 /* RNPMotion.m in Sources */,
195
-				9DE8D2821CA3188D009CE8CC /* ReactNativePermissions.m in Sources */,
196
-				9D4628411D34719100346A5B /* RNPContacts.m in Sources */,
197
-				9D4628441D34719100346A5B /* RNPNotification.m in Sources */,
197
+				669582111FE441A8008596CD /* RNPNotification.m in Sources */,
198
+				669582151FE441A8008596CD /* RNPEvent.m in Sources */,
199
+				669582101FE441A8008596CD /* RNPBackgroundRefresh.m in Sources */,
200
+				669581F71FE4416B008596CD /* RCTConvert+RNPStatus.m in Sources */,
201
+				6695820E1FE441A8008596CD /* RNPLocation.m in Sources */,
202
+				6695820F1FE441A8008596CD /* RNPBluetooth.m in Sources */,
203
+				669582141FE441A8008596CD /* RNPContacts.m in Sources */,
204
+				6695820D1FE441A8008596CD /* RNPSpeechRecognition.m in Sources */,
205
+				669582131FE441A8008596CD /* RNPAudioVideo.m in Sources */,
206
+				669581F81FE4416B008596CD /* ReactNativePermissions.m in Sources */,
207
+				669582121FE441A8008596CD /* RNPPhoto.m in Sources */,
198
 			);
208
 			);
199
 			runOnlyForDeploymentPostprocessing = 0;
209
 			runOnlyForDeploymentPostprocessing = 0;
200
 		};
210
 		};

+ 117
- 0
lib/permissions.android.js View File

1
+// @flow
2
+
3
+import { AsyncStorage, NativeModules, PermissionsAndroid } from 'react-native'
4
+
5
+type Status = 'authorized' | 'denied' | 'restricted' | 'undetermined'
6
+type Rationale = { title: string, message: string }
7
+type CheckOptions = string | { type: string }
8
+type RequestOptions = string | { type: string, rationale?: Rationale }
9
+
10
+const permissionTypes = {
11
+  location: PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
12
+  camera: PermissionsAndroid.PERMISSIONS.CAMERA,
13
+  microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
14
+  contacts: PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
15
+  event: PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
16
+  storage: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
17
+  photo: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
18
+  callPhone: PermissionsAndroid.PERMISSIONS.CALL_PHONE,
19
+  readSms: PermissionsAndroid.PERMISSIONS.READ_SMS,
20
+  receiveSms: PermissionsAndroid.PERMISSIONS.RECEIVE_SMS,
21
+}
22
+
23
+const RESULTS = {
24
+  [PermissionsAndroid.RESULTS.GRANTED]: 'authorized',
25
+  [PermissionsAndroid.RESULTS.DENIED]: 'denied',
26
+  [PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN]: 'restricted',
27
+}
28
+
29
+const STORAGE_KEY = '@RNPermissions:didAskPermission:'
30
+
31
+const setDidAskOnce = (permission: string) =>
32
+  AsyncStorage.setItem(STORAGE_KEY + permission, 'true')
33
+
34
+const getDidAskOnce = (permission: string) =>
35
+  AsyncStorage.getItem(STORAGE_KEY + permission).then(item => !!item)
36
+
37
+class ReactNativePermissions {
38
+  canOpenSettings: () => Promise<boolean> = () => Promise.resolve(false)
39
+
40
+  openSettings: () => Promise<*> = () =>
41
+    Promise.reject(new Error("'openSettings' is deprecated on android"))
42
+
43
+  getTypes: () => Array<string> = () => Object.keys(permissionTypes)
44
+
45
+  check = (permission: string, options?: CheckOptions): Promise<Status> => {
46
+    if (!permissionTypes[permission]) {
47
+      const error = new Error(
48
+        `ReactNativePermissions: ${
49
+          permission
50
+        } is not a valid permission type on Android`,
51
+      )
52
+
53
+      return Promise.reject(error)
54
+    }
55
+
56
+    return PermissionsAndroid.check(permissionTypes[permission]).then(
57
+      isAuthorized => {
58
+        if (isAuthorized) {
59
+          return 'authorized'
60
+        }
61
+
62
+        return getDidAskOnce(permission).then(didAsk => {
63
+          if (didAsk) {
64
+            return NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale(
65
+              permissionTypes[permission],
66
+            ).then(shouldShow => (shouldShow ? 'denied' : 'restricted'))
67
+          }
68
+
69
+          return 'undetermined'
70
+        })
71
+      },
72
+    )
73
+  }
74
+
75
+  request = (permission: string, options?: RequestOptions): Promise<Status> => {
76
+    if (!permissionTypes[permission]) {
77
+      const error = new Error(
78
+        `ReactNativePermissions: ${
79
+          permission
80
+        } is not a valid permission type on Android`,
81
+      )
82
+
83
+      return Promise.reject(error)
84
+    }
85
+
86
+    let rationale
87
+
88
+    if (options && options.rationale) {
89
+      rationale = options.rationale
90
+    }
91
+
92
+    return PermissionsAndroid.request(
93
+      permissionTypes[permission],
94
+      rationale,
95
+    ).then(result => {
96
+      // PermissionsAndroid.request() to native module resolves to boolean
97
+      // rather than string if running on OS version prior to Android M
98
+      if (typeof result === 'boolean') {
99
+        return result ? 'authorized' : 'denied'
100
+      }
101
+
102
+      return setDidAskOnce(permission).then(() => RESULTS[result])
103
+    })
104
+  }
105
+
106
+  checkMultiple = (permissions: Array<string>): Promise<{ [string]: string }> =>
107
+    Promise.all(permissions.map(permission => this.check(permission))).then(
108
+      result =>
109
+        result.reduce((acc, value, index) => {
110
+          const name = permissions[index]
111
+          acc[name] = value
112
+          return acc
113
+        }, {}),
114
+    )
115
+}
116
+
117
+export default new ReactNativePermissions()

+ 107
- 0
lib/permissions.ios.js View File

1
+// @flow
2
+
3
+import { NativeModules } from 'react-native'
4
+const PermissionsIOS = NativeModules.ReactNativePermissions
5
+
6
+type Status = 'authorized' | 'denied' | 'restricted' | 'undetermined'
7
+type Rationale = { title: string, message: string }
8
+type CheckOptions = string | { type: string }
9
+type RequestOptions = string | { type: string, rationale?: Rationale }
10
+
11
+const permissionTypes = [
12
+  'location',
13
+  'camera',
14
+  'microphone',
15
+  'photo',
16
+  'contacts',
17
+  'event',
18
+  'reminder',
19
+  'bluetooth',
20
+  'notification',
21
+  'backgroundRefresh',
22
+  'speechRecognition',
23
+]
24
+
25
+const DEFAULTS = {
26
+  location: 'whenInUse',
27
+  notification: ['alert', 'badge', 'sound'],
28
+}
29
+
30
+class ReactNativePermissions {
31
+  canOpenSettings: () => Promise<boolean> = () =>
32
+    PermissionsIOS.canOpenSettings()
33
+
34
+  openSettings: () => Promise<*> = () => PermissionsIOS.openSettings()
35
+
36
+  getTypes: () => Array<string> = () => permissionTypes
37
+
38
+  check = (permission: string, options?: CheckOptions): Promise<Status> => {
39
+    if (!permissionTypes.includes(permission)) {
40
+      const error = new Error(
41
+        `ReactNativePermissions: ${
42
+          permission
43
+        } is not a valid permission type on iOS`,
44
+      )
45
+
46
+      return Promise.reject(error)
47
+    }
48
+
49
+    let type
50
+
51
+    if (typeof options === 'string') {
52
+      type = options
53
+    } else if (options && options.type) {
54
+      type = options.type
55
+    }
56
+
57
+    return PermissionsIOS.getPermissionStatus(
58
+      permission,
59
+      type || DEFAULTS[permission],
60
+    )
61
+  }
62
+
63
+  request = (permission: string, options?: RequestOptions): Promise<Status> => {
64
+    if (!permissionTypes.includes(permission)) {
65
+      const error = new Error(
66
+        `ReactNativePermissions: ${
67
+          permission
68
+        } is not a valid permission type on iOS`,
69
+      )
70
+
71
+      return Promise.reject(error)
72
+    }
73
+
74
+    if (permission == 'backgroundRefresh') {
75
+      const error = new Error(
76
+        'ReactNativePermissions: You cannot request backgroundRefresh',
77
+      )
78
+
79
+      return Promise.reject(error)
80
+    }
81
+
82
+    let type
83
+
84
+    if (typeof options === 'string') {
85
+      type = options
86
+    } else if (options && options.type) {
87
+      type = options.type
88
+    }
89
+
90
+    return PermissionsIOS.requestPermission(
91
+      permission,
92
+      type || DEFAULTS[permission],
93
+    )
94
+  }
95
+
96
+  checkMultiple = (permissions: Array<string>): Promise<{ [string]: string }> =>
97
+    Promise.all(permissions.map(permission => this.check(permission))).then(
98
+      result =>
99
+        result.reduce((acc, value, index) => {
100
+          const name = permissions[index]
101
+          acc[name] = value
102
+          return acc
103
+        }, {}),
104
+    )
105
+}
106
+
107
+export default new ReactNativePermissions()

+ 21
- 12
package.json View File

1
 {
1
 {
2
   "name": "react-native-permissions",
2
   "name": "react-native-permissions",
3
-  "version": "1.0.1",
3
+  "version": "1.0.6",
4
+  "description": "Check user permissions in React Native",
5
+  "author": "Yonah Forst <yonaforst@hotmail.com>",
6
+  "homepage": "https://github.com/yonahforst/react-native-permissions",
7
+  "keywords": ["react-native", "react-permissions", "permissions"],
8
+  "main": "index.js",
9
+  "license": "MIT",
4
   "repository": {
10
   "repository": {
5
     "type": "git",
11
     "type": "git",
6
-    "url": "https://github.com/joshblour/react-native-permissions.git"
12
+    "url": "https://github.com/yonahforst/react-native-permissions.git"
7
   },
13
   },
8
-  "main": "index",
9
-  "license": "MIT",
10
-  "keywords": [
11
-    "react-native",
12
-    "react-permissions",
13
-    "permissions"
14
-  ],
15
-  "author": "Yonah Forst <yonaforst@hotmail.com>",
16
-  "homepage": "https://github.com/joshblour/react-native-permissions",
17
-  "description": "Check user permissions in React Native"
14
+  "scripts": {
15
+    "precommit": "lint-staged",
16
+    "prettier": "prettier --write '**/*.{js,json,md}'"
17
+  },
18
+  "lint-staged": {
19
+    "**/*.{js,json,md}": ["prettier --write", "git add"]
20
+  },
21
+  "devDependencies": {
22
+    "flow-bin": "^0.57.3",
23
+    "husky": "^0.14.3",
24
+    "lint-staged": "^6.0.0",
25
+    "prettier": "^1.9.2"
26
+  }
18
 }
27
 }

+ 614
- 0
yarn.lock View File

1
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
+# yarn lockfile v1
3
+
4
+
5
+ansi-escapes@^1.0.0:
6
+  version "1.4.0"
7
+  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
8
+
9
+ansi-regex@^2.0.0:
10
+  version "2.1.1"
11
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
12
+
13
+ansi-regex@^3.0.0:
14
+  version "3.0.0"
15
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
16
+
17
+ansi-styles@^2.2.1:
18
+  version "2.2.1"
19
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
20
+
21
+ansi-styles@^3.1.0, ansi-styles@^3.2.0:
22
+  version "3.2.0"
23
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
24
+  dependencies:
25
+    color-convert "^1.9.0"
26
+
27
+any-observable@^0.2.0:
28
+  version "0.2.0"
29
+  resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
30
+
31
+app-root-path@^2.0.0:
32
+  version "2.0.1"
33
+  resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46"
34
+
35
+argparse@^1.0.7:
36
+  version "1.0.9"
37
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
38
+  dependencies:
39
+    sprintf-js "~1.0.2"
40
+
41
+balanced-match@^1.0.0:
42
+  version "1.0.0"
43
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
44
+
45
+brace-expansion@^1.1.7:
46
+  version "1.1.8"
47
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
48
+  dependencies:
49
+    balanced-match "^1.0.0"
50
+    concat-map "0.0.1"
51
+
52
+chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
53
+  version "1.1.3"
54
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
55
+  dependencies:
56
+    ansi-styles "^2.2.1"
57
+    escape-string-regexp "^1.0.2"
58
+    has-ansi "^2.0.0"
59
+    strip-ansi "^3.0.0"
60
+    supports-color "^2.0.0"
61
+
62
+chalk@^2.0.1, chalk@^2.1.0:
63
+  version "2.3.0"
64
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
65
+  dependencies:
66
+    ansi-styles "^3.1.0"
67
+    escape-string-regexp "^1.0.5"
68
+    supports-color "^4.0.0"
69
+
70
+ci-info@^1.0.0:
71
+  version "1.1.2"
72
+  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4"
73
+
74
+cli-cursor@^1.0.2:
75
+  version "1.0.2"
76
+  resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
77
+  dependencies:
78
+    restore-cursor "^1.0.1"
79
+
80
+cli-spinners@^0.1.2:
81
+  version "0.1.2"
82
+  resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
83
+
84
+cli-truncate@^0.2.1:
85
+  version "0.2.1"
86
+  resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
87
+  dependencies:
88
+    slice-ansi "0.0.4"
89
+    string-width "^1.0.1"
90
+
91
+code-point-at@^1.0.0:
92
+  version "1.1.0"
93
+  resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
94
+
95
+color-convert@^1.9.0:
96
+  version "1.9.1"
97
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
98
+  dependencies:
99
+    color-name "^1.1.1"
100
+
101
+color-name@^1.1.1:
102
+  version "1.1.3"
103
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
104
+
105
+commander@^2.11.0, commander@^2.9.0:
106
+  version "2.12.2"
107
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
108
+
109
+concat-map@0.0.1:
110
+  version "0.0.1"
111
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
112
+
113
+cosmiconfig@^3.1.0:
114
+  version "3.1.0"
115
+  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
116
+  dependencies:
117
+    is-directory "^0.3.1"
118
+    js-yaml "^3.9.0"
119
+    parse-json "^3.0.0"
120
+    require-from-string "^2.0.1"
121
+
122
+cross-spawn@^5.0.1:
123
+  version "5.1.0"
124
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
125
+  dependencies:
126
+    lru-cache "^4.0.1"
127
+    shebang-command "^1.2.0"
128
+    which "^1.2.9"
129
+
130
+date-fns@^1.27.2:
131
+  version "1.29.0"
132
+  resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
133
+
134
+dedent@^0.7.0:
135
+  version "0.7.0"
136
+  resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
137
+
138
+elegant-spinner@^1.0.1:
139
+  version "1.0.1"
140
+  resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
141
+
142
+error-ex@^1.3.1:
143
+  version "1.3.1"
144
+  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
145
+  dependencies:
146
+    is-arrayish "^0.2.1"
147
+
148
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
149
+  version "1.0.5"
150
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
151
+
152
+esprima@^4.0.0:
153
+  version "4.0.0"
154
+  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
155
+
156
+execa@^0.8.0:
157
+  version "0.8.0"
158
+  resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da"
159
+  dependencies:
160
+    cross-spawn "^5.0.1"
161
+    get-stream "^3.0.0"
162
+    is-stream "^1.1.0"
163
+    npm-run-path "^2.0.0"
164
+    p-finally "^1.0.0"
165
+    signal-exit "^3.0.0"
166
+    strip-eof "^1.0.0"
167
+
168
+exit-hook@^1.0.0:
169
+  version "1.1.1"
170
+  resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
171
+
172
+figures@^1.7.0:
173
+  version "1.7.0"
174
+  resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
175
+  dependencies:
176
+    escape-string-regexp "^1.0.5"
177
+    object-assign "^4.1.0"
178
+
179
+find-parent-dir@^0.3.0:
180
+  version "0.3.0"
181
+  resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54"
182
+
183
+flow-bin@^0.57.3:
184
+  version "0.57.3"
185
+  resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.57.3.tgz#843fb80a821b6d0c5847f7bb3f42365ffe53b27b"
186
+
187
+get-own-enumerable-property-symbols@^2.0.1:
188
+  version "2.0.1"
189
+  resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b"
190
+
191
+get-stream@^3.0.0:
192
+  version "3.0.0"
193
+  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
194
+
195
+has-ansi@^2.0.0:
196
+  version "2.0.0"
197
+  resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
198
+  dependencies:
199
+    ansi-regex "^2.0.0"
200
+
201
+has-flag@^2.0.0:
202
+  version "2.0.0"
203
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
204
+
205
+husky@^0.14.3:
206
+  version "0.14.3"
207
+  resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3"
208
+  dependencies:
209
+    is-ci "^1.0.10"
210
+    normalize-path "^1.0.0"
211
+    strip-indent "^2.0.0"
212
+
213
+indent-string@^2.1.0:
214
+  version "2.1.0"
215
+  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
216
+  dependencies:
217
+    repeating "^2.0.0"
218
+
219
+indent-string@^3.0.0:
220
+  version "3.2.0"
221
+  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
222
+
223
+is-arrayish@^0.2.1:
224
+  version "0.2.1"
225
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
226
+
227
+is-ci@^1.0.10:
228
+  version "1.0.10"
229
+  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
230
+  dependencies:
231
+    ci-info "^1.0.0"
232
+
233
+is-directory@^0.3.1:
234
+  version "0.3.1"
235
+  resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
236
+
237
+is-extglob@^2.1.1:
238
+  version "2.1.1"
239
+  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
240
+
241
+is-finite@^1.0.0:
242
+  version "1.0.2"
243
+  resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
244
+  dependencies:
245
+    number-is-nan "^1.0.0"
246
+
247
+is-fullwidth-code-point@^1.0.0:
248
+  version "1.0.0"
249
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
250
+  dependencies:
251
+    number-is-nan "^1.0.0"
252
+
253
+is-glob@^4.0.0:
254
+  version "4.0.0"
255
+  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
256
+  dependencies:
257
+    is-extglob "^2.1.1"
258
+
259
+is-obj@^1.0.1:
260
+  version "1.0.1"
261
+  resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
262
+
263
+is-observable@^0.2.0:
264
+  version "0.2.0"
265
+  resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2"
266
+  dependencies:
267
+    symbol-observable "^0.2.2"
268
+
269
+is-promise@^2.1.0:
270
+  version "2.1.0"
271
+  resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
272
+
273
+is-regexp@^1.0.0:
274
+  version "1.0.0"
275
+  resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
276
+
277
+is-stream@^1.1.0:
278
+  version "1.1.0"
279
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
280
+
281
+isexe@^2.0.0:
282
+  version "2.0.0"
283
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
284
+
285
+jest-get-type@^21.2.0:
286
+  version "21.2.0"
287
+  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23"
288
+
289
+jest-validate@^21.1.0:
290
+  version "21.2.1"
291
+  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7"
292
+  dependencies:
293
+    chalk "^2.0.1"
294
+    jest-get-type "^21.2.0"
295
+    leven "^2.1.0"
296
+    pretty-format "^21.2.1"
297
+
298
+js-yaml@^3.9.0:
299
+  version "3.10.0"
300
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
301
+  dependencies:
302
+    argparse "^1.0.7"
303
+    esprima "^4.0.0"
304
+
305
+leven@^2.1.0:
306
+  version "2.1.0"
307
+  resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
308
+
309
+lint-staged@^5.0.0:
310
+  version "5.0.0"
311
+  resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-5.0.0.tgz#f1c670e03e2fdf3f3d0eb81f72d3bcf658770e54"
312
+  dependencies:
313
+    app-root-path "^2.0.0"
314
+    chalk "^2.1.0"
315
+    commander "^2.11.0"
316
+    cosmiconfig "^3.1.0"
317
+    dedent "^0.7.0"
318
+    execa "^0.8.0"
319
+    find-parent-dir "^0.3.0"
320
+    is-glob "^4.0.0"
321
+    jest-validate "^21.1.0"
322
+    listr "^0.13.0"
323
+    lodash "^4.17.4"
324
+    log-symbols "^2.0.0"
325
+    minimatch "^3.0.0"
326
+    npm-which "^3.0.1"
327
+    p-map "^1.1.1"
328
+    path-is-inside "^1.0.2"
329
+    pify "^3.0.0"
330
+    staged-git-files "0.0.4"
331
+    stringify-object "^3.2.0"
332
+
333
+listr-silent-renderer@^1.1.1:
334
+  version "1.1.1"
335
+  resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
336
+
337
+listr-update-renderer@^0.4.0:
338
+  version "0.4.0"
339
+  resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
340
+  dependencies:
341
+    chalk "^1.1.3"
342
+    cli-truncate "^0.2.1"
343
+    elegant-spinner "^1.0.1"
344
+    figures "^1.7.0"
345
+    indent-string "^3.0.0"
346
+    log-symbols "^1.0.2"
347
+    log-update "^1.0.2"
348
+    strip-ansi "^3.0.1"
349
+
350
+listr-verbose-renderer@^0.4.0:
351
+  version "0.4.1"
352
+  resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
353
+  dependencies:
354
+    chalk "^1.1.3"
355
+    cli-cursor "^1.0.2"
356
+    date-fns "^1.27.2"
357
+    figures "^1.7.0"
358
+
359
+listr@^0.13.0:
360
+  version "0.13.0"
361
+  resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d"
362
+  dependencies:
363
+    chalk "^1.1.3"
364
+    cli-truncate "^0.2.1"
365
+    figures "^1.7.0"
366
+    indent-string "^2.1.0"
367
+    is-observable "^0.2.0"
368
+    is-promise "^2.1.0"
369
+    is-stream "^1.1.0"
370
+    listr-silent-renderer "^1.1.1"
371
+    listr-update-renderer "^0.4.0"
372
+    listr-verbose-renderer "^0.4.0"
373
+    log-symbols "^1.0.2"
374
+    log-update "^1.0.2"
375
+    ora "^0.2.3"
376
+    p-map "^1.1.1"
377
+    rxjs "^5.4.2"
378
+    stream-to-observable "^0.2.0"
379
+    strip-ansi "^3.0.1"
380
+
381
+lodash@^4.17.4:
382
+  version "4.17.4"
383
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
384
+
385
+log-symbols@^1.0.2:
386
+  version "1.0.2"
387
+  resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
388
+  dependencies:
389
+    chalk "^1.0.0"
390
+
391
+log-symbols@^2.0.0:
392
+  version "2.1.0"
393
+  resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6"
394
+  dependencies:
395
+    chalk "^2.0.1"
396
+
397
+log-update@^1.0.2:
398
+  version "1.0.2"
399
+  resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
400
+  dependencies:
401
+    ansi-escapes "^1.0.0"
402
+    cli-cursor "^1.0.2"
403
+
404
+lru-cache@^4.0.1:
405
+  version "4.1.1"
406
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
407
+  dependencies:
408
+    pseudomap "^1.0.2"
409
+    yallist "^2.1.2"
410
+
411
+minimatch@^3.0.0:
412
+  version "3.0.4"
413
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
414
+  dependencies:
415
+    brace-expansion "^1.1.7"
416
+
417
+normalize-path@^1.0.0:
418
+  version "1.0.0"
419
+  resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379"
420
+
421
+npm-path@^2.0.2:
422
+  version "2.0.3"
423
+  resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.3.tgz#15cff4e1c89a38da77f56f6055b24f975dfb2bbe"
424
+  dependencies:
425
+    which "^1.2.10"
426
+
427
+npm-run-path@^2.0.0:
428
+  version "2.0.2"
429
+  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
430
+  dependencies:
431
+    path-key "^2.0.0"
432
+
433
+npm-which@^3.0.1:
434
+  version "3.0.1"
435
+  resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa"
436
+  dependencies:
437
+    commander "^2.9.0"
438
+    npm-path "^2.0.2"
439
+    which "^1.2.10"
440
+
441
+number-is-nan@^1.0.0:
442
+  version "1.0.1"
443
+  resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
444
+
445
+object-assign@^4.0.1, object-assign@^4.1.0:
446
+  version "4.1.1"
447
+  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
448
+
449
+onetime@^1.0.0:
450
+  version "1.1.0"
451
+  resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
452
+
453
+ora@^0.2.3:
454
+  version "0.2.3"
455
+  resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
456
+  dependencies:
457
+    chalk "^1.1.1"
458
+    cli-cursor "^1.0.2"
459
+    cli-spinners "^0.1.2"
460
+    object-assign "^4.0.1"
461
+
462
+p-finally@^1.0.0:
463
+  version "1.0.0"
464
+  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
465
+
466
+p-map@^1.1.1:
467
+  version "1.2.0"
468
+  resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
469
+
470
+parse-json@^3.0.0:
471
+  version "3.0.0"
472
+  resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
473
+  dependencies:
474
+    error-ex "^1.3.1"
475
+
476
+path-is-inside@^1.0.2:
477
+  version "1.0.2"
478
+  resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
479
+
480
+path-key@^2.0.0:
481
+  version "2.0.1"
482
+  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
483
+
484
+pify@^3.0.0:
485
+  version "3.0.0"
486
+  resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
487
+
488
+prettier@^1.8.2:
489
+  version "1.8.2"
490
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8"
491
+
492
+pretty-format@^21.2.1:
493
+  version "21.2.1"
494
+  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36"
495
+  dependencies:
496
+    ansi-regex "^3.0.0"
497
+    ansi-styles "^3.2.0"
498
+
499
+pseudomap@^1.0.2:
500
+  version "1.0.2"
501
+  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
502
+
503
+repeating@^2.0.0:
504
+  version "2.0.1"
505
+  resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
506
+  dependencies:
507
+    is-finite "^1.0.0"
508
+
509
+require-from-string@^2.0.1:
510
+  version "2.0.1"
511
+  resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"
512
+
513
+restore-cursor@^1.0.1:
514
+  version "1.0.1"
515
+  resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
516
+  dependencies:
517
+    exit-hook "^1.0.0"
518
+    onetime "^1.0.0"
519
+
520
+rxjs@^5.4.2:
521
+  version "5.5.3"
522
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.3.tgz#b62227e74b84f4e77bdf440e50b5ee01a1bc7dcd"
523
+  dependencies:
524
+    symbol-observable "^1.0.1"
525
+
526
+shebang-command@^1.2.0:
527
+  version "1.2.0"
528
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
529
+  dependencies:
530
+    shebang-regex "^1.0.0"
531
+
532
+shebang-regex@^1.0.0:
533
+  version "1.0.0"
534
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
535
+
536
+signal-exit@^3.0.0:
537
+  version "3.0.2"
538
+  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
539
+
540
+slice-ansi@0.0.4:
541
+  version "0.0.4"
542
+  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
543
+
544
+sprintf-js@~1.0.2:
545
+  version "1.0.3"
546
+  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
547
+
548
+staged-git-files@0.0.4:
549
+  version "0.0.4"
550
+  resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35"
551
+
552
+stream-to-observable@^0.2.0:
553
+  version "0.2.0"
554
+  resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10"
555
+  dependencies:
556
+    any-observable "^0.2.0"
557
+
558
+string-width@^1.0.1:
559
+  version "1.0.2"
560
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
561
+  dependencies:
562
+    code-point-at "^1.0.0"
563
+    is-fullwidth-code-point "^1.0.0"
564
+    strip-ansi "^3.0.0"
565
+
566
+stringify-object@^3.2.0:
567
+  version "3.2.1"
568
+  resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.1.tgz#2720c2eff940854c819f6ee252aaeb581f30624d"
569
+  dependencies:
570
+    get-own-enumerable-property-symbols "^2.0.1"
571
+    is-obj "^1.0.1"
572
+    is-regexp "^1.0.0"
573
+
574
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
575
+  version "3.0.1"
576
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
577
+  dependencies:
578
+    ansi-regex "^2.0.0"
579
+
580
+strip-eof@^1.0.0:
581
+  version "1.0.0"
582
+  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
583
+
584
+strip-indent@^2.0.0:
585
+  version "2.0.0"
586
+  resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
587
+
588
+supports-color@^2.0.0:
589
+  version "2.0.0"
590
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
591
+
592
+supports-color@^4.0.0:
593
+  version "4.5.0"
594
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
595
+  dependencies:
596
+    has-flag "^2.0.0"
597
+
598
+symbol-observable@^0.2.2:
599
+  version "0.2.4"
600
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40"
601
+
602
+symbol-observable@^1.0.1:
603
+  version "1.1.0"
604
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
605
+
606
+which@^1.2.10, which@^1.2.9:
607
+  version "1.3.0"
608
+  resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
609
+  dependencies:
610
+    isexe "^2.0.0"
611
+
612
+yallist@^2.1.2:
613
+  version "2.1.2"
614
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"