Skip to content

Commit

Permalink
done with basic typescript package
Browse files Browse the repository at this point in the history
fixed flow package
  • Loading branch information
dotansimha committed Feb 26, 2019
1 parent f69e3e0 commit 6bad5f5
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 104 deletions.
42 changes: 42 additions & 0 deletions packages/plugins/flow/src/flow-variables-to-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { OperationVariablesToObject, ScalarsMap, ConvertNameFn } from 'graphql-codegen-visitor-plugin-common';
import { TypeNode, Kind } from 'graphql';

export class FlowOperationVariablesToObject extends OperationVariablesToObject {
private clearOptional(str: string): string {
if (str.startsWith('?')) {
return str.replace(/^\?(.*?)$/i, '$1');
}

return str;
}

protected wrapAstTypeWithModifiers(baseType: string, typeNode: TypeNode): string {
if (typeNode.kind === Kind.NON_NULL_TYPE) {
const type = this.wrapAstTypeWithModifiers(baseType, typeNode.type);

return this.clearOptional(type);
} else if (typeNode.kind === Kind.LIST_TYPE) {
const innerType = this.wrapAstTypeWithModifiers(baseType, typeNode.type);

return `?Array<${innerType}>`;
} else {
return `?${baseType}`;
}
}

protected formatFieldString(fieldName: string, isNonNullType: boolean, hasDefaultValue: boolean): string {
if (hasDefaultValue || isNonNullType) {
return fieldName;
} else {
return `${fieldName}?`;
}
}

protected formatTypeString(fieldType: string, isNonNullType: boolean, hasDefaultValue: boolean): string {
if (hasDefaultValue && !isNonNullType) {
return this.clearOptional(fieldType);
}

return fieldType;
}
}
6 changes: 3 additions & 3 deletions packages/plugins/flow/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
NamedTypeNode
} from 'graphql';
import {
wrapAstTypeWithModifiers,
BaseVisitor,
DeclarationBlock,
wrapWithSingleQuotes,
Expand All @@ -18,6 +17,7 @@ import {
} from 'graphql-codegen-visitor-plugin-common';
import * as autoBind from 'auto-bind';
import { FlowPluginConfig } from './index';
import { FlowOperationVariablesToObject } from './flow-variables-to-object';

export interface FlowPluginParsedConfig extends ParsedConfig {
useFlowExactObjects: boolean;
Expand All @@ -32,9 +32,9 @@ export class FlowVisitor extends BaseVisitor<FlowPluginConfig, FlowPluginParsedC
} as FlowPluginParsedConfig);
autoBind(this);

this.setArgumentsTransformer(new FlowOperationVariablesToObject(this.config.scalars, this.convertName));
this.setDeclarationBlockConfig({
blockWrapper: this.config.useFlowExactObjects ? '|' : '',
wrapAstTypeWithModifiers: wrapAstTypeWithModifiers('?')
blockWrapper: this.config.useFlowExactObjects ? '|' : ''
});
}

Expand Down
46 changes: 46 additions & 0 deletions packages/plugins/typescript/src/typescript-variables-to-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { OperationVariablesToObject, ScalarsMap, ConvertNameFn } from 'graphql-codegen-visitor-plugin-common';
import { TypeNode, Kind } from 'graphql';

export class TypeScriptOperationVariablesToObject extends OperationVariablesToObject {
constructor(_scalars: ScalarsMap, _convertName: ConvertNameFn, private _avoidOptionals: boolean) {
super(_scalars, _convertName);
}

private clearOptional(str: string): string {
if (str.startsWith('Maybe')) {
return str.replace(/^Maybe<(.*?)>$/i, '$1');
}

return str;
}

protected wrapAstTypeWithModifiers(baseType: string, typeNode: TypeNode): string {
if (typeNode.kind === Kind.NON_NULL_TYPE) {
const type = this.wrapAstTypeWithModifiers(baseType, typeNode.type);

return this.clearOptional(type);
} else if (typeNode.kind === Kind.LIST_TYPE) {
const innerType = this.wrapAstTypeWithModifiers(baseType, typeNode.type);

return `Maybe<Array<${innerType}>>`;
} else {
return `Maybe<${baseType}>`;
}
}

protected formatFieldString(fieldName: string, isNonNullType: boolean, hasDefaultValue: boolean): string {
if (hasDefaultValue || isNonNullType || this._avoidOptionals) {
return fieldName;
} else {
return `${fieldName}?`;
}
}

protected formatTypeString(fieldType: string, isNonNullType: boolean, hasDefaultValue: boolean): string {
if (hasDefaultValue) {
return this.clearOptional(fieldType);
}

return fieldType;
}
}
20 changes: 13 additions & 7 deletions packages/plugins/typescript/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { indent, BaseVisitor, ParsedConfig } from 'graphql-codegen-visitor-plugi
import { TypeScriptPluginConfig } from './index';
import * as autoBind from 'auto-bind';
import { FieldDefinitionNode, NamedTypeNode, ListTypeNode, NonNullTypeNode } from 'graphql';
import { wrapAstTypeWithModifiers } from '../../visitor-plugin-common/src/utils';
import { TypeScriptOperationVariablesToObject } from './typescript-variables-to-object';

export interface TypeScriptPluginParsedConfig extends ParsedConfig {
avoidOptionals: boolean;
Expand All @@ -11,15 +11,21 @@ export interface TypeScriptPluginParsedConfig extends ParsedConfig {

export class TsVisitor extends BaseVisitor<TypeScriptPluginConfig, TypeScriptPluginParsedConfig> {
constructor(pluginConfig: TypeScriptPluginConfig = {}) {
super(pluginConfig, {
avoidOptionals: pluginConfig.avoidOptionals || false,
maybeValue: pluginConfig.maybeValue || 'T | null'
} as TypeScriptPluginParsedConfig);
super(
pluginConfig,
{
avoidOptionals: pluginConfig.avoidOptionals || false,
maybeValue: pluginConfig.maybeValue || 'T | null'
} as TypeScriptPluginParsedConfig,
null
);

autoBind(this);
this.setArgumentsTransformer(
new TypeScriptOperationVariablesToObject(this.scalars, this.convertName, this.config.avoidOptionals)
);
this.setDeclarationBlockConfig({
enumNameValueSeparator: ' =',
wrapAstTypeWithModifiers: wrapAstTypeWithModifiers('')
enumNameValueSeparator: ' ='
});
}

Expand Down
81 changes: 51 additions & 30 deletions packages/plugins/typescript/tests/typescript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,41 +284,49 @@ describe('TypeScript', () => {
const result = await plugin(schema, [], { namingConvention: 'change-case#lowerCase' }, { outputFile: '' });

expect(result).toBeSimilarStringTo(`
export enum myenumvalues {
export enum myenum {
a = 'A',
b = 'B',
c = 'C'
}
`);
expect(result).toBeSimilarStringTo(`
export type mytype = {
f?: Maybe<string>,
bar?: Maybe<myenum>,
b_a_r?: Maybe<string>,
myOtherField?: Maybe<string>,
};
`);
expect(result).toBeSimilarStringTo(`
export type my_type = {
linkTest?: Maybe<mytype>,
};
`);
expect(result).toBeSimilarStringTo(`
export type myunion = my_type | mytype;
`);
expect(result).toBeSimilarStringTo(`
export type some_interface = {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type impl1 = some_interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type impl_2 = some_interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type impl_3 = some_interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type query = {
something?: Maybe<myunion>,
use_interface?: Maybe<some_interface>,
Expand All @@ -337,36 +345,44 @@ describe('TypeScript', () => {
B = 'B',
C = 'C'
}
`);
expect(result).toBeSimilarStringTo(`
export type MyType = {
f?: Maybe<string>,
bar?: Maybe<MyEnum>,
b_a_r?: Maybe<string>,
myOtherField?: Maybe<string>,
};
`);
expect(result).toBeSimilarStringTo(`
export type My_Type = {
linkTest?: Maybe<MyType>,
};
`);
expect(result).toBeSimilarStringTo(`
export type MyUnion = My_Type | MyType;
`);
expect(result).toBeSimilarStringTo(`
export type Some_Interface = {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type Impl1 = Some_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type Impl_2 = Some_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type Impl_3 = Some_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type Query = {
something?: Maybe<MyUnion>,
use_interface?: Maybe<Some_Interface>,
Expand All @@ -384,37 +400,42 @@ describe('TypeScript', () => {
IA = 'A',
IB = 'B',
IC = 'C'
}
};`);

expect(result).toBeSimilarStringTo(`
export type IMyType = {
f?: Maybe<string>,
bar?: Maybe<IMyEnum>,
b_a_r?: Maybe<string>,
myOtherField?: Maybe<string>,
};
};`);
expect(result).toBeSimilarStringTo(`
export type IMy_Type = {
linkTest?: Maybe<IMyType>,
};
export type IMyUnion = IMy_Type | IMyType;
`);
expect(result).toBeSimilarStringTo(`export type IMyUnion = IMy_Type | IMyType;`);
expect(result).toBeSimilarStringTo(`
export type ISome_Interface = {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type IImpl1 = ISome_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type IImpl_2 = ISome_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type IImpl_3 = ISome_Interface & {
id: string,
};
`);
expect(result).toBeSimilarStringTo(`
export type IQuery = {
something?: Maybe<IMyUnion>,
use_interface?: Maybe<ISome_Interface>,
Expand Down Expand Up @@ -497,8 +518,8 @@ describe('TypeScript', () => {
};
export type TMutationFooArgs = {
id?: string,
input?: TInput
id?: Maybe<string>,
input?: Maybe<TInput>
};
`);

Expand Down
31 changes: 11 additions & 20 deletions packages/plugins/visitor-plugin-common/src/base-visitor.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { ScalarsMap, EnumValuesMap } from './types';
import {
toPascalCase,
DeclarationBlock,
indent,
wrapAstTypeWithModifiers,
wrapWithSingleQuotes,
DeclarationBlockConfig
} from './utils';
import { toPascalCase, DeclarationBlock, indent, wrapWithSingleQuotes, DeclarationBlockConfig } from './utils';
import { resolveExternalModuleAndFn } from 'graphql-codegen-plugin-helpers';
import * as autoBind from 'auto-bind';
import {
Expand Down Expand Up @@ -44,24 +37,28 @@ export interface RawConfig {

export class BaseVisitor<TRawConfig extends RawConfig = RawConfig, TPluginConfig extends ParsedConfig = ParsedConfig> {
protected _parsedConfig: TPluginConfig;
protected _declarationBlockConfig: DeclarationBlockConfig = {
wrapAstTypeWithModifiers: wrapAstTypeWithModifiers('')
};
protected _argumentsTransformer: OperationVariablesToObject;
protected _declarationBlockConfig: DeclarationBlockConfig = {};

constructor(rawConfig: TRawConfig, additionalConfig: TPluginConfig, defaultScalars: ScalarsMap = DEFAULT_SCALARS) {
this._parsedConfig = {
scalars: { ...defaultScalars, ...(rawConfig.scalars || {}) },
scalars: { ...(defaultScalars || DEFAULT_SCALARS), ...(rawConfig.scalars || {}) },
enumValues: rawConfig.enumValues || {},
convert: rawConfig.namingConvention ? resolveExternalModuleAndFn(rawConfig.namingConvention) : toPascalCase,
typesPrefix: rawConfig.typesPrefix || '',
...((additionalConfig || {}) as any)
};

autoBind(this);
this._argumentsTransformer = new OperationVariablesToObject(this.scalars, this.convertName);
}

setDeclarationBlockConfig(config: DeclarationBlockConfig): void {
this._declarationBlockConfig = config || {};
this._declarationBlockConfig = config;
}

setArgumentsTransformer(argumentsTransfomer: OperationVariablesToObject): void {
this._argumentsTransformer = argumentsTransfomer;
}

get config(): TPluginConfig {
Expand Down Expand Up @@ -150,18 +147,12 @@ export class BaseVisitor<TRawConfig extends RawConfig = RawConfig, TPluginConfig
const fieldsWithArguments = original.fields.filter(field => field.arguments && field.arguments.length > 0);
const fieldsArguments = fieldsWithArguments.map(field => {
const name = original.name.value + this.convertName(field.name.value, false) + 'Args';
const transformedArguments = new OperationVariablesToObject<InputValueDefinitionNode>(
this.scalars,
this.convertName,
field.arguments,
this._declarationBlockConfig.wrapAstTypeWithModifiers
);

return new DeclarationBlock(this._declarationBlockConfig)
.export()
.asKind('type')
.withName(this.convertName(name))
.withBlock(transformedArguments.string).string;
.withBlock(this._argumentsTransformer.transform<InputValueDefinitionNode>(field.arguments)).string;
});

return [typeDefinition, ...fieldsArguments].filter(f => f).join('\n\n');
Expand Down
Loading

0 comments on commit 6bad5f5

Please sign in to comment.