Add flow anotation (#163)

* Add flow anotation

* Update typed and add flow.js test

* Auto calculation of  Emun values for flow types
This commit is contained in:
David Narbutovich(g) 2018-12-19 20:48:03 +03:00 committed by Joel Arvidsson
parent c0aba252b3
commit b4106fc10b
6 changed files with 4975 additions and 46 deletions

View File

@ -29,7 +29,23 @@ node_modules/react-native/flow-github/
[options]
emoji=true
esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
module.system=haste
module.system.haste.use_name_reducers=true
# get basename
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
# strip .js or .js.flow suffix
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
# strip .ios suffix
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
module.system.haste.paths.blacklist=.*/__tests__/.*
module.system.haste.paths.blacklist=.*/__mocks__/.*
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
munge_underscores=true
@ -50,7 +66,5 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
^0.61.0
^0.78.0

View File

@ -7,3 +7,5 @@ node_modules
KeychainExample
.editorconfig
test_index.js

View File

@ -1,7 +1,8 @@
// @flow
import { NativeModules, Platform } from 'react-native';
const { RNKeychainManager } = NativeModules;
export const ACCESSIBLE = {
export const ACCESSIBLE = Object.freeze({
WHEN_UNLOCKED: 'AccessibleWhenUnlocked',
AFTER_FIRST_UNLOCK: 'AccessibleAfterFirstUnlock',
ALWAYS: 'AccessibleAlways',
@ -10,9 +11,9 @@ export const ACCESSIBLE = {
AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY:
'AccessibleAfterFirstUnlockThisDeviceOnly',
ALWAYS_THIS_DEVICE_ONLY: 'AccessibleAlwaysThisDeviceOnly',
};
});
export const ACCESS_CONTROL = {
export const ACCESS_CONTROL = Object.freeze({
USER_PRESENCE: 'UserPresence',
BIOMETRY_ANY: 'BiometryAny',
BIOMETRY_CURRENT_SET: 'BiometryCurrentSet',
@ -20,40 +21,26 @@ export const ACCESS_CONTROL = {
APPLICATION_PASSWORD: 'ApplicationPassword',
BIOMETRY_ANY_OR_DEVICE_PASSCODE: 'BiometryAnyOrDevicePasscode',
BIOMETRY_CURRENT_SET_OR_DEVICE_PASSCODE: 'BiometryCurrentSetOrDevicePasscode',
};
});
export const AUTHENTICATION_TYPE = {
export const AUTHENTICATION_TYPE = Object.freeze({
DEVICE_PASSCODE_OR_BIOMETRICS: 'AuthenticationWithBiometricsDevicePasscode',
BIOMETRICS: 'AuthenticationWithBiometrics',
};
});
export const BIOMETRY_TYPE = {
export const BIOMETRY_TYPE = Object.freeze({
TOUCH_ID: 'TouchID',
FACE_ID: 'FaceID',
FINGERPRINT: 'Fingerprint',
};
});
type SecAccessible =
| 'AccessibleWhenUnlocked'
| 'AccessibleAfterFirstUnlock'
| 'AccessibleAlways'
| 'AccessibleWhenPasscodeSetThisDeviceOnly'
| 'AccessibleWhenUnlockedThisDeviceOnly'
| 'AccessibleAfterFirstUnlockThisDeviceOnly'
| 'AccessibleAlwaysThisDeviceOnly';
export type SecAccessible = $Values<typeof ACCESSIBLE>;
type SecAccessControl =
| 'UserPresence'
| 'BiometryAny'
| 'BiometryCurrentSet'
| 'DevicePasscode'
| 'ApplicationPassword'
| 'BiometryAnyOrDevicePasscode'
| 'BiometryCurrentSetOrDevicePasscode';
export type SecAccessControl = $Values<typeof ACCESS_CONTROL>;
type LAPolicy = 'Authentication' | 'AuthenticationWithBiometrics';
export type LAPolicy = $Values<typeof AUTHENTICATION_TYPE>;
type Options = {
export type Options = {
accessControl?: SecAccessControl,
accessGroup?: string,
accessible?: SecAccessible,
@ -68,7 +55,7 @@ type Options = {
* @param {object} options LAPolicy option, iOS only
* @return {Promise} Resolves to `true` when supported, otherwise `false`
*/
export function canImplyAuthentication(options?: Options): Promise {
export function canImplyAuthentication(options?: Options): Promise<boolean> {
if (!RNKeychainManager.canCheckAuthentication) {
return Promise.resolve(false);
}
@ -79,7 +66,7 @@ export function canImplyAuthentication(options?: Options): Promise {
* Get what type of hardware biometry support the device has.
* @return {Promise} Resolves to a `BIOMETRY_TYPE` when supported, otherwise `null`
*/
export function getSupportedBiometryType(): Promise {
export function getSupportedBiometryType(): Promise<?($Values<typeof BIOMETRY_TYPE>)> {
if (!RNKeychainManager.getSupportedBiometryType) {
return Promise.resolve(null);
}
@ -99,7 +86,7 @@ export function setInternetCredentials(
username: string,
password: string,
options?: Options
): Promise {
): Promise<void> {
return RNKeychainManager.setInternetCredentialsForServer(
server,
username,
@ -113,12 +100,15 @@ export function setInternetCredentials(
* @param {string} server URL to server.
* @return {Promise} Resolves to `true` when successful
*/
export function hasInternetCredentials(
server: string,
): Promise {
export function hasInternetCredentials(server: string): Promise<boolean> {
return RNKeychainManager.hasInternetCredentialsForServer(server);
}
export type UserCredentials = {|
+username: string,
+password: string,
|};
/**
* Fetches login combination for `server`.
* @param {string} server URL to server.
@ -128,7 +118,7 @@ export function hasInternetCredentials(
export function getInternetCredentials(
server: string,
options?: Options
): Promise {
): Promise<UserCredentials> {
return RNKeychainManager.getInternetCredentialsForServer(server, options);
}
@ -141,7 +131,7 @@ export function getInternetCredentials(
export function resetInternetCredentials(
server: string,
options?: Options
): Promise {
): Promise<void> {
return RNKeychainManager.resetInternetCredentialsForServer(server, options);
}
@ -167,7 +157,7 @@ export function setGenericPassword(
username: string,
password: string,
serviceOrOptions?: string | Options
): Promise {
): Promise<boolean> {
return RNKeychainManager.setGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions),
username,
@ -175,6 +165,12 @@ export function setGenericPassword(
);
}
export type SharedWebCredentials = {|
+server: string,
+username: string,
+password: string,
|};
/**
* Fetches login combination for `service`.
* @param {string|object} serviceOrOptions Reverse domain name qualifier for the service, defaults to `bundleId` or an options object.
@ -182,7 +178,7 @@ export function setGenericPassword(
*/
export function getGenericPassword(
serviceOrOptions?: string | Options
): Promise {
): Promise<boolean | SharedWebCredentials> {
return RNKeychainManager.getGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions)
);
@ -195,7 +191,7 @@ export function getGenericPassword(
*/
export function resetGenericPassword(
serviceOrOptions?: string | Options
): Promise {
): Promise<boolean> {
return RNKeychainManager.resetGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions)
);
@ -206,7 +202,7 @@ export function resetGenericPassword(
* @return {Promise} Resolves to `{ server, username, password }` if approved and
* `false` if denied and throws an error if not supported on platform or there's no shared credentials
*/
export function requestSharedWebCredentials(): Promise {
export function requestSharedWebCredentials(): Promise<SharedWebCredentials> {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(
@ -228,7 +224,7 @@ export function setSharedWebCredentials(
server: string,
username: string,
password: string
): Promise {
): Promise<void> {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(

View File

@ -34,6 +34,7 @@
},
"license": "MIT",
"devDependencies": {
"flow-bin": "0.61.0"
"flow-bin": "0.78",
"react-native": "^0.57.4"
}
}

104
test_index.js Normal file
View File

@ -0,0 +1,104 @@
// @flow
import {
ACCESS_CONTROL,
ACCESSIBLE,
AUTHENTICATION_TYPE,
BIOMETRY_TYPE,
canImplyAuthentication,
getGenericPassword,
getInternetCredentials,
getSupportedBiometryType,
hasInternetCredentials,
requestSharedWebCredentials,
resetGenericPassword,
resetInternetCredentials,
setGenericPassword,
setInternetCredentials,
setSharedWebCredentials,
type Options,
type SharedWebCredentials,
} from 'react-native-keychain';
canImplyAuthentication().then(result => {
(result: boolean);
});
const simpleOptions2: Options = {
// $FlowExpectedError - not valid accessible value
accessible: 'ACCESSIBLE.ALWAYS',
};
const simpleOptions: Options = {
accessControl: ACCESS_CONTROL.BIOMETRY_ANY,
accessible: ACCESSIBLE.ALWAYS,
authenticationType: AUTHENTICATION_TYPE.BIOMETRICS,
accessGroup: 'accessGroup',
authenticationPrompt: 'authenticationPrompt',
service: 'service',
};
canImplyAuthentication(simpleOptions).then(result => {
(result: boolean);
});
getSupportedBiometryType().then(result => {
(result: ?string);
});
// $FlowExpectedError - First 3 arguments are required
setInternetCredentials();
setInternetCredentials('server', 'username', 'password');
setInternetCredentials('server', 'username', 'password', simpleOptions).then(
result => {
(result: void);
}
);
// $FlowExpectedError - First argument is required
hasInternetCredentials();
hasInternetCredentials('server').then(result => {
(result: boolean);
});
// $FlowExpectedError - First argument is required
getInternetCredentials();
getInternetCredentials('server', simpleOptions).then(credentials => {
(credentials.username: string);
(credentials.password: string);
});
// $FlowExpectedError - First argument is required
resetInternetCredentials();
resetInternetCredentials('server', simpleOptions).then(result => {
(result: void);
});
// $FlowExpectedError - First two arguments are required
setGenericPassword();
setGenericPassword('username', 'password').then(result => {
(result: boolean);
});
setGenericPassword('username', 'password', 'service');
setGenericPassword('username', 'password', simpleOptions);
getGenericPassword().then(result => {
(result: boolean | SharedWebCredentials);
});
getGenericPassword('service');
getGenericPassword(simpleOptions);
resetGenericPassword().then(result => {
(result: boolean);
});
resetGenericPassword('service');
resetGenericPassword(simpleOptions);
requestSharedWebCredentials().then(result => {
(result.server: string);
(result.username: string);
(result.password: string);
});
setSharedWebCredentials('server', 'username', 'password').then(result => {
(result: void);
});

4818
yarn.lock

File diff suppressed because it is too large Load Diff