apollographql / meteor-integration

🚀 meteor add apollo
http://dev.apollodata.com/core/meteor.html
108 stars 45 forks source link

Add TypeScript typings for 'meteor/apollo' #65

Closed KeithGillette closed 7 years ago

KeithGillette commented 7 years ago

Are there any TypeScript type definitions available for meteor-integration to overcome the TypeScript TS2307:Cannot find module 'meteor/apollo'. warning message? Any work-arounds? Thanks!

xavxyz commented 7 years ago

Hey @KeithGillette, did you find a workaround in the end?

How are you using TypeScript in your Meteor application?

KeithGillette commented 7 years ago

Hey @KeithGillette, did you find a workaround in the end?

Hi @xavcz: I have not found a work-around and still get the TypeScript warning.

How are you using TypeScript in your Meteor application?

I'm not sure I understand the question. Do you mean "What's your TypeScript-meteor build tooling?" or "How are you leveraging TypeScript to build a Meteor application?" If the former, I added TypeScript support using the Angular-Meteor Atmosphere package angular2-compilers.

xavxyz commented 7 years ago

So #84 won't help.

https://medium.com/@birkskyum/modern-meteor-development-with-typescript-introduction-836f2a89f79#.q8zjzgj0u

@lorensr much better understanding of TS now, cheers 🙆‍♂️

If I'm not mistaken, meteor-integration is an Atmosphere package, so I don't think that TypeScript will locate the typings, since it looks in node_modules/@types for external typings, which are installed via npm, as are, for example, the existing Meteor TypeScript typings, rather than included in this repository. In addition, I think the declarations file itself would need to declare a module 'meteor/apollo' to resolve #65.

@KeithGillette indeed, the types for meteor/apollo should be accessible from NPM.

Do you think you can make a PR to https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/meteor to create the 'meteor/apollo' module and the related functions (createMeteorNetworkInterface, meteorClientConfig, createApolloServer)? Or maybe to a new folder there?

KeithGillette commented 7 years ago

Thanks for the follow-up @xavcz. I'd love to help get a fix for this, but am not sure how to proceed.

According to the README for the Definitely Typed Meteor Type Definitions, they are automatically created from compiled Meteor code, so I don't think it would be welcome to just insert typings for meteor/apollo into the Definitely Typed meteor folder via a PR. However, according to the meteor-typings/meteor README, the meteor-typings organization is supposed to contain all available typings for Atmosphere packages, so perhaps that is the place to submit a pull request. If not, then directly creating a separate directory on a fork of Definitely Typed is probably appropriate.

Regardless, the good news is, after some additional research and experimentation, I was able to resolve this issue with the type definition file quoted below, which I cobbled together from the Apollo-Meteor Usage and API documentation.

meteor/apollo.d.ts

import { NetworkInterface } from 'apollo-client';
import { GraphQLSchema } from 'graphql';
import { ApolloStateSelector } from 'apollo-client/ApolloClient';
import { IdGetter, ResultTransformer, ResultComparator } from 'apollo-client/core/types';
import { CustomResolverMap } from 'apollo-client/data/readFromStore';
import { NetworkInterfaceOptions } from 'apollo-client/transport/networkInterface';

export function createMeteorNetworkInterface(uriOrInterfaceOpts: string | NetworkInterfaceOptions, secondArgOpts: NetworkInterfaceOptions): NetworkInterface;

export function meteorClientConfig(customClientConfig?: apolloClientConfig): any;

export function createApolloServer(customOptions: GraphQLOptions, customConfig?: customApolloServerConfig): void;

export interface GraphQLOptions {
    schema: GraphQLSchema;  // values to be used as context and rootValue in resolvers
    context?: any;
    rootValue?: any;    // function used to format errors before returning them to clients
    formatError?: () => any;    // additional validation rules to be applied to client-specified queries
    validationRules?: Array<() => any>; // function applied for each query in a batch to format parameters before passing them to `runQuery`
    formatParams?: () => any;   // function applied to each response before returning data to clients
    formatResponse?: () => any; // a boolean option that will trigger additional debug logging if execution errors occur
    debug?: boolean;
}

export interface apolloClientConfig {
    networkInterface?: NetworkInterface;
    reduxRootKey?: string;
    reduxRootSelector?: string | ApolloStateSelector;
    initialState?: any;
    dataIdFromObject?: IdGetter;
    resultTransformer?: ResultTransformer;
    resultComparator?: ResultComparator;
    ssrMode?: boolean;
    ssrForceFetchDelay?: number;
    addTypename?: boolean;
    customResolvers?: CustomResolverMap;
    connectToDevTools?: boolean;
    queryDeduplication?: boolean;
}

export interface customApolloServerConfig {
    path: string;
    configServer: () => any;
    graphiql: boolean;
    graphiqlPath: string;
    graphiqlOptions: graphiqlOptions;
}

export interface graphiqlOptions {
    endpointURL: string; // URL for the GraphQL endpoint this instance of GraphiQL serves
    query?: string; // optional query to pre-populate the GraphiQL UI with
    operationName?: string; // optional operationName to pre-populate the GraphiQL UI with
    variables?: {}; // optional variables to pre-populate the GraphiQL UI with
    result?: {}; // optional result to pre-populate the GraphiQL UI with
}

However, I am not conversant enough with creating TypeScript declaration files to know whether this is entirely correct nor where they should be published. I noticed that @barbatus, who maintains meteor typings, is also a contributor to this repository, so I'm tagging him in hopes he can provide some guidance.

csillag commented 7 years ago

Three things:

  1. ApolloClientConfig should be start with an upper case

  2. I think most of the fields here should be optional:

export interface customApolloServerConfig {
    path?: string;
    configServer?: () => any;
    graphiql?: boolean;
    graphiqlPath?: string;
    graphiqlOptions?: graphiqlOptions;
}
  1. Furthermore, I would add the following:
export interface ApolloServerOptions {
    schema: GraphQLSchema,
    context?: any,
    rootValue?: any,
    formatError?: Function,
    validationRules?: Array<ValidationRule>,
    formatParams?: Function,
    formatResponse?: Function,
    debug?: boolean,
}

export const createApolloServer: (options: ApolloServerOptions, config?: ApolloServerConfig) => void;
export const meteorClientConfig: (): ApolloClientConfig;        
KeithGillette commented 7 years ago

Thanks, @csillag. You're probably right about points 1 & 2. With regard to 3, I was just following the naming convention I found in the documentation for Apollo > Server > GraphQL server options, referenced in the Apollo > Meteor > API > create ApolloServer documentation, which uses GraphQLOptions instead of ApolloServerOptions (the latter being more parallel to ApolloServerConfig and my preference, as well). However, I'd defer it to the maintainers of this repository to choose final naming.

Regardless, the question still remains how best to get these typings packaged and published. As I said before, it looks to me like the meteor-typings organization might be the best spot to house them, but @barbatus hasn't weighed in on that. I see that @exKAZUu is the only person associated with that organization, so I'm tagging him in hopes he can provide some guidance.

KeithGillette commented 7 years ago

I tweaked the ambient type definitions file and created a Apollo-GraphQL-Meteor-Integration-Typings GitHub repository to share them. I started to follow the DefinitelyType contribution guide in hopes these can at some point be included in the DefinitelyTyped repository, but did not get to creating any tests per their requirements.

Regardless, it still seems to me that these should be housed in the meteor-typings organization, but I have not heard from @barbatus or @exKAZUu for guidance on that question.

exKAZUu commented 7 years ago

@KeithGillette I'm not sure what is the best way. Anyway, I can create a repo in meteor-typings organization for you if you want me to do so.

KeithGillette commented 7 years ago

If you don't know, @exKAZUu, then who does?! ;-)

I was just going by the Typings for Meteor README, which states:

If you want to install some Atmosphere package's typings, search for an appropriate repo in the current meteor-typings organization, which is supposed to contain all available typings of such type. If you have found that package's typings repo, go inside and read how to install typings. If not - you are very welcome to create new repo and contribute typings.

Are the repositories in meteor-typings only for ambient TypeScript definitions distributed via Typings or installed manually? Is there any automatic build that you do to get the typings in meteor-typings into DefinitelyTyped?

xavxyz commented 7 years ago

Looks like there is no progress on the DefinitelyTyped thing? Let's add a link to your repo in the docs 👌

KeithGillette commented 7 years ago

Thanks for the follow-up @xavcz.

I haven't gotten any substantive guidance from the maintainers of the meteor-typings organization on how they manage submission to DefinitelyTyped, so have not moved ahead with getting these TypeScript definitions published for broader consumption.

I have updated them to the best of my knowledge to match the meteor-integration module, so feel free to link to them, though I would value validation that they work for for someone, else, as I have only exercised a portion of them in my project and implemented no typings tests.

xavxyz commented 7 years ago

PR opened on docs 👍