feat(relay-compiler): add typings for relay compiler (#37576)

* feat(relay-compiler): add typings

* fix(relay-compiler): apply feedback by @PranavSenthilnathan

* revert imports for reporter modules

* fix(relay-compiler): apply feedback from @PranavSenthilnathan

* fix(relay-compile): apply feedback from @sheetalkamat (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37576#discussion_r316413227)

* fix(relay-compiler): apply feedback (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37576#discussion_r316738559)
This commit is contained in:
Laurin Quast
2019-08-22 10:58:18 -07:00
committed by Sheetal Nandi
parent edb01c0cf4
commit 859c748181
16 changed files with 520 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
// Type definitions for relay-compiler 5.0
// Project: https://relay.dev
// Definitions by: n1ru4l <https://github.com/n1ru4l>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.0
import { GraphQLCompilerContext } from './lib/GraphQLCompilerContext';
import * as ASTConvert from './lib/ASTConvert';
import * as Parser from './lib/RelayParser';
import * as Printer from './lib/GraphQLIRPrinter';
import ConsoleReporter = require('./lib/GraphQLConsoleReporter');
import MultiReporter = require('./lib/GraphQLMultiReporter');
declare var transformASTSchema: typeof ASTConvert.transformASTSchema;
export { GraphQLCompilerContext, ASTConvert, transformASTSchema, Parser, Printer, ConsoleReporter, MultiReporter };
+5
View File
@@ -0,0 +1,5 @@
import { GraphQLSchema } from 'graphql';
export function transformASTSchema(
schema: GraphQLSchema,
transforms: string[],
): GraphQLSchema;
+9
View File
@@ -0,0 +1,9 @@
import { GraphQLCompilerContext } from '../';
export interface FlattenOptions {
flattenAbstractTypes?: boolean;
}
export function transformWithOptions(
options: FlattenOptions,
): (context: GraphQLCompilerContext) => GraphQLCompilerContext;
+38
View File
@@ -0,0 +1,38 @@
import { GraphQLSchema } from 'graphql';
import { Root, Fragment, SplitOperation, Location } from './GraphQLIR';
import { GraphQLReporter } from './GraphQLReporter';
export type IRTransform = (
context: GraphQLCompilerContext,
) => GraphQLCompilerContext;
export type IRValidation = (contect: GraphQLCompilerContext) => void;
export type CompilerContextDocument = Fragment | Root | SplitOperation;
export class GraphQLCompilerContext {
constructor(serverSchema: GraphQLSchema, clientSchema?: GraphQLSchema);
documents(): ReadonlyArray<CompilerContextDocument>;
forEachDocument(fn: (doc: CompilerContextDocument) => void): void;
replace(node: CompilerContextDocument): GraphQLCompilerContext;
add(node: CompilerContextDocument): GraphQLCompilerContext;
addAll(nodes: ReadonlyArray<CompilerContextDocument>): GraphQLCompilerContext;
applyTransforms(
transforms: ReadonlyArray<IRTransform>,
reporter?: GraphQLReporter,
): GraphQLCompilerContext;
applyTransform(
transform: IRTransform,
reporter?: GraphQLReporter,
): GraphQLCompilerContext;
applyValidations(
validations: ReadonlyArray<IRValidation>,
reporter?: GraphQLReporter,
): void;
get(name: string): CompilerContextDocument | undefined;
getFragment(name: string, referencedFrom?: Location): Fragment;
getRoot(name: string): Root;
remove(name: string): GraphQLCompilerContext;
withMutations(
fn: (context: GraphQLCompilerContext) => GraphQLCompilerContext,
): GraphQLCompilerContext;
}
+9
View File
@@ -0,0 +1,9 @@
import { GraphQLReporter } from './GraphQLReporter';
declare class GraphQLMultiReporter implements GraphQLReporter {
reportMessage(message: string): void;
reportTime(name: string, ms: number): void;
reportError(caughtLocation: string, error: Error): void;
}
export = GraphQLMultiReporter;
+334
View File
@@ -0,0 +1,334 @@
import {
Source,
GraphQLInputType,
GraphQLOutputType,
GraphQLCompositeType,
GraphQLLeafType,
GraphQLList,
GraphQLNonNull,
} from 'graphql';
export type Metadata = { [key: string]: unknown } | undefined;
export interface SourceLocation {
kind: 'Source';
start: number;
end: number;
source: Source;
}
export interface GeneratedLocation {
kind: 'Generated';
}
export interface DerivedLocation {
kind: 'Derived';
source: Location;
}
export interface UnknownLocation {
kind: 'Unknown';
}
export type Location = SourceLocation | GeneratedLocation | DerivedLocation | UnknownLocation;
export interface Argument {
kind: 'Argument';
loc: Location;
metadata: Metadata;
name: string;
type?: GraphQLInputType;
value: ArgumentValue;
}
export type ArgumentDefinition = LocalArgumentDefinition | RootArgumentDefinition;
export type ArgumentValue = ListValue | Literal | ObjectValue | Variable;
export interface Condition {
condition: Literal | Variable;
kind: 'Condition';
loc: Location;
metadata: Metadata;
passingValue: boolean;
selections: ReadonlyArray<Selection>;
}
export interface Directive {
args: ReadonlyArray<Argument>;
kind: 'Directive';
loc: Location;
metadata: Metadata;
name: string;
}
export type Field = LinkedField | ScalarField | ConnectionField;
export interface Fragment {
argumentDefinitions: ReadonlyArray<ArgumentDefinition>;
directives: ReadonlyArray<Directive>;
kind: 'Fragment';
loc: Location;
metadata: Metadata;
name: string;
selections: ReadonlyArray<Selection>;
type: GraphQLCompositeType;
}
export interface FragmentSpread {
args: ReadonlyArray<Argument>;
directives: ReadonlyArray<Directive>;
kind: 'FragmentSpread';
loc: Location;
metadata: Metadata;
name: string;
}
export interface Defer {
kind: 'Defer';
loc: Location;
metadata: Metadata;
selections: ReadonlyArray<Selection>;
label: string;
if: ArgumentValue | null;
}
export interface Stream {
kind: 'Stream';
loc: Location;
metadata: Metadata;
selections: ReadonlyArray<Selection>;
label: string;
if: ArgumentValue | null;
initialCount: ArgumentValue;
}
export interface InlineDataFragmentSpread {
kind: 'InlineDataFragmentSpread';
loc: Location;
metadata: Metadata;
name: string;
selections: ReadonlyArray<Selection>;
}
export type IR =
| Argument
| ClientExtension
| Condition
| Defer
| ConnectionField
| Directive
| Fragment
| FragmentSpread
| InlineFragment
| LinkedField
| ListValue
| Literal
| LocalArgumentDefinition
| ModuleImport
| ObjectFieldValue
| ObjectValue
| Request
| Root
| RootArgumentDefinition
| ScalarField
| SplitOperation
| Stream
| InlineDataFragmentSpread
| Variable;
export interface RootArgumentDefinition {
kind: 'RootArgumentDefinition';
loc: Location;
metadata: Metadata;
name: string;
type: GraphQLInputType;
}
export interface InlineFragment {
directives: ReadonlyArray<Directive>;
kind: 'InlineFragment';
loc: Location;
metadata: Metadata;
selections: ReadonlyArray<Selection>;
typeCondition: GraphQLCompositeType;
}
export interface Handle {
name: string;
key: string;
dynamicKey: Variable | null;
filters?: Readonly<string>;
}
export interface ClientExtension {
kind: 'ClientExtension';
loc: Location;
metadata: Metadata;
selections: ReadonlyArray<Selection>;
}
export interface ConnectionField {
alias: string;
args: ReadonlyArray<Argument>;
directives: ReadonlyArray<Directive>;
kind: 'ConnectionField';
label: string;
loc: Location;
metadata: Metadata;
name: string;
resolver: string;
selections: ReadonlyArray<Selection>;
type: GraphQLOutputType;
}
export interface LinkedField {
alias: string;
args: ReadonlyArray<Argument>;
directives: ReadonlyArray<Directive>;
handles?: ReadonlyArray<Handle>;
kind: 'LinkedField';
loc: Location;
metadata: Metadata;
name: string;
selections: ReadonlyArray<Selection>;
type: GraphQLOutputType;
}
export interface ListValue {
kind: 'ListValue';
items: ReadonlyArray<ArgumentValue>;
loc: Location;
metadata: Metadata;
}
export interface Literal {
kind: 'Literal';
loc: Location;
metadata: Metadata;
value: unknown;
}
export interface LocalArgumentDefinition {
defaultValue: unknown;
kind: 'LocalArgumentDefinition';
loc: Location;
metadata: Metadata;
name: string;
type: GraphQLInputType;
}
export interface ModuleImport {
kind: 'ModuleImport';
loc: Location;
documentName: string;
module: string;
id: string;
name: string;
selections: ReadonlyArray<Selection>;
}
export type Node =
| ClientExtension
| Condition
| Defer
| ConnectionField
| Fragment
| InlineDataFragmentSpread
| InlineFragment
| LinkedField
| ModuleImport
| Root
| SplitOperation
| Stream;
export interface ObjectFieldValue {
kind: 'ObjectFieldValue';
loc: Location;
metadata: Metadata;
name: string;
value: ArgumentValue;
}
export interface ObjectValue {
kind: 'ObjectValue';
fields: ReadonlyArray<ObjectFieldValue>;
loc: Location;
metadata: Metadata;
}
export interface Request {
kind: 'Request';
fragment: Fragment;
id?: string;
loc: Location;
metadata: Metadata;
name: string;
root: Root;
text?: string;
}
export interface Root {
argumentDefinitions: Readonly<LocalArgumentDefinition>;
directives: Readonly<Directive>;
kind: 'Root';
loc: Location;
metadata: Metadata;
name: string;
operation: 'query' | 'mutation' | 'subscription';
selections: Readonly<Selection>;
type: GraphQLCompositeType;
}
// workaround for circular reference
// tslint:disable-next-line:no-empty-interface
export interface ScalarFieldTypeGraphQLList extends GraphQLList<ScalarFieldType> {}
export type ScalarFieldType =
| GraphQLLeafType
| ScalarFieldTypeGraphQLList
| GraphQLNonNull<GraphQLLeafType | ScalarFieldTypeGraphQLList>;
export interface ScalarField {
alias: string;
args: ReadonlyArray<Argument>;
directives: ReadonlyArray<Directive>;
handles?: ReadonlyArray<Handle>;
kind: 'ScalarField';
loc: Location;
metadata: Metadata;
name: string;
type: ScalarFieldType;
}
export type Selection =
| ClientExtension
| Condition
| Defer
| ConnectionField
| FragmentSpread
| InlineFragment
| LinkedField
| ModuleImport
| ScalarField
| InlineDataFragmentSpread
| Stream;
export type Definition = Fragment | Root | SplitOperation;
export type GeneratedDefinition = Fragment | Request | SplitOperation;
export interface SplitOperation {
kind: 'SplitOperation';
name: string;
selections: ReadonlyArray<Selection>;
loc: Location;
metadata: Metadata;
type: GraphQLCompositeType;
}
export interface Variable {
kind: 'Variable';
loc: Location;
metadata: Metadata;
variableName: string;
type?: GraphQLInputType;
}
+2
View File
@@ -0,0 +1,2 @@
import { CompilerContextDocument } from './GraphQLCompilerContext';
export function print(node: CompilerContextDocument): string;
+9
View File
@@ -0,0 +1,9 @@
import { GraphQLReporter } from './GraphQLReporter';
declare class GraphQLMultiReporter implements GraphQLReporter {
reportMessage(message: string): void;
reportTime(name: string, ms: number): void;
reportError(caughtLocation: string, error: Error): void;
}
export = GraphQLMultiReporter;
+5
View File
@@ -0,0 +1,5 @@
export interface GraphQLReporter {
reportMessage(message: string): void;
reportTime(name: string, ms: number): void;
reportError(caughtLocation: string, error: Error): void;
}
@@ -0,0 +1,5 @@
import { GraphQLCompilerContext } from '../';
export function transform(
context: GraphQLCompilerContext,
): GraphQLCompilerContext;
@@ -0,0 +1,5 @@
import { GraphQLCompilerContext } from '../';
export function transform(
context: GraphQLCompilerContext,
): GraphQLCompilerContext;
+13
View File
@@ -0,0 +1,13 @@
import { GraphQLSchema, DefinitionNode } from 'graphql';
import { Root, Fragment } from './GraphQLIR';
export function parse(
schema: GraphQLSchema,
text: string,
filename?: string,
): ReadonlyArray<Root | Fragment>;
export function transform(
schema: GraphQLSchema,
documents: DefinitionNode[],
): ReadonlyArray<Root | Fragment>;
@@ -0,0 +1,5 @@
import { GraphQLCompilerContext } from '../';
export function transform(
context: GraphQLCompilerContext,
): GraphQLCompilerContext;
@@ -0,0 +1,35 @@
import {
GraphQLCompilerContext,
transformASTSchema,
Parser as RelayParser,
Printer as GraphQLIRPrinter,
} from 'relay-compiler';
import * as InlineFragmentsTransform from 'relay-compiler/lib/InlineFragmentsTransform';
import * as SkipRedundantNodesTransform from 'relay-compiler/lib/SkipRedundantNodesTransform';
import * as RelayApplyFragmentArgumentTransform from 'relay-compiler/lib/RelayApplyFragmentArgumentTransform';
import * as FlattenTransform from 'relay-compiler/lib/FlattenTransform';
import { GraphQLSchema, DefinitionNode } from 'graphql';
const documentAsts: DefinitionNode[] = [];
const schema: GraphQLSchema = (undefined as any) as GraphQLSchema;
const adjustedSchema = transformASTSchema(schema, [
/* GraphQL */ `
directive @connection(key: String!) on FIELD
directive @client on FIELD
`,
]);
const relayDocuments = RelayParser.transform(adjustedSchema, documentAsts);
const queryCompilerContext = new GraphQLCompilerContext(adjustedSchema)
.addAll(relayDocuments)
.applyTransforms([
RelayApplyFragmentArgumentTransform.transform,
InlineFragmentsTransform.transform,
FlattenTransform.transformWithOptions({ flattenAbstractTypes: false }),
SkipRedundantNodesTransform.transform,
]);
queryCompilerContext.documents().map(doc => GraphQLIRPrinter.print(doc));
+28
View File
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"esnext.asynciterable"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"relay-compiler-tests.ts",
"lib/FlattenTransform.d.ts",
"lib/InlineFragmentsTransform.d.ts",
"lib/RelayApplyFragmentArgumentTransform.d.ts",
"lib/SkipRedundantNodesTransform.d.ts"
]
}
+1
View File
@@ -0,0 +1 @@
{ "extends": "dtslint/dt.json" }