Better flow config to remove unrelated errors

This commit is contained in:
Chris Bianca 2017-12-04 12:07:41 +00:00
parent ba79167c7f
commit 19cec2cd8b
18 changed files with 234 additions and 198 deletions

View File

@ -1,77 +1,37 @@
[ignore] [ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
.*/node_modules/react-native/\.buckd/
# Some modules have their own node_modules with overlap ; Ignore unexpected extra "@providesModule"
.*/node_modules/node-haste/.* .*/node_modules/.*/node_modules/fbjs/.*
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
; Ignore polyfills
.*/Libraries/polyfills/.*
# React Native problems # React Native problems
.*/node_modules/react-native/Libraries/Animated/src/AnimatedInterpolation.js .*/node_modules/metro-bundler/src/DeltaBundler/DeltaCalculator.js.flow
.*/node_modules/react-native/Libraries/Animated/src/Interpolation.js .*/node_modules/metro-bundler/src/DeltaBundler/DeltaPatcher.js.flow
.*/node_modules/react-native/Libraries/BugReporting/dumpReactTree.js .*/node_modules/metro-bundler/src/node-haste/AssetResolutionCache.js.flow
.*/node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js .*/node_modules/metro-bundler/src/node-haste/DependencyGraph.js.flow
.*/node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolater.js #.*/node_modules/react-native/Libraries/Animated/src/nodes/AnimatedStyle.js
.*/node_modules/react-native/Libraries/Experimental/WindowedListView.js #.*/node_modules/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js
.*/node_modules/react-native/Libraries/Image/Image.io.js #.*/node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js
.*/node_modules/react-native/Libraries/NavigationExperimental/NavigationExperimental.js #.*/node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableListView.js
.*/node_modules/react-native/Libraries/NavigationExperimental/NavigationHeaderStyleInterpolator.js #.*/node_modules/react-native/Libraries/Image/ImageBackground.js
.*/node_modules/react-native/Libraries/Network/FormData.js #.*/node_modules/react-native/Libraries/Lists/FlatList.js
.*/node_modules/react-native/Libraries/ReactIOS/YellowBox.js #.*/node_modules/react-native/Libraries/Lists/MetroListView.js
#.*/node_modules/react-native/Libraries/Lists/SectionList.js
#.*/node_modules/react-native/Libraries/Lists/ViewabilityHelper.js
#.*/node_modules/react-native/Libraries/Lists/VirtualizedList.js
# Ignore react and fbjs where there are overlaps, but don't ignore #.*/node_modules/react-native/Libraries/Lists/VirtualizedSectionList.js
# anything that react-native relies on
.*/node_modules/fbjs/lib/Map.js
.*/node_modules/fbjs/lib/ErrorUtils.js
# Flow has a built-in definition for the 'react' module which we prefer to use
# over the currently-untyped source
.*/node_modules/react/react.js
.*/node_modules/react/lib/React.js
.*/node_modules/react/lib/ReactDOM.js
.*/__mocks__/.*
.*/__tests__/.*
.*/commoner/test/source/widget/share.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
# See https://github.com/facebook/flow/issues/442
.*/react-tools/node_modules/commoner/lib/reader.js
# Ignore jest
.*/node_modules/jest-cli/.*
# Ignore Website
.*/website/.*
# Ignore generators
.*/local-cli/generator.*
# Ignore BUCK generated folders
.*\.buckd/
.*/node_modules/is-my-json-valid/test/.*\.json
.*/node_modules/iconv-lite/encodings/tables/.*\.json
.*/node_modules/y18n/test/.*\.json
.*/node_modules/spdx-license-ids/spdx-license-ids.json
.*/node_modules/spdx-exceptions/index.json
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
.*/node_modules/resolve/lib/core.json
.*/node_modules/jsonparse/samplejson/.*\.json
.*/node_modules/json5/test/.*\.json
.*/node_modules/ua-parser-js/test/.*\.json
.*/node_modules/builtin-modules/builtin-modules.json
.*/node_modules/binary-extensions/binary-extensions.json
.*/node_modules/url-regex/tlds.json
.*/node_modules/joi/.*\.json
.*/node_modules/isemail/.*\.json
.*/node_modules/tr46/.*\.json
.*/node_modules/protobufjs/src/bower.json
.*/node_modules/grpc/node_modules/protobufjs/src/bower.json
# Ignore dist folder # Ignore dist folder
.*/dist/.* .*/dist/.*
@ -80,34 +40,37 @@
.*/tests/.* .*/tests/.*
[include] [include]
node_modules/fbjs/lib
[libs] [libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow node_modules/react-native/flow/
node_modules/fbjs/flow/lib
[options] [options]
module.system=haste module.system=haste
experimental.strict_type_args=true emoji=true
unsafe.enable_getters_and_setters=true
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
munge_underscores=false munge_underscores=false
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.native.js
suppress_type=$FlowIssue suppress_type=$FlowIssue
suppress_type=$FlowFixMe suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FixMe suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-4]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-4]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 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]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version] [version]
^0.56.0 ^0.56.0

View File

@ -1,8 +1,19 @@
/** /**
* @flow * @flow
* Remote Config representation wrapper
*/ */
import ModuleBase from './../../utils/ModuleBase'; import ModuleBase from './../../utils/ModuleBase';
import type FirebaseApp from '../core/firebase-app';
type NativeValue = {
stringValue?: string,
numberValue?: number,
dataValue?: Object,
boolValue?: boolean,
source: 'remoteConfigSourceRemote' | 'remoteConfigSourceDefault' | ' remoteConfigSourceStatic',
}
/** /**
* @class Config * @class Config
*/ */
@ -10,9 +21,11 @@ export default class RemoteConfig extends ModuleBase {
static _NAMESPACE = 'config'; static _NAMESPACE = 'config';
static _NATIVE_MODULE = 'RNFirebaseRemoteConfig'; static _NATIVE_MODULE = 'RNFirebaseRemoteConfig';
constructor(firebaseApp: Object, options: Object = {}) { _developerModeEnabled: boolean;
constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options); super(firebaseApp, options);
this.developerModeEnabled = false; this._developerModeEnabled = false;
} }
/** /**
@ -21,7 +34,7 @@ export default class RemoteConfig extends ModuleBase {
* @returns {*} * @returns {*}
* @private * @private
*/ */
_nativeValueToJS(nativeValue) { _nativeValueToJS(nativeValue: NativeValue) {
return { return {
source: nativeValue.source, source: nativeValue.source,
val() { val() {
@ -37,10 +50,10 @@ export default class RemoteConfig extends ModuleBase {
* Enable Remote Config developer mode to allow for frequent refreshes of the cache * Enable Remote Config developer mode to allow for frequent refreshes of the cache
*/ */
enableDeveloperMode() { enableDeveloperMode() {
if (!this.developerModeEnabled) { if (!this._developerModeEnabled) {
this.log.debug('Enabled developer mode'); this.log.debug('Enabled developer mode');
this._native.enableDeveloperMode(); this._native.enableDeveloperMode();
this.developerModeEnabled = true; this._developerModeEnabled = true;
} }
} }

View File

@ -4,13 +4,14 @@
*/ */
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import type FirebaseApp from '../core/firebase-app';
import type { FirebaseError } from '../../types'; import type { FirebaseError } from '../../types';
export default class Crash extends ModuleBase { export default class Crash extends ModuleBase {
static _NAMESPACE = 'crash'; static _NAMESPACE = 'crash';
static _NATIVE_MODULE = 'RNFirebaseCrash'; static _NATIVE_MODULE = 'RNFirebaseCrash';
constructor(firebaseApp: Object, options: Object = {}) { constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options); super(firebaseApp, options);
} }

View File

@ -1,7 +1,10 @@
/* @flow */ /**
* @flow
* Disconnect representation wrapper
*/
import { typeOf } from './../../utils'; import { typeOf } from './../../utils';
import Reference from './reference'; import type Database from './';
import type Reference from './reference';
/** /**
@ -9,6 +12,7 @@ import Reference from './reference';
* @class Disconnect * @class Disconnect
*/ */
export default class Disconnect { export default class Disconnect {
_database: Database;
ref: Reference; ref: Reference;
path: string; path: string;

View File

@ -8,6 +8,8 @@ import Reference from './reference';
import TransactionHandler from './transaction'; import TransactionHandler from './transaction';
import ModuleBase from './../../utils/ModuleBase'; import ModuleBase from './../../utils/ModuleBase';
import type FirebaseApp from '../core/firebase-app';
/** /**
* @class Database * @class Database
*/ */
@ -15,7 +17,11 @@ export default class Database extends ModuleBase {
static _NAMESPACE = 'database'; static _NAMESPACE = 'database';
static _NATIVE_MODULE = 'RNFirebaseDatabase'; static _NATIVE_MODULE = 'RNFirebaseDatabase';
constructor(firebaseApp: Object, options: Object = {}) { _offsetRef: Reference;
_serverTimeOffset: number;
_transactionHandler: TransactionHandler;
constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options, true); super(firebaseApp, options, true);
this._transactionHandler = new TransactionHandler(this); this._transactionHandler = new TransactionHandler(this);
@ -40,21 +46,21 @@ export default class Database extends ModuleBase {
* *
* @return {number} * @return {number}
*/ */
getServerTime() { getServerTime(): number {
return new Date(Date.now() + this._serverTimeOffset); return new Date(Date.now() + this._serverTimeOffset);
} }
/** /**
* *
*/ */
goOnline() { goOnline(): void {
this._native.goOnline(); this._native.goOnline();
} }
/** /**
* *
*/ */
goOffline() { goOffline(): void {
this._native.goOffline(); this._native.goOffline();
} }
@ -63,7 +69,7 @@ export default class Database extends ModuleBase {
* @param path * @param path
* @returns {Reference} * @returns {Reference}
*/ */
ref(path: string) { ref(path: string): Reference {
return new Reference(this, path); return new Reference(this, path);
} }
} }
@ -72,9 +78,9 @@ export const statics = {
ServerValue: NativeModules.RNFirebaseDatabase ? { ServerValue: NativeModules.RNFirebaseDatabase ? {
TIMESTAMP: NativeModules.RNFirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' }, TIMESTAMP: NativeModules.RNFirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' },
} : {}, } : {},
enableLogging(bool) { enableLogging(enabled: boolean) {
if (NativeModules[Database._NATIVE_MODULE]) { if (NativeModules[Database._NATIVE_MODULE]) {
NativeModules[Database._NATIVE_MODULE].enableLogging(bool); NativeModules[Database._NATIVE_MODULE].enableLogging(enabled);
} }
}, },
}; };

View File

@ -1,11 +1,11 @@
/** /**
* @flow * @flow
* Query representation wrapper
*/ */
import Reference from './reference.js';
import { objectToUniqueId } from '../../utils'; import { objectToUniqueId } from '../../utils';
import type { DatabaseModifier } from '../../types'; import type { DatabaseModifier } from '../../types';
import type Reference from './reference.js';
// todo doc methods // todo doc methods
@ -13,6 +13,7 @@ import type { DatabaseModifier } from '../../types';
* @class Query * @class Query
*/ */
export default class Query { export default class Query {
_reference: Reference;
modifiers: Array<DatabaseModifier>; modifiers: Array<DatabaseModifier>;
constructor(ref: Reference, path: string, existingModifiers?: Array<DatabaseModifier>) { constructor(ref: Reference, path: string, existingModifiers?: Array<DatabaseModifier>) {
@ -28,7 +29,7 @@ export default class Query {
*/ */
orderBy(name: string, key?: string) { orderBy(name: string, key?: string) {
this.modifiers.push({ this.modifiers.push({
id: `orderBy-${name}:${key}`, id: `orderBy-${name}:${key || ''}`,
type: 'orderBy', type: 'orderBy',
name, name,
key, key,
@ -63,7 +64,7 @@ export default class Query {
*/ */
filter(name: string, value: any, key?: string) { filter(name: string, value: any, key?: string) {
this.modifiers.push({ this.modifiers.push({
id: `filter-${name}:${objectToUniqueId(value)}:${key}`, id: `filter-${name}:${objectToUniqueId(value)}:${key || ''}`,
type: 'filter', type: 'filter',
name, name,
value, value,

View File

@ -1,7 +1,7 @@
/** /**
* @flow * @flow
* Database Reference representation wrapper
*/ */
import Query from './query.js'; import Query from './query.js';
import Snapshot from './snapshot'; import Snapshot from './snapshot';
import Disconnect from './disconnect'; import Disconnect from './disconnect';
@ -20,6 +20,7 @@ import {
import INTERNALS from '../../utils/internals'; import INTERNALS from '../../utils/internals';
import type { DatabaseModifier, FirebaseError } from '../../types'; import type { DatabaseModifier, FirebaseError } from '../../types';
import type SyncTree from '../../utils/SyncTree';
// track all event registrations by path // track all event registrations by path
let listeners = 0; let listeners = 0;
@ -72,10 +73,10 @@ type DatabaseListener = {
* @extends ReferenceBase * @extends ReferenceBase
*/ */
export default class Reference extends ReferenceBase { export default class Reference extends ReferenceBase {
_refListeners: { [listenerId: number]: DatabaseListener };
_database: Object; _database: Object;
_promise: ?Promise<*>;
_query: Query; _query: Query;
_refListeners: { [listenerId: number]: DatabaseListener };
constructor(database: Object, path: string, existingModifiers?: Array<DatabaseModifier>) { constructor(database: Object, path: string, existingModifiers?: Array<DatabaseModifier>) {
super(path, database); super(path, database);
@ -96,7 +97,7 @@ export default class Reference extends ReferenceBase {
* @param bool * @param bool
* @returns {*} * @returns {*}
*/ */
keepSynced(bool: boolean) { keepSynced(bool: boolean): Promise<void> {
return this._database._native.keepSynced(this._getRefKey(), this.path, this._query.getModifiers(), bool); return this._database._native.keepSynced(this._getRefKey(), this.path, this._query.getModifiers(), bool);
} }
@ -108,7 +109,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @returns {Promise} * @returns {Promise}
*/ */
set(value: any, onComplete?: Function): Promise { set(value: any, onComplete?: Function): Promise<void> {
return promiseOrCallback( return promiseOrCallback(
this._database._native.set(this.path, this._serializeAnyType(value)), this._database._native.set(this.path, this._serializeAnyType(value)),
onComplete, onComplete,
@ -123,7 +124,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @returns {Promise} * @returns {Promise}
*/ */
setPriority(priority: string | number | null, onComplete?: Function): Promise { setPriority(priority: string | number | null, onComplete?: Function): Promise<void> {
const _priority = this._serializeAnyType(priority); const _priority = this._serializeAnyType(priority);
return promiseOrCallback( return promiseOrCallback(
@ -141,7 +142,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @returns {Promise} * @returns {Promise}
*/ */
setWithPriority(value: any, priority: string | number | null, onComplete?: Function): Promise { setWithPriority(value: any, priority: string | number | null, onComplete?: Function): Promise<void> {
const _value = this._serializeAnyType(value); const _value = this._serializeAnyType(value);
const _priority = this._serializeAnyType(priority); const _priority = this._serializeAnyType(priority);
@ -159,7 +160,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @returns {Promise} * @returns {Promise}
*/ */
update(val: Object, onComplete?: Function): Promise { update(val: Object, onComplete?: Function): Promise<void> {
const value = this._serializeObject(val); const value = this._serializeObject(val);
return promiseOrCallback( return promiseOrCallback(
@ -175,7 +176,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @return {Promise} * @return {Promise}
*/ */
remove(onComplete?: Function): Promise { remove(onComplete?: Function): Promise<void> {
return promiseOrCallback( return promiseOrCallback(
this._database._native.remove(this.path), this._database._native.remove(this.path),
onComplete, onComplete,
@ -196,16 +197,14 @@ export default class Reference extends ReferenceBase {
applyLocally: boolean = false, applyLocally: boolean = false,
) { ) {
if (!isFunction(transactionUpdate)) { if (!isFunction(transactionUpdate)) {
return Promise.reject( return Promise.reject(new Error('Missing transactionUpdate function argument.'));
new Error('Missing transactionUpdate function argument.'),
);
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const onCompleteWrapper = (error, committed, snapshotData) => { const onCompleteWrapper = (error, committed, snapshotData) => {
if (isFunction(onComplete)) { if (isFunction(onComplete)) {
if (error) { if (error) {
onComplete(error, committed, null); onComplete(error, committed, null);
} else { } else {
onComplete(null, committed, new Snapshot(this, snapshotData)); onComplete(null, committed, new Snapshot(this, snapshotData));
} }
@ -259,7 +258,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete * @param onComplete
* @returns {*} * @returns {*}
*/ */
push(value: any, onComplete?: Function): Reference | Promise { push(value: any, onComplete?: Function): Reference | Promise<void> {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return new Reference(this._database, `${this.path}/${generatePushID(this._database._serverTimeOffset)}`); return new Reference(this._database, `${this.path}/${generatePushID(this._database._serverTimeOffset)}`);
} }
@ -492,7 +491,7 @@ export default class Reference extends ReferenceBase {
* Access then method of promise if set * Access then method of promise if set
* @return {*} * @return {*}
*/ */
then(fnResolve, fnReject) { then(fnResolve: (any) => any, fnReject: (any) => any) {
if (isFunction(fnResolve) && this._promise && this._promise.then) { if (isFunction(fnResolve) && this._promise && this._promise.then) {
return this._promise.then.bind(this._promise)((result) => { return this._promise.then.bind(this._promise)((result) => {
this._promise = null; this._promise = null;
@ -515,7 +514,7 @@ export default class Reference extends ReferenceBase {
* Access catch method of promise if set * Access catch method of promise if set
* @return {*} * @return {*}
*/ */
catch(fnReject) { catch(fnReject: (any) => any) {
if (isFunction(fnReject) && this._promise && this._promise.catch) { if (isFunction(fnReject) && this._promise && this._promise.catch) {
return this._promise.catch.bind(this._promise)((possibleErr) => { return this._promise.catch.bind(this._promise)((possibleErr) => {
this._promise = null; this._promise = null;
@ -535,7 +534,7 @@ export default class Reference extends ReferenceBase {
* *
* @return {string} * @return {string}
*/ */
_getRegistrationKey(eventType) { _getRegistrationKey(eventType: string): string {
return `$${this._database._appName}$/${this.path}$${this._query.queryIdentifier()}$${listeners}$${eventType}`; return `$${this._database._appName}$/${this.path}$${this._query.queryIdentifier()}$${listeners}$${eventType}`;
} }
@ -546,7 +545,7 @@ export default class Reference extends ReferenceBase {
* @return {string} * @return {string}
* @private * @private
*/ */
_getRefKey() { _getRefKey(): string {
return `$${this._database._appName}$/${this.path}$${this._query.queryIdentifier()}`; return `$${this._database._appName}$/${this.path}$${this._query.queryIdentifier()}`;
} }
@ -562,7 +561,7 @@ export default class Reference extends ReferenceBase {
* @param promise * @param promise
* @private * @private
*/ */
_setThenable(promise) { _setThenable(promise: Promise<*>) {
this._promise = promise; this._promise = promise;
} }
@ -770,7 +769,7 @@ export default class Reference extends ReferenceBase {
return this._syncTree.removeListenersForRegistrations(registrations); return this._syncTree.removeListenersForRegistrations(registrations);
} }
get _syncTree() { get _syncTree(): SyncTree {
return INTERNALS.SyncTree; return INTERNALS.SyncTree;
} }
} }

View File

@ -1,15 +1,16 @@
/** /**
* @flow * @flow
* Snapshot representation wrapper
*/ */
import Reference from './reference.js';
import { isObject, deepGet, deepExists } from './../../utils'; import { isObject, deepGet, deepExists } from './../../utils';
import type Reference from './reference.js';
/** /**
* @class DataSnapshot * @class DataSnapshot
* @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot
*/ */
export default class Snapshot { export default class Snapshot {
ref: Object; ref: Reference;
key: string; key: string;
_value: any; _value: any;
@ -138,7 +139,7 @@ export default class Snapshot {
* @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#toJSON * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#toJSON
* @returns {any} * @returns {any}
*/ */
toJSON(): any { toJSON(): Object {
return this.val(); return this.val();
} }
} }

View File

@ -2,6 +2,7 @@
* @flow * @flow
* Database Transaction representation wrapper * Database Transaction representation wrapper
*/ */
import type Database from './';
let transactionId = 0; let transactionId = 0;
@ -9,7 +10,11 @@ let transactionId = 0;
* @class TransactionHandler * @class TransactionHandler
*/ */
export default class TransactionHandler { export default class TransactionHandler {
constructor(database: Object) { _database: Database;
_transactionListener: Function;
_transactions: { [string]: Object }
constructor(database: Database) {
this._transactions = {}; this._transactions = {};
this._database = database; this._database = database;

View File

@ -1,6 +1,12 @@
/**
* @flow
* Dynamic Links representation wrapper
*/
import ModuleBase from './../../utils/ModuleBase'; import ModuleBase from './../../utils/ModuleBase';
import { areObjectKeysContainedInOther, isObject, isString } from './../../utils'; import { areObjectKeysContainedInOther, isObject, isString } from './../../utils';
import type FirebaseApp from '../core/firebase-app';
const EVENT_TYPE = { const EVENT_TYPE = {
Link: 'dynamic_link_received', Link: 'dynamic_link_received',
}; };
@ -59,11 +65,11 @@ export default class Links extends ModuleBase {
static _NAMESPACE = 'links'; static _NAMESPACE = 'links';
static _NATIVE_MODULE = 'RNFirebaseLinks'; static _NATIVE_MODULE = 'RNFirebaseLinks';
constructor(firebaseApp: Object, options: Object = {}) { constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options, true); super(firebaseApp, options, true);
} }
get EVENT_TYPE() { get EVENT_TYPE(): Object {
return EVENT_TYPE; return EVENT_TYPE;
} }
@ -71,7 +77,7 @@ export default class Links extends ModuleBase {
* Returns the link that triggered application open * Returns the link that triggered application open
* @returns {Promise.<String>} * @returns {Promise.<String>}
*/ */
getInitialLink() { getInitialLink(): Promise<string> {
return this._native.getInitialLink(); return this._native.getInitialLink();
} }
@ -90,7 +96,7 @@ export default class Links extends ModuleBase {
* @param parameters * @param parameters
* @returns {Promise.<String>} * @returns {Promise.<String>}
*/ */
createDynamicLink(parameters: Object = {}): Promise<String> { createDynamicLink(parameters: Object = {}): Promise<string> {
try { try {
checkForMandatoryParameters(parameters); checkForMandatoryParameters(parameters);
validateParameters(parameters); validateParameters(parameters);

View File

@ -1,7 +1,13 @@
/**
* @flow
* Remote message representation wrapper
*/
import { isObject, generatePushID } from './../../utils'; import { isObject, generatePushID } from './../../utils';
export default class RemoteMessage { export default class RemoteMessage {
constructor(sender: String) { properties: Object;
constructor(sender: string) {
this.properties = { this.properties = {
id: generatePushID(), id: generatePushID(),
ttl: 3600, ttl: 3600,
@ -17,7 +23,7 @@ export default class RemoteMessage {
* @param ttl * @param ttl
* @returns {RemoteMessage} * @returns {RemoteMessage}
*/ */
setTtl(ttl: Number): RemoteMessage { setTtl(ttl: number): RemoteMessage {
this.properties.ttl = ttl; this.properties.ttl = ttl;
return this; return this;
} }
@ -74,7 +80,7 @@ export default class RemoteMessage {
return this; return this;
} }
toJSON() { toJSON(): Object {
return Object.assign({}, this.properties); return Object.assign({}, this.properties);
} }
} }

View File

@ -1,7 +1,13 @@
/**
* @flow
* Messaging representation wrapper
*/
import { Platform, NativeModules } from 'react-native'; import { Platform, NativeModules } from 'react-native';
import ModuleBase from './../../utils/ModuleBase'; import ModuleBase from './../../utils/ModuleBase';
import RemoteMessage from './RemoteMessage'; import RemoteMessage from './RemoteMessage';
import type FirebaseApp from '../core/firebase-app';
const EVENT_TYPE = { const EVENT_TYPE = {
RefreshToken: 'messaging_token_refreshed', RefreshToken: 'messaging_token_refreshed',
Notification: 'messaging_notification_received', Notification: 'messaging_notification_received',
@ -75,23 +81,23 @@ export default class Messaging extends ModuleBase {
static _NAMESPACE = 'messaging'; static _NAMESPACE = 'messaging';
static _NATIVE_MODULE = 'RNFirebaseMessaging'; static _NATIVE_MODULE = 'RNFirebaseMessaging';
constructor(firebaseApp: Object, options: Object = {}) { constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options, true); super(firebaseApp, options, true);
} }
get EVENT_TYPE() { get EVENT_TYPE(): Object {
return EVENT_TYPE; return EVENT_TYPE;
} }
get NOTIFICATION_TYPE() { get NOTIFICATION_TYPE(): Object {
return NOTIFICATION_TYPE; return NOTIFICATION_TYPE;
} }
get REMOTE_NOTIFICATION_RESULT() { get REMOTE_NOTIFICATION_RESULT(): Object {
return REMOTE_NOTIFICATION_RESULT; return REMOTE_NOTIFICATION_RESULT;
} }
get WILL_PRESENT_RESULT() { get WILL_PRESENT_RESULT(): Object {
return WILL_PRESENT_RESULT; return WILL_PRESENT_RESULT;
} }
@ -99,7 +105,7 @@ export default class Messaging extends ModuleBase {
* Returns the notification that triggered application open * Returns the notification that triggered application open
* @returns {*} * @returns {*}
*/ */
getInitialNotification() { getInitialNotification(): Promise<Object> {
return this._native.getInitialNotification(); return this._native.getInitialNotification();
} }
@ -107,7 +113,7 @@ export default class Messaging extends ModuleBase {
* Returns the fcm token for the current device * Returns the fcm token for the current device
* @returns {*|Promise.<String>} * @returns {*|Promise.<String>}
*/ */
getToken() { getToken(): Promise<string> {
return this._native.getToken(); return this._native.getToken();
} }
@ -115,7 +121,7 @@ export default class Messaging extends ModuleBase {
* Reset Instance ID and revokes all tokens. * Reset Instance ID and revokes all tokens.
* @returns {*|Promise.<*>} * @returns {*|Promise.<*>}
*/ */
deleteInstanceId() { deleteInstanceId(): Promise<void> {
return this._native.deleteInstanceId(); return this._native.deleteInstanceId();
} }
@ -124,7 +130,7 @@ export default class Messaging extends ModuleBase {
* @param notification * @param notification
* @returns {*} * @returns {*}
*/ */
createLocalNotification(notification: Object) { createLocalNotification(notification: Object): Promise<void> {
const _notification = Object.assign({}, notification); const _notification = Object.assign({}, notification);
_notification.id = _notification.id || new Date().getTime().toString(); _notification.id = _notification.id || new Date().getTime().toString();
_notification.local_notification = true; _notification.local_notification = true;
@ -136,7 +142,7 @@ export default class Messaging extends ModuleBase {
* @param notification * @param notification
* @returns {*} * @returns {*}
*/ */
scheduleLocalNotification(notification: Object) { scheduleLocalNotification(notification: Object): Promise<void> {
const _notification = Object.assign({}, notification); const _notification = Object.assign({}, notification);
if (!notification.id) return Promise.reject(new Error('An id is required to schedule a local notification.')); if (!notification.id) return Promise.reject(new Error('An id is required to schedule a local notification.'));
_notification.local_notification = true; _notification.local_notification = true;
@ -147,7 +153,7 @@ export default class Messaging extends ModuleBase {
* Returns an array of all scheduled notifications * Returns an array of all scheduled notifications
* @returns {Promise.<Array>} * @returns {Promise.<Array>}
*/ */
getScheduledLocalNotifications() { getScheduledLocalNotifications(): Promise<Object[]> {
return this._native.getScheduledLocalNotifications(); return this._native.getScheduledLocalNotifications();
} }
@ -157,8 +163,8 @@ export default class Messaging extends ModuleBase {
* @param id * @param id
* @returns {*} * @returns {*}
*/ */
cancelLocalNotification(id: string) { cancelLocalNotification(id: string): Promise<void> {
if (!id) return null; if (!id) return Promise.reject(new Error('Missing notification id'));
if (id === '*') return this._native.cancelAllLocalNotifications(); if (id === '*') return this._native.cancelAllLocalNotifications();
return this._native.cancelLocalNotification(id); return this._native.cancelLocalNotification(id);
} }
@ -169,8 +175,8 @@ export default class Messaging extends ModuleBase {
* @param id * @param id
* @returns {*} * @returns {*}
*/ */
removeDeliveredNotification(id: string) { removeDeliveredNotification(id: string): Promise<void> {
if (!id) return null; if (!id) return Promise.reject(new Error('Missing notification id'));
if (id === '*') return this._native.removeAllDeliveredNotifications(); if (id === '*') return this._native.removeAllDeliveredNotifications();
return this._native.removeDeliveredNotification(id); return this._native.removeDeliveredNotification(id);
} }
@ -180,7 +186,7 @@ export default class Messaging extends ModuleBase {
* @platforms ios * @platforms ios
* @returns {*|Promise.<*>} * @returns {*|Promise.<*>}
*/ */
requestPermissions() { requestPermissions(): Promise<void> {
return this._native.requestPermissions(); return this._native.requestPermissions();
} }
@ -189,7 +195,7 @@ export default class Messaging extends ModuleBase {
* Set notification count badge number * Set notification count badge number
* @param n * @param n
*/ */
setBadgeNumber(n: number) { setBadgeNumber(n: number): void {
this._native.setBadgeNumber(n); this._native.setBadgeNumber(n);
} }
@ -197,7 +203,7 @@ export default class Messaging extends ModuleBase {
* set notification count badge number * set notification count badge number
* @returns {Promise.<Number>} * @returns {Promise.<Number>}
*/ */
getBadgeNumber() { getBadgeNumber(): Promise<number> {
return this._native.getBadgeNumber(); return this._native.getBadgeNumber();
} }
@ -206,7 +212,7 @@ export default class Messaging extends ModuleBase {
* @param listener * @param listener
* @returns {*} * @returns {*}
*/ */
onMessage(listener: Function): () => any { onMessage(listener: (Object) => any): () => any {
const rnListener = this._eventEmitter.addListener( const rnListener = this._eventEmitter.addListener(
EVENT_TYPE.Notification, EVENT_TYPE.Notification,
async (event) => { async (event) => {
@ -229,7 +235,7 @@ export default class Messaging extends ModuleBase {
* @param listener * @param listener
* @returns {*} * @returns {*}
*/ */
onTokenRefresh(listener: Function): () => any { onTokenRefresh(listener: (string) => any): () => any {
const rnListener = this._eventEmitter.addListener(EVENT_TYPE.RefreshToken, listener); const rnListener = this._eventEmitter.addListener(EVENT_TYPE.RefreshToken, listener);
return () => rnListener.remove(); return () => rnListener.remove();
} }
@ -238,7 +244,7 @@ export default class Messaging extends ModuleBase {
* Subscribe to a topic * Subscribe to a topic
* @param topic * @param topic
*/ */
subscribeToTopic(topic: String) { subscribeToTopic(topic: string): void {
this._native.subscribeToTopic(topic); this._native.subscribeToTopic(topic);
} }
@ -246,7 +252,7 @@ export default class Messaging extends ModuleBase {
* Unsubscribe from a topic * Unsubscribe from a topic
* @param topic * @param topic
*/ */
unsubscribeFromTopic(topic: String) { unsubscribeFromTopic(topic: string): void {
this._native.unsubscribeFromTopic(topic); this._native.unsubscribeFromTopic(topic);
} }
@ -254,7 +260,7 @@ export default class Messaging extends ModuleBase {
* Send an upstream message * Send an upstream message
* @param remoteMessage * @param remoteMessage
*/ */
send(remoteMessage: RemoteMessage) { send(remoteMessage: RemoteMessage): Promise<void> {
if (!(remoteMessage instanceof RemoteMessage)) { if (!(remoteMessage instanceof RemoteMessage)) {
throw new Error('messaging().send requires an instance of RemoteMessage as the first argument.'); throw new Error('messaging().send requires an instance of RemoteMessage as the first argument.');
} }

View File

@ -1,19 +1,27 @@
export default class Trace { /**
* @flow
* Trace representation wrapper
*/
import type PerformanceMonitoring from './';
constructor(perf: Object, identifier: string) { export default class Trace {
identifier: string;
perf: PerformanceMonitoring;
constructor(perf: PerformanceMonitoring, identifier: string) {
this.perf = perf; this.perf = perf;
this.identifier = identifier; this.identifier = identifier;
} }
start() { start(): void {
this.perf._native.start(this.identifier); this.perf._native.start(this.identifier);
} }
stop() { stop(): void {
this.perf._native.stop(this.identifier); this.perf._native.stop(this.identifier);
} }
incrementCounter(event: string) { incrementCounter(event: string): void {
this.perf._native.incrementCounter(this.identifier, event); this.perf._native.incrementCounter(this.identifier, event);
} }
} }

View File

@ -1,14 +1,17 @@
// @flow /**
* @flow
* Performance monitoring representation wrapper
*/
import Trace from './Trace'; import Trace from './Trace';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import type FirebaseApp from '../core/firebase-app';
export default class PerformanceMonitoring extends ModuleBase { export default class PerformanceMonitoring extends ModuleBase {
static _NAMESPACE = 'perf'; static _NAMESPACE = 'perf';
static _NATIVE_MODULE = 'RNFirebasePerformance'; static _NATIVE_MODULE = 'RNFirebasePerformance';
_native: Object; constructor(firebaseApp: FirebaseApp, options: Object = {}) {
constructor(firebaseApp: Object, options: Object = {}) {
super(firebaseApp, options); super(firebaseApp, options);
} }
@ -17,15 +20,15 @@ export default class PerformanceMonitoring extends ModuleBase {
* @param enabled * @param enabled
* @returns {*} * @returns {*}
*/ */
setPerformanceCollectionEnabled(enabled: boolean) { setPerformanceCollectionEnabled(enabled: boolean): void {
return this._native.setPerformanceCollectionEnabled(enabled); this._native.setPerformanceCollectionEnabled(enabled);
} }
/** /**
* Returns a new trace instance * Returns a new trace instance
* @param trace * @param trace
*/ */
newTrace(trace: string): void { newTrace(trace: string): Trace {
return new Trace(this, trace); return new Trace(this, trace);
} }
} }

View File

@ -1,22 +1,27 @@
/* @flow */ /**
* @flow
* Storage representation wrapper
*/
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native';
import StorageRef from './reference'; import StorageRef from './reference';
import ModuleBase from './../../utils/ModuleBase'; import ModuleBase from './../../utils/ModuleBase';
import type FirebaseApp from '../core/firebase-app';
const FirebaseStorage = NativeModules.RNFirebaseStorage; const FirebaseStorage = NativeModules.RNFirebaseStorage;
export default class Storage extends ModuleBase { export default class Storage extends ModuleBase {
static _NAMESPACE = 'storage'; static _NAMESPACE = 'storage';
static _NATIVE_MODULE = 'RNFirebaseStorage'; static _NATIVE_MODULE = 'RNFirebaseStorage';
/** /**
* *
* @param firebaseApp * @param firebaseApp
* @param options * @param options
*/ */
constructor(firebaseApp: Object, options: Object = {}) { constructor(firebaseApp: FirebaseApp, options: Object = {}) {
super(firebaseApp, options, true); super(firebaseApp, options, true);
this._subscriptions = {};
this.addListener( this.addListener(
this._getAppEventName('storage_event'), this._getAppEventName('storage_event'),
@ -55,7 +60,7 @@ export default class Storage extends ModuleBase {
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime
* @param time The new maximum operation retry time in milliseconds. * @param time The new maximum operation retry time in milliseconds.
*/ */
setMaxOperationRetryTime(time: number) { setMaxOperationRetryTime(time: number): void {
this._native.setMaxOperationRetryTime(time); this._native.setMaxOperationRetryTime(time);
} }
@ -64,7 +69,7 @@ export default class Storage extends ModuleBase {
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime
* @param time The new maximum upload retry time in milliseconds. * @param time The new maximum upload retry time in milliseconds.
*/ */
setMaxUploadRetryTime(time: number) { setMaxUploadRetryTime(time: number): void {
this._native.setMaxUploadRetryTime(time); this._native.setMaxUploadRetryTime(time);
} }
@ -73,14 +78,14 @@ export default class Storage extends ModuleBase {
* @url N/A * @url N/A
* @param time The new maximum download retry time in milliseconds. * @param time The new maximum download retry time in milliseconds.
*/ */
setMaxDownloadRetryTime(time: number) { setMaxDownloadRetryTime(time: number): void {
this._native.setMaxDownloadRetryTime(time); this._native.setMaxDownloadRetryTime(time);
} }
/** ********** /**
* INTERNALS * INTERNALS
********** **/ */
_getSubEventName(path, eventName) { _getSubEventName(path: string, eventName: string) {
return this._getAppEventName(`${path}-${eventName}`); return this._getAppEventName(`${path}-${eventName}`);
} }
@ -93,18 +98,18 @@ export default class Storage extends ModuleBase {
} }
_handleStorageError(err: Object) { _handleStorageError(err: Object) {
const { path, eventName } = event; const { path, eventName } = err;
const body = event.body || {}; const body = err.body || {};
this.log.debug('_handleStorageError ->', err); this.log.debug('_handleStorageError ->', err);
this.emit(this._getSubEventName(path, eventName), body); this.emit(this._getSubEventName(path, eventName), body);
} }
_addListener(path: string, eventName: string, cb: (evt: Object) => Object) { _addListener(path: string, eventName: string, cb: (evt: Object) => Object): void {
this.on(this._getSubEventName(path, eventName), cb); this.on(this._getSubEventName(path, eventName), cb);
} }
_removeListener(path: string, eventName: string, origCB: (evt: Object) => Object) { _removeListener(path: string, eventName: string, origCB: (evt: Object) => Object): void {
this.removeListener(this._getSubEventName(path, eventName), origCB); this.removeListener(this._getSubEventName(path, eventName), origCB);
} }
} }

View File

@ -1,14 +1,18 @@
/* @flow */ /**
* @flow
* StorageReference representation wrapper
*/
import ReferenceBase from '../../utils/ReferenceBase'; import ReferenceBase from '../../utils/ReferenceBase';
import StorageTask, { UPLOAD_TASK, DOWNLOAD_TASK } from './task'; import StorageTask, { UPLOAD_TASK, DOWNLOAD_TASK } from './task';
import Storage from './'; import type Storage from './';
/** /**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference
*/ */
export default class StorageReference extends ReferenceBase { export default class StorageReference extends ReferenceBase {
_storage: Storage;
constructor(storage: Storage, path: string) { constructor(storage: Storage, path: string) {
super(path, storage); super(path, storage);
this._storage = storage; this._storage = storage;
@ -18,7 +22,7 @@ export default class StorageReference extends ReferenceBase {
return this.path; return this.path;
} }
toString(): String { toString(): string {
return `gs://${this._storage.app.options.storageBucket}${this.path}`; return `gs://${this._storage.app.options.storageBucket}${this.path}`;
} }
@ -27,24 +31,24 @@ export default class StorageReference extends ReferenceBase {
* @param path * @param path
* @returns {StorageReference} * @returns {StorageReference}
*/ */
child(path: string) { child(path: string): StorageReference {
return new StorageReference(this._module, `${this.path}/${path}`); return new StorageReference(this._storage, `${this.path}/${path}`);
} }
/** /**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete
* @returns {Promise.<T>|*} * @returns {Promise.<T>|*}
*/ */
delete(): Promise<*> { delete(): Promise<void> {
return this._module._native.delete(this.path); return this._storage._native.delete(this.path);
} }
/** /**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL
* @returns {Promise.<T>|*} * @returns {Promise.<T>|*}
*/ */
getDownloadURL(): Promise<String> { getDownloadURL(): Promise<string> {
return this._module._native.getDownloadURL(this.path); return this._storage._native.getDownloadURL(this.path);
} }
/** /**
@ -52,7 +56,7 @@ export default class StorageReference extends ReferenceBase {
* @returns {Promise.<T>|*} * @returns {Promise.<T>|*}
*/ */
getMetadata(): Promise<Object> { getMetadata(): Promise<Object> {
return this._module._native.getMetadata(this.path); return this._storage._native.getMetadata(this.path);
} }
/** /**
@ -61,7 +65,7 @@ export default class StorageReference extends ReferenceBase {
* @returns {Promise.<T>|*} * @returns {Promise.<T>|*}
*/ */
updateMetadata(metadata: Object = {}): Promise<Object> { updateMetadata(metadata: Object = {}): Promise<Object> {
return this._module._native.updateMetadata(this.path, metadata); return this._storage._native.updateMetadata(this.path, metadata);
} }
/** /**
@ -70,14 +74,14 @@ export default class StorageReference extends ReferenceBase {
* @return {Promise} * @return {Promise}
*/ */
downloadFile(filePath: string): Promise<Object> { downloadFile(filePath: string): Promise<Object> {
return new StorageTask(DOWNLOAD_TASK, this._module._native.downloadFile(this.path, filePath), this); return new StorageTask(DOWNLOAD_TASK, this._storage._native.downloadFile(this.path, filePath), this);
} }
/** /**
* Alias to putFile * Alias to putFile
* @returns {StorageReference.putFile} * @returns {StorageReference.putFile}
*/ */
get put(): Function { get put(): (Object, Object) => Promise<Object> {
return this.putFile; return this.putFile;
} }

View File

@ -1,7 +1,11 @@
/* @flow */ /**
* @flow
* UploadTask representation wrapper
*/
import { statics as StorageStatics } from './'; import { statics as StorageStatics } from './';
import { isFunction } from './../../utils'; import { isFunction } from './../../utils';
import StorageReference from './reference'; import type Storage from './';
import type StorageReference from './reference';
export const UPLOAD_TASK = 'upload'; export const UPLOAD_TASK = 'upload';
export const DOWNLOAD_TASK = 'download'; export const DOWNLOAD_TASK = 'download';
@ -40,15 +44,15 @@ declare type NextOrObserverType = null |
export default class StorageTask { export default class StorageTask {
type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK; type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK;
ref: StorageReference; ref: StorageReference;
storage: StorageReference.storage; storage: Storage;
path: StorageReference.path; path: string;
then: () => Promise<*>; then: () => Promise<*>;
catch: () => Promise<*>; catch: () => Promise<*>;
constructor(type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK, promise: Promise<*>, storageRef: StorageReference) { constructor(type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK, promise: Promise<*>, storageRef: StorageReference) {
this.type = type; this.type = type;
this.ref = storageRef; this.ref = storageRef;
this.storage = storageRef._module; this.storage = storageRef._storage;
this.path = storageRef.path; this.path = storageRef.path;
// 'proxy' original promise // 'proxy' original promise

View File

@ -106,6 +106,7 @@ export type DatabaseModule = {
} & DatabaseStatics; } & DatabaseStatics;
export type DatabaseModifier = { export type DatabaseModifier = {
id: string;
type: 'orderBy' | 'limit' | 'filter'; type: 'orderBy' | 'limit' | 'filter';
name?: string; name?: string;
key?: string; key?: string;