diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 0000000000..c2a4545473 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,12 @@ +[ignore] +.*/examples/**/.* +.*/node_modules/art/.* +.*/node_modules/react-native/**/.* + +[include] + +[libs] +./index.js.flow + +[options] +suppress_comment= \\(.\\|\n\\)*\\$ExpectError diff --git a/index.js.flow b/index.js.flow index 94efad898d..dca467b241 100644 --- a/index.js.flow +++ b/index.js.flow @@ -36,7 +36,7 @@ declare module "react-apollo" { render(): React$Element<*>, } declare export type MutationFunc = ( - opts: MutationOptions + opts: MutationOpts ) => Promise>; declare export type DefaultChildProps = { @@ -44,13 +44,13 @@ declare module "react-apollo" { mutate: MutationFunc, } & P; - declare export interface MutationOptions { + declare export interface MutationOpts { variables?: { [key: string]: mixed }, optimisticResponse?: Object, updateQueries?: MutationQueryReducersMap, } - declare export interface QueryOptions { + declare export interface QueryOpts { ssr?: boolean, variables?: { [key: string]: mixed, @@ -87,7 +87,7 @@ declare module "react-apollo" { declare export type OptionDescription

= ( props: P - ) => QueryOptions | MutationOptions; + ) => QueryOpts | MutationOpts; declare export interface OperationOption { options?: OptionDescription, diff --git a/package.json b/package.json index 34ca3e9dd0..b64b695b54 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "test-watch": "jest --watch", "posttest": "npm run lint", "filesize": "npm run compile:browser && ./scripts/filesize.js --file=./dist/index.min.js --maxGzip=20", + "flow-check": "flow check", "compile": "tsc", "bundle": "rollup -c && rollup -c rollup.browser.config.js && rollup -c rollup.test-utils.config.js && cp ./index.js.flow ./lib", "compile:browser": "rm -rf ./dist && mkdir ./dist && browserify ./lib/react-apollo.browser.umd.js --i graphql-tag --i react --i apollo-client -o=./dist/index.js && npm run minify:browser && npm run compress:browser", @@ -54,9 +55,10 @@ "json" ], "modulePathIgnorePatterns": [ - "/examples" + "/examples", + "/test/flow.js" ], -"testRegex": "(/test/.*|\\.(test|spec))\\.(ts|tsx|js)$", + "testRegex": "(/test/.*|\\.(test|spec))\\.(ts|tsx|js)$", "collectCoverage": true }, "license": "MIT", diff --git a/src/browser.ts b/src/browser.ts index f34428eb8d..fd8c7160c5 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -1,5 +1,14 @@ export { default as ApolloProvider } from './ApolloProvider'; -export { default as graphql } from './graphql'; +export { + default as graphql, + MutationOpts, + QueryOpts, + QueryProps, + MutationFunc, + OptionProps, + DefaultChildProps, + OperationOption, + } from './graphql'; export { withApollo } from './withApollo'; // expose easy way to join queries from redux diff --git a/src/graphql.tsx b/src/graphql.tsx index ad48c81f8a..a68ec8c219 100644 --- a/src/graphql.tsx +++ b/src/graphql.tsx @@ -35,13 +35,13 @@ import { import { parser, DocumentType } from './parser'; -export declare interface MutationOptions { +export declare interface MutationOpts { variables?: Object; optimisticResponse?: Object; updateQueries?: MutationQueryReducersMap; } -export declare interface QueryOptions { +export declare interface QueryOpts { ssr?: boolean; variables?: { [key: string]: any }; fetchPolicy?: FetchPolicy; @@ -65,7 +65,7 @@ export interface QueryProps { updateQuery: (mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any) => void; } -export type MutationFunc = (opts: MutationOptions) => Promise>; +export type MutationFunc = (opts: MutationOpts) => Promise>; export interface OptionProps { ownProps: TProps; @@ -76,7 +76,7 @@ export interface OptionProps { export type DefaultChildProps = P & { data?: QueryProps & R, mutate?: MutationFunc }; export interface OperationOption { - options?: QueryOptions | MutationOptions | ((props: TProps) => QueryOptions | MutationOptions); + options?: QueryOpts | MutationOpts | ((props: TProps) => QueryOpts | MutationOpts); props?: (props: OptionProps) => any; skip?: boolean | ((props: any) => boolean); name?: string; @@ -131,7 +131,7 @@ export default function graphql QueryOptions | MutationOptions; + let mapPropsToOptions = options as (props: any) => QueryOpts | MutationOpts; if (typeof mapPropsToOptions !== 'function') mapPropsToOptions = () => options; let mapPropsToSkip = skip as (props: any) => boolean; @@ -329,12 +329,12 @@ export default function graphql { + return (mutationOpts: MutationOpts) => { const opts = this.calculateOptions(this.props, mutationOpts); if (typeof opts.variables === 'undefined') delete opts.variables; @@ -626,7 +626,7 @@ class ObservableQueryRecycler { * All mutations that occured between the time of recycling and the time of * reusing have been applied. */ - public reuse (options: QueryOptions): ObservableQuery { + public reuse (options: QueryOpts): ObservableQuery { if (this.observableQueries.length <= 0) { return null; } diff --git a/src/withApollo.tsx b/src/withApollo.tsx index e97dbd082a..81637cea08 100644 --- a/src/withApollo.tsx +++ b/src/withApollo.tsx @@ -33,8 +33,6 @@ import { import { parser, DocumentType } from './parser'; import { OperationOption, - MutationOptions, - QueryOptions, } from './graphql'; function getDisplayName(WrappedComponent) { diff --git a/test/flow.js b/test/flow.js new file mode 100644 index 0000000000..4c1fb0d3e9 --- /dev/null +++ b/test/flow.js @@ -0,0 +1,34 @@ +/* + + This file is used to validate the flow typings for react-apollo. + Currently it just serves as a smoke test around used imports and + common usage patterns. + + Ideally this should include tests for all of the functionality of + react-apollo + +*/ + +// @flow +import { graphql } from "react-apollo"; +import type { OperationComponent } from "react-apollo"; +import type { DocumentNode } from "graphql"; +import gql from "graphql-tag"; + +const query: DocumentNode = gql`{ foo }`; +const mutation: DocumentNode = gql`mutation { foo }`; + +type IQuery = { + foo: string, +}; + +// common errors + +const withData: OperationComponent = graphql(query); + +const ComponentWithData = withData(({ data: { foo }}) => { + // $ExpectError + if (foo > 1) return ; + + return null; +});