@graphql-codegen/visitor-plugin-common
Advanced tools
Comparing version 1.0.7-alpha-91766652.13 to 1.0.7-alpha-9b2216ab.39
@@ -20,3 +20,6 @@ "use strict"; | ||
constructor(rawConfig, additionalConfig, _schema, scalars = scalars_1.DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ addTypename: !rawConfig.skipTypename }, (additionalConfig || {})), utils_1.buildScalars(_schema, scalars)); | ||
super(rawConfig, { | ||
addTypename: !rawConfig.skipTypename, | ||
...(additionalConfig || {}), | ||
}, utils_1.buildScalars(_schema, scalars)); | ||
this._schema = _schema; | ||
@@ -23,0 +26,0 @@ this._unnamedCounter = 1; |
@@ -5,3 +5,3 @@ import { ParsedConfig, RawConfig, BaseVisitor } from './base-visitor'; | ||
import { NameNode, ListTypeNode, NamedTypeNode, FieldDefinitionNode, ObjectTypeDefinitionNode, GraphQLSchema, NonNullTypeNode, UnionTypeDefinitionNode, ScalarTypeDefinitionNode, InterfaceTypeDefinitionNode } from 'graphql'; | ||
import { DirectiveDefinitionNode } from 'graphql'; | ||
import { DirectiveDefinitionNode, GraphQLOutputType } from 'graphql'; | ||
import { OperationVariablesToObject } from './variables-to-object'; | ||
@@ -78,2 +78,10 @@ import { ParsedMapper } from './mappers'; | ||
* ``` | ||
* | ||
* @example Wrap default types with Partial | ||
* You can also specify a custom wrapper for the original type, without overring the original generated types, use "{T}" to specify the identifier. (for flow, use `$Shape<{T}>`) | ||
* ```yml | ||
* plugins | ||
* config: | ||
* defaultMapper: Partial<{T}> | ||
* ``` | ||
*/ | ||
@@ -101,3 +109,24 @@ defaultMapper?: string; | ||
avoidOptionals?: boolean; | ||
/** | ||
* @name showUnusedMappers | ||
* @type boolean | ||
* @description Warns about unused mappers. | ||
* @default true | ||
* | ||
* @example | ||
* ```yml | ||
* generates: | ||
* path/to/file.ts: | ||
* plugins: | ||
* - typescript | ||
* - typescript-resolvers | ||
* config: | ||
* showUnusedMappers: true | ||
* ``` | ||
*/ | ||
showUnusedMappers?: boolean; | ||
} | ||
export declare type ResolverTypes = { | ||
[gqlType: string]: string; | ||
}; | ||
export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig = RawResolversConfig, TPluginConfig extends ParsedResolversConfig = ParsedResolversConfig> extends BaseVisitor<TRawConfig, TPluginConfig> { | ||
@@ -117,3 +146,13 @@ private _schema; | ||
}; | ||
protected _resolversTypes: ResolverTypes; | ||
constructor(rawConfig: TRawConfig, additionalConfig: TPluginConfig, _schema: GraphQLSchema, defaultScalars?: ScalarsMap); | ||
protected createResolversFields(): void; | ||
protected replaceFieldsInType(typeName: string, relevantFields: { | ||
fieldName: string; | ||
replaceWithType: string; | ||
}[]): string; | ||
protected applyMaybe(str: string): string; | ||
protected clearMaybe(str: string): string; | ||
protected wrapTypeWithModifiers(baseType: string, type: GraphQLOutputType): string; | ||
buildResolversTypes(): string; | ||
readonly schema: GraphQLSchema; | ||
@@ -135,5 +174,3 @@ readonly defaultMapperType: string; | ||
protected markMapperAsUsed(name: string): void; | ||
protected getTypeToUse(name: string, node: { | ||
name: any; | ||
}): string; | ||
protected getTypeToUse(name: string): string; | ||
FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): (parentName: string) => string; | ||
@@ -140,0 +177,0 @@ ObjectTypeDefinition(node: ObjectTypeDefinitionNode, key: string | number, parent: any): string; |
@@ -8,2 +8,3 @@ "use strict"; | ||
const graphql_1 = require("graphql"); | ||
const graphql_2 = require("graphql"); | ||
const variables_to_object_1 = require("./variables-to-object"); | ||
@@ -13,3 +14,9 @@ const mappers_1 = require("./mappers"); | ||
constructor(rawConfig, additionalConfig, _schema, defaultScalars = scalars_1.DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ contextType: mappers_1.parseMapper(rawConfig.contextType || 'any'), avoidOptionals: utils_1.getConfigValue(rawConfig.avoidOptionals, false), defaultMapper: rawConfig.defaultMapper ? mappers_1.parseMapper(rawConfig.defaultMapper || 'any') : null, mappers: mappers_1.transformMappers(rawConfig.mappers || {}) }, (additionalConfig || {})), utils_1.buildScalars(_schema, defaultScalars)); | ||
super(rawConfig, { | ||
contextType: mappers_1.parseMapper(rawConfig.contextType || 'any'), | ||
avoidOptionals: utils_1.getConfigValue(rawConfig.avoidOptionals, false), | ||
defaultMapper: rawConfig.defaultMapper ? mappers_1.parseMapper(rawConfig.defaultMapper || 'any') : null, | ||
mappers: mappers_1.transformMappers(rawConfig.mappers || {}), | ||
...(additionalConfig || {}), | ||
}, utils_1.buildScalars(_schema, defaultScalars)); | ||
this._schema = _schema; | ||
@@ -20,5 +27,88 @@ this._declarationBlockConfig = {}; | ||
this._usedMappers = {}; | ||
this._resolversTypes = {}; | ||
autoBind(this); | ||
this._variablesTransfomer = new variables_to_object_1.OperationVariablesToObject(this.scalars, this.convertName); | ||
this.createResolversFields(); | ||
} | ||
createResolversFields() { | ||
const allSchemaTypes = this._schema.getTypeMap(); | ||
this._resolversTypes = Object.keys(allSchemaTypes).reduce((prev, typeName) => { | ||
if (typeName.startsWith('__')) { | ||
return prev; | ||
} | ||
let shouldApplyOmit = false; | ||
if (this.config.mappers[typeName] && this.config.mappers[typeName].type) { | ||
this.markMapperAsUsed(typeName); | ||
prev[typeName] = this.config.mappers[typeName].type; | ||
} | ||
else if (this.config.defaultMapper && this.config.defaultMapper.type && !this.config.defaultMapper.type.includes('{T}')) { | ||
prev[typeName] = this.config.defaultMapper.type; | ||
} | ||
else if (this.config.scalars[typeName]) { | ||
prev[typeName] = this._getScalar(typeName); | ||
} | ||
else { | ||
shouldApplyOmit = true; | ||
prev[typeName] = this.convertName(typeName); | ||
} | ||
const schemaType = allSchemaTypes[typeName]; | ||
if ((shouldApplyOmit && prev[typeName] !== 'any' && graphql_1.isObjectType(schemaType)) || graphql_1.isInterfaceType(schemaType)) { | ||
const fields = schemaType.getFields(); | ||
const relevantFields = Object.keys(fields) | ||
.map(fieldName => { | ||
const field = fields[fieldName]; | ||
const baseType = utils_1.getBaseType(field.type); | ||
if (!this.config.mappers[baseType.name]) { | ||
return null; | ||
} | ||
return { | ||
fieldName, | ||
replaceWithType: this.wrapTypeWithModifiers(this.getTypeToUse(baseType.name), field.type), | ||
}; | ||
}) | ||
.filter(a => a); | ||
if (relevantFields.length > 0) { | ||
prev[typeName] = this.replaceFieldsInType(prev[typeName], relevantFields); | ||
} | ||
} | ||
if (!this.config.scalars[typeName] && !this.config.mappers[typeName] && this.config.defaultMapper && this.config.defaultMapper.type.includes('{T}')) { | ||
prev[typeName] = this.config.defaultMapper.type.replace('{T}', prev[typeName]); | ||
} | ||
return prev; | ||
}, {}); | ||
} | ||
replaceFieldsInType(typeName, relevantFields) { | ||
return `Omit<${typeName}, ${relevantFields.map(f => `'${f.fieldName}'`).join(' | ')}> & { ${relevantFields.map(f => `${f.fieldName}: ${f.replaceWithType}`).join(', ')} }`; | ||
} | ||
applyMaybe(str) { | ||
return `Maybe<${str}>`; | ||
} | ||
clearMaybe(str) { | ||
if (str.startsWith('Maybe')) { | ||
return str.replace(/Maybe<(.*?)>$/, '$1'); | ||
} | ||
return str; | ||
} | ||
wrapTypeWithModifiers(baseType, type) { | ||
if (graphql_1.isNonNullType(type)) { | ||
return this.clearMaybe(this.wrapTypeWithModifiers(baseType, type.ofType)); | ||
} | ||
else if (graphql_1.isListType(type)) { | ||
const innerType = this.wrapTypeWithModifiers(baseType, type.ofType); | ||
return this.applyMaybe(`Array<${innerType}>`); | ||
} | ||
else { | ||
return this.applyMaybe(baseType); | ||
} | ||
} | ||
buildResolversTypes() { | ||
return new utils_1.DeclarationBlock(this._declarationBlockConfig) | ||
.export() | ||
.asKind('type') | ||
.withName(this.convertName('ResolversTypes')) | ||
.withComment('Mapping between all available schema types and the resolvers types') | ||
.withBlock(Object.keys(this._resolversTypes) | ||
.map(typeName => utils_1.indent(`${typeName}: ${this._resolversTypes[typeName]},`)) | ||
.join('\n')).string; | ||
} | ||
get schema() { | ||
@@ -56,3 +146,7 @@ return this._schema; | ||
} | ||
groupedMappers[this.config.defaultMapper.source].push(this.config.defaultMapper.type); | ||
let identifier = this.config.defaultMapper.type; | ||
if (identifier.includes('{T}')) { | ||
identifier = identifier.replace(/<.*?>/g, ''); | ||
} | ||
groupedMappers[this.config.defaultMapper.source].push(identifier); | ||
} | ||
@@ -154,14 +248,5 @@ return Object.keys(groupedMappers).map(source => this.buildMapperImport(source, groupedMappers[source])); | ||
} | ||
getTypeToUse(name, node) { | ||
if (this.config.mappers[name]) { | ||
this.markMapperAsUsed(name); | ||
return this.config.mappers[name].type; | ||
} | ||
else if (this.config.defaultMapper) { | ||
return this.config.defaultMapper.type; | ||
} | ||
else if (this.config.scalars[name]) { | ||
return this._getScalar(name); | ||
} | ||
return this.convertName(typeof node.name === 'string' ? node.name : node.name.value); | ||
getTypeToUse(name) { | ||
const resolversType = this.convertName('ResolversTypes'); | ||
return `${resolversType}['${name}']`; | ||
} | ||
@@ -174,3 +259,3 @@ FieldDefinition(node, key, parent) { | ||
const realType = baseType.name.value; | ||
const typeToUse = this.getTypeToUse(realType, baseType); | ||
const typeToUse = this.getTypeToUse(realType); | ||
const mappedType = this._variablesTransfomer.wrapAstTypeWithModifiers(typeToUse, original.type); | ||
@@ -194,3 +279,3 @@ const subscriptionType = this._schema.getSubscriptionType(); | ||
}); | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
const block = new utils_1.DeclarationBlock(this._declarationBlockConfig) | ||
@@ -214,3 +299,3 @@ .export() | ||
this._collectedResolvers[node.name] = name; | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
return new utils_1.DeclarationBlock(this._declarationBlockConfig) | ||
@@ -224,7 +309,10 @@ .export() | ||
const nameAsString = node.name; | ||
const baseName = this.scalars[nameAsString] ? this._getScalar(nameAsString) : this.convertName(node); | ||
const baseName = this.getTypeToUse(nameAsString); | ||
this._collectedResolvers[node.name] = 'GraphQLScalarType'; | ||
return new utils_1.DeclarationBlock(Object.assign({}, this._declarationBlockConfig, { blockTransformer(block) { | ||
return new utils_1.DeclarationBlock({ | ||
...this._declarationBlockConfig, | ||
blockTransformer(block) { | ||
return block; | ||
} })) | ||
}, | ||
}) | ||
.export() | ||
@@ -244,5 +332,8 @@ .asKind('interface') | ||
this._collectedDirectiveResolvers[node.name] = directiveName + '<any, any, Context>'; | ||
return new utils_1.DeclarationBlock(Object.assign({}, this._declarationBlockConfig, { blockTransformer(block) { | ||
return new utils_1.DeclarationBlock({ | ||
...this._declarationBlockConfig, | ||
blockTransformer(block) { | ||
return block; | ||
} })) | ||
}, | ||
}) | ||
.export() | ||
@@ -261,3 +352,3 @@ .asKind('type') | ||
for (const graphqlType of Object.values(allTypesMap)) { | ||
if (graphqlType instanceof graphql_1.GraphQLObjectType) { | ||
if (graphqlType instanceof graphql_2.GraphQLObjectType) { | ||
const allInterfaces = graphqlType.getInterfaces(); | ||
@@ -269,3 +360,4 @@ if (allInterfaces.find(int => int.name === node.name)) { | ||
} | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
const possibleTypes = implementingTypes.map(name => `'${name}'`).join(' | ') || 'null'; | ||
return new utils_1.DeclarationBlock(this._declarationBlockConfig) | ||
@@ -275,3 +367,3 @@ .export() | ||
.withName(name, `<Context = ${this.config.contextType.type}, ParentType = ${type}>`) | ||
.withBlock([utils_1.indent(`__resolveType: TypeResolveFn<${implementingTypes.map(name => `'${name}'`).join(' | ')}, ParentType, Context>,`), ...(node.fields || []).map((f) => f(node.name))].join('\n')).string; | ||
.withBlock([utils_1.indent(`__resolveType: TypeResolveFn<${possibleTypes}, ParentType, Context>,`), ...(node.fields || []).map((f) => f(node.name))].join('\n')).string; | ||
} | ||
@@ -278,0 +370,0 @@ SchemaDefinition() { |
@@ -10,3 +10,6 @@ "use strict"; | ||
constructor(_schema, rawConfig, additionalConfig, defaultScalars = scalars_1.DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ enumValues: rawConfig.enumValues || {} }, additionalConfig), utils_1.buildScalars(_schema, defaultScalars)); | ||
super(rawConfig, { | ||
enumValues: rawConfig.enumValues || {}, | ||
...additionalConfig, | ||
}, utils_1.buildScalars(_schema, defaultScalars)); | ||
this._schema = _schema; | ||
@@ -13,0 +16,0 @@ this._argumentsTransformer = new variables_to_object_1.OperationVariablesToObject(this.scalars, this.convertName); |
@@ -9,3 +9,8 @@ "use strict"; | ||
this._declarationBlockConfig = {}; | ||
this._parsedConfig = Object.assign({ scalars: Object.assign({}, (defaultScalars || scalars_1.DEFAULT_SCALARS), (rawConfig.scalars || {})), convert: naming_1.convertFactory(rawConfig), typesPrefix: rawConfig.typesPrefix || '' }, (additionalConfig || {})); | ||
this._parsedConfig = { | ||
scalars: { ...(defaultScalars || scalars_1.DEFAULT_SCALARS), ...(rawConfig.scalars || {}) }, | ||
convert: naming_1.convertFactory(rawConfig), | ||
typesPrefix: rawConfig.typesPrefix || '', | ||
...(additionalConfig || {}), | ||
}; | ||
autoBind(this); | ||
@@ -12,0 +17,0 @@ } |
@@ -12,3 +12,7 @@ "use strict"; | ||
constructor(_fragments, rawConfig, additionalConfig) { | ||
super(rawConfig, Object.assign({ noGraphQLTag: utils_1.getConfigValue(rawConfig.noGraphQLTag, false), gqlImport: rawConfig.gqlImport || null }, additionalConfig)); | ||
super(rawConfig, { | ||
noGraphQLTag: utils_1.getConfigValue(rawConfig.noGraphQLTag, false), | ||
gqlImport: rawConfig.gqlImport || null, | ||
...additionalConfig, | ||
}); | ||
this._fragments = _fragments; | ||
@@ -15,0 +19,0 @@ autoBind(this); |
@@ -76,2 +76,5 @@ "use strict"; | ||
const loadedFragment = this._loadedFragments.find(f => f.name === node.name.value); | ||
if (!loadedFragment) { | ||
throw new Error(`Unable to find fragment matching then name "${node.name.value}"! Please make sure it's loaded.`); | ||
} | ||
if (!this._fragments[loadedFragment.onType]) { | ||
@@ -191,3 +194,3 @@ this._fragments[loadedFragment.onType] = []; | ||
const typeFragments = fragments[typeName]; | ||
const interfacesFragments = schemaType.getInterfaces().filter(gqlInterface => !!interfaces[gqlInterface.name]); | ||
const interfacesFragments = schemaType.getInterfaces === undefined ? [] : schemaType.getInterfaces().filter(gqlInterface => !!interfaces[gqlInterface.name]); | ||
if (interfacesFragments.length > 0) { | ||
@@ -205,3 +208,3 @@ for (const relevantInterface of interfacesFragments) { | ||
} | ||
const mergedResult = Object.assign({}, interfaces, types); | ||
const mergedResult = { ...interfaces, ...types }; | ||
return utils_1.quoteIfNeeded(Object.keys(mergedResult).map(typeName => { | ||
@@ -208,0 +211,0 @@ const baseFragments = utils_1.quoteIfNeeded(mergedResult[typeName].fragments, ' & '); |
@@ -1,2 +0,2 @@ | ||
import { NameNode, TypeNode, NamedTypeNode, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLOutputType, GraphQLNamedType, GraphQLSchema, StringValueNode } from 'graphql'; | ||
import { NameNode, TypeNode, NamedTypeNode, GraphQLOutputType, GraphQLNamedType, GraphQLSchema, StringValueNode } from 'graphql'; | ||
import { ScalarsMap } from './types'; | ||
@@ -39,9 +39,2 @@ export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T; | ||
export declare function toPascalCase(str: string, transformUnderscore?: boolean): string; | ||
export declare const wrapTypeWithModifiers: (prefix?: string) => (baseType: string, type: GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}> | GraphQLNonNull<GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}>> | GraphQLList<GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}>>) => string; | ||
export declare function buildScalars(schema: GraphQLSchema, scalarsMapping: ScalarsMap): ScalarsMap; |
@@ -82,3 +82,8 @@ "use strict"; | ||
this._comment = null; | ||
this._config = Object.assign({ blockWrapper: '', blockTransformer: block => block, enumNameValueSeparator: ':' }, this._config); | ||
this._config = { | ||
blockWrapper: '', | ||
blockTransformer: block => block, | ||
enumNameValueSeparator: ':', | ||
...this._config, | ||
}; | ||
} | ||
@@ -177,17 +182,5 @@ export(exp = true) { | ||
exports.toPascalCase = toPascalCase; | ||
exports.wrapTypeWithModifiers = (prefix = '') => (baseType, type) => { | ||
if (graphql_1.isNonNullType(type)) { | ||
return exports.wrapTypeWithModifiers(prefix)(baseType, type.ofType).substr(1); | ||
} | ||
else if (graphql_1.isListType(type)) { | ||
const innerType = exports.wrapTypeWithModifiers(prefix)(baseType, type.ofType); | ||
return `${prefix}Array<${innerType}>`; | ||
} | ||
else { | ||
return `${prefix}${baseType}`; | ||
} | ||
}; | ||
function buildScalars(schema, scalarsMapping) { | ||
const typeMap = schema.getTypeMap(); | ||
let result = Object.assign({}, scalarsMapping); | ||
let result = { ...scalarsMapping }; | ||
Object.keys(typeMap) | ||
@@ -194,0 +187,0 @@ .map(typeName => typeMap[typeName]) |
@@ -18,3 +18,6 @@ import * as autoBind from 'auto-bind'; | ||
constructor(rawConfig, additionalConfig, _schema, scalars = DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ addTypename: !rawConfig.skipTypename }, (additionalConfig || {})), buildScalars(_schema, scalars)); | ||
super(rawConfig, { | ||
addTypename: !rawConfig.skipTypename, | ||
...(additionalConfig || {}), | ||
}, buildScalars(_schema, scalars)); | ||
this._schema = _schema; | ||
@@ -21,0 +24,0 @@ this._unnamedCounter = 1; |
@@ -5,3 +5,3 @@ import { ParsedConfig, RawConfig, BaseVisitor } from './base-visitor'; | ||
import { NameNode, ListTypeNode, NamedTypeNode, FieldDefinitionNode, ObjectTypeDefinitionNode, GraphQLSchema, NonNullTypeNode, UnionTypeDefinitionNode, ScalarTypeDefinitionNode, InterfaceTypeDefinitionNode } from 'graphql'; | ||
import { DirectiveDefinitionNode } from 'graphql'; | ||
import { DirectiveDefinitionNode, GraphQLOutputType } from 'graphql'; | ||
import { OperationVariablesToObject } from './variables-to-object'; | ||
@@ -78,2 +78,10 @@ import { ParsedMapper } from './mappers'; | ||
* ``` | ||
* | ||
* @example Wrap default types with Partial | ||
* You can also specify a custom wrapper for the original type, without overring the original generated types, use "{T}" to specify the identifier. (for flow, use `$Shape<{T}>`) | ||
* ```yml | ||
* plugins | ||
* config: | ||
* defaultMapper: Partial<{T}> | ||
* ``` | ||
*/ | ||
@@ -101,3 +109,24 @@ defaultMapper?: string; | ||
avoidOptionals?: boolean; | ||
/** | ||
* @name showUnusedMappers | ||
* @type boolean | ||
* @description Warns about unused mappers. | ||
* @default true | ||
* | ||
* @example | ||
* ```yml | ||
* generates: | ||
* path/to/file.ts: | ||
* plugins: | ||
* - typescript | ||
* - typescript-resolvers | ||
* config: | ||
* showUnusedMappers: true | ||
* ``` | ||
*/ | ||
showUnusedMappers?: boolean; | ||
} | ||
export declare type ResolverTypes = { | ||
[gqlType: string]: string; | ||
}; | ||
export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig = RawResolversConfig, TPluginConfig extends ParsedResolversConfig = ParsedResolversConfig> extends BaseVisitor<TRawConfig, TPluginConfig> { | ||
@@ -117,3 +146,13 @@ private _schema; | ||
}; | ||
protected _resolversTypes: ResolverTypes; | ||
constructor(rawConfig: TRawConfig, additionalConfig: TPluginConfig, _schema: GraphQLSchema, defaultScalars?: ScalarsMap); | ||
protected createResolversFields(): void; | ||
protected replaceFieldsInType(typeName: string, relevantFields: { | ||
fieldName: string; | ||
replaceWithType: string; | ||
}[]): string; | ||
protected applyMaybe(str: string): string; | ||
protected clearMaybe(str: string): string; | ||
protected wrapTypeWithModifiers(baseType: string, type: GraphQLOutputType): string; | ||
buildResolversTypes(): string; | ||
readonly schema: GraphQLSchema; | ||
@@ -135,5 +174,3 @@ readonly defaultMapperType: string; | ||
protected markMapperAsUsed(name: string): void; | ||
protected getTypeToUse(name: string, node: { | ||
name: any; | ||
}): string; | ||
protected getTypeToUse(name: string): string; | ||
FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): (parentName: string) => string; | ||
@@ -140,0 +177,0 @@ ObjectTypeDefinition(node: ObjectTypeDefinitionNode, key: string | number, parent: any): string; |
import { BaseVisitor } from './base-visitor'; | ||
import * as autoBind from 'auto-bind'; | ||
import { DEFAULT_SCALARS } from './scalars'; | ||
import { DeclarationBlock, indent, getBaseTypeNode, buildScalars, getConfigValue } from './utils'; | ||
import { DeclarationBlock, indent, getBaseTypeNode, buildScalars, getConfigValue, getBaseType } from './utils'; | ||
import { isObjectType, isInterfaceType, isNonNullType, isListType, } from 'graphql'; | ||
import { GraphQLObjectType } from 'graphql'; | ||
@@ -10,3 +11,9 @@ import { OperationVariablesToObject } from './variables-to-object'; | ||
constructor(rawConfig, additionalConfig, _schema, defaultScalars = DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ contextType: parseMapper(rawConfig.contextType || 'any'), avoidOptionals: getConfigValue(rawConfig.avoidOptionals, false), defaultMapper: rawConfig.defaultMapper ? parseMapper(rawConfig.defaultMapper || 'any') : null, mappers: transformMappers(rawConfig.mappers || {}) }, (additionalConfig || {})), buildScalars(_schema, defaultScalars)); | ||
super(rawConfig, { | ||
contextType: parseMapper(rawConfig.contextType || 'any'), | ||
avoidOptionals: getConfigValue(rawConfig.avoidOptionals, false), | ||
defaultMapper: rawConfig.defaultMapper ? parseMapper(rawConfig.defaultMapper || 'any') : null, | ||
mappers: transformMappers(rawConfig.mappers || {}), | ||
...(additionalConfig || {}), | ||
}, buildScalars(_schema, defaultScalars)); | ||
this._schema = _schema; | ||
@@ -17,5 +24,88 @@ this._declarationBlockConfig = {}; | ||
this._usedMappers = {}; | ||
this._resolversTypes = {}; | ||
autoBind(this); | ||
this._variablesTransfomer = new OperationVariablesToObject(this.scalars, this.convertName); | ||
this.createResolversFields(); | ||
} | ||
createResolversFields() { | ||
const allSchemaTypes = this._schema.getTypeMap(); | ||
this._resolversTypes = Object.keys(allSchemaTypes).reduce((prev, typeName) => { | ||
if (typeName.startsWith('__')) { | ||
return prev; | ||
} | ||
let shouldApplyOmit = false; | ||
if (this.config.mappers[typeName] && this.config.mappers[typeName].type) { | ||
this.markMapperAsUsed(typeName); | ||
prev[typeName] = this.config.mappers[typeName].type; | ||
} | ||
else if (this.config.defaultMapper && this.config.defaultMapper.type && !this.config.defaultMapper.type.includes('{T}')) { | ||
prev[typeName] = this.config.defaultMapper.type; | ||
} | ||
else if (this.config.scalars[typeName]) { | ||
prev[typeName] = this._getScalar(typeName); | ||
} | ||
else { | ||
shouldApplyOmit = true; | ||
prev[typeName] = this.convertName(typeName); | ||
} | ||
const schemaType = allSchemaTypes[typeName]; | ||
if ((shouldApplyOmit && prev[typeName] !== 'any' && isObjectType(schemaType)) || isInterfaceType(schemaType)) { | ||
const fields = schemaType.getFields(); | ||
const relevantFields = Object.keys(fields) | ||
.map(fieldName => { | ||
const field = fields[fieldName]; | ||
const baseType = getBaseType(field.type); | ||
if (!this.config.mappers[baseType.name]) { | ||
return null; | ||
} | ||
return { | ||
fieldName, | ||
replaceWithType: this.wrapTypeWithModifiers(this.getTypeToUse(baseType.name), field.type), | ||
}; | ||
}) | ||
.filter(a => a); | ||
if (relevantFields.length > 0) { | ||
prev[typeName] = this.replaceFieldsInType(prev[typeName], relevantFields); | ||
} | ||
} | ||
if (!this.config.scalars[typeName] && !this.config.mappers[typeName] && this.config.defaultMapper && this.config.defaultMapper.type.includes('{T}')) { | ||
prev[typeName] = this.config.defaultMapper.type.replace('{T}', prev[typeName]); | ||
} | ||
return prev; | ||
}, {}); | ||
} | ||
replaceFieldsInType(typeName, relevantFields) { | ||
return `Omit<${typeName}, ${relevantFields.map(f => `'${f.fieldName}'`).join(' | ')}> & { ${relevantFields.map(f => `${f.fieldName}: ${f.replaceWithType}`).join(', ')} }`; | ||
} | ||
applyMaybe(str) { | ||
return `Maybe<${str}>`; | ||
} | ||
clearMaybe(str) { | ||
if (str.startsWith('Maybe')) { | ||
return str.replace(/Maybe<(.*?)>$/, '$1'); | ||
} | ||
return str; | ||
} | ||
wrapTypeWithModifiers(baseType, type) { | ||
if (isNonNullType(type)) { | ||
return this.clearMaybe(this.wrapTypeWithModifiers(baseType, type.ofType)); | ||
} | ||
else if (isListType(type)) { | ||
const innerType = this.wrapTypeWithModifiers(baseType, type.ofType); | ||
return this.applyMaybe(`Array<${innerType}>`); | ||
} | ||
else { | ||
return this.applyMaybe(baseType); | ||
} | ||
} | ||
buildResolversTypes() { | ||
return new DeclarationBlock(this._declarationBlockConfig) | ||
.export() | ||
.asKind('type') | ||
.withName(this.convertName('ResolversTypes')) | ||
.withComment('Mapping between all available schema types and the resolvers types') | ||
.withBlock(Object.keys(this._resolversTypes) | ||
.map(typeName => indent(`${typeName}: ${this._resolversTypes[typeName]},`)) | ||
.join('\n')).string; | ||
} | ||
get schema() { | ||
@@ -53,3 +143,7 @@ return this._schema; | ||
} | ||
groupedMappers[this.config.defaultMapper.source].push(this.config.defaultMapper.type); | ||
let identifier = this.config.defaultMapper.type; | ||
if (identifier.includes('{T}')) { | ||
identifier = identifier.replace(/<.*?>/g, ''); | ||
} | ||
groupedMappers[this.config.defaultMapper.source].push(identifier); | ||
} | ||
@@ -151,14 +245,5 @@ return Object.keys(groupedMappers).map(source => this.buildMapperImport(source, groupedMappers[source])); | ||
} | ||
getTypeToUse(name, node) { | ||
if (this.config.mappers[name]) { | ||
this.markMapperAsUsed(name); | ||
return this.config.mappers[name].type; | ||
} | ||
else if (this.config.defaultMapper) { | ||
return this.config.defaultMapper.type; | ||
} | ||
else if (this.config.scalars[name]) { | ||
return this._getScalar(name); | ||
} | ||
return this.convertName(typeof node.name === 'string' ? node.name : node.name.value); | ||
getTypeToUse(name) { | ||
const resolversType = this.convertName('ResolversTypes'); | ||
return `${resolversType}['${name}']`; | ||
} | ||
@@ -171,3 +256,3 @@ FieldDefinition(node, key, parent) { | ||
const realType = baseType.name.value; | ||
const typeToUse = this.getTypeToUse(realType, baseType); | ||
const typeToUse = this.getTypeToUse(realType); | ||
const mappedType = this._variablesTransfomer.wrapAstTypeWithModifiers(typeToUse, original.type); | ||
@@ -191,3 +276,3 @@ const subscriptionType = this._schema.getSubscriptionType(); | ||
}); | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
const block = new DeclarationBlock(this._declarationBlockConfig) | ||
@@ -211,3 +296,3 @@ .export() | ||
this._collectedResolvers[node.name] = name; | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
return new DeclarationBlock(this._declarationBlockConfig) | ||
@@ -221,7 +306,10 @@ .export() | ||
const nameAsString = node.name; | ||
const baseName = this.scalars[nameAsString] ? this._getScalar(nameAsString) : this.convertName(node); | ||
const baseName = this.getTypeToUse(nameAsString); | ||
this._collectedResolvers[node.name] = 'GraphQLScalarType'; | ||
return new DeclarationBlock(Object.assign({}, this._declarationBlockConfig, { blockTransformer(block) { | ||
return new DeclarationBlock({ | ||
...this._declarationBlockConfig, | ||
blockTransformer(block) { | ||
return block; | ||
} })) | ||
}, | ||
}) | ||
.export() | ||
@@ -241,5 +329,8 @@ .asKind('interface') | ||
this._collectedDirectiveResolvers[node.name] = directiveName + '<any, any, Context>'; | ||
return new DeclarationBlock(Object.assign({}, this._declarationBlockConfig, { blockTransformer(block) { | ||
return new DeclarationBlock({ | ||
...this._declarationBlockConfig, | ||
blockTransformer(block) { | ||
return block; | ||
} })) | ||
}, | ||
}) | ||
.export() | ||
@@ -265,3 +356,4 @@ .asKind('type') | ||
} | ||
const type = this.getTypeToUse(node.name, node); | ||
const type = this.getTypeToUse(node.name); | ||
const possibleTypes = implementingTypes.map(name => `'${name}'`).join(' | ') || 'null'; | ||
return new DeclarationBlock(this._declarationBlockConfig) | ||
@@ -271,3 +363,3 @@ .export() | ||
.withName(name, `<Context = ${this.config.contextType.type}, ParentType = ${type}>`) | ||
.withBlock([indent(`__resolveType: TypeResolveFn<${implementingTypes.map(name => `'${name}'`).join(' | ')}, ParentType, Context>,`), ...(node.fields || []).map((f) => f(node.name))].join('\n')).string; | ||
.withBlock([indent(`__resolveType: TypeResolveFn<${possibleTypes}, ParentType, Context>,`), ...(node.fields || []).map((f) => f(node.name))].join('\n')).string; | ||
} | ||
@@ -274,0 +366,0 @@ SchemaDefinition() { |
@@ -8,3 +8,6 @@ import { BaseVisitor } from './base-visitor'; | ||
constructor(_schema, rawConfig, additionalConfig, defaultScalars = DEFAULT_SCALARS) { | ||
super(rawConfig, Object.assign({ enumValues: rawConfig.enumValues || {} }, additionalConfig), buildScalars(_schema, defaultScalars)); | ||
super(rawConfig, { | ||
enumValues: rawConfig.enumValues || {}, | ||
...additionalConfig, | ||
}, buildScalars(_schema, defaultScalars)); | ||
this._schema = _schema; | ||
@@ -11,0 +14,0 @@ this._argumentsTransformer = new OperationVariablesToObject(this.scalars, this.convertName); |
@@ -7,3 +7,8 @@ import * as autoBind from 'auto-bind'; | ||
this._declarationBlockConfig = {}; | ||
this._parsedConfig = Object.assign({ scalars: Object.assign({}, (defaultScalars || DEFAULT_SCALARS), (rawConfig.scalars || {})), convert: convertFactory(rawConfig), typesPrefix: rawConfig.typesPrefix || '' }, (additionalConfig || {})); | ||
this._parsedConfig = { | ||
scalars: { ...(defaultScalars || DEFAULT_SCALARS), ...(rawConfig.scalars || {}) }, | ||
convert: convertFactory(rawConfig), | ||
typesPrefix: rawConfig.typesPrefix || '', | ||
...(additionalConfig || {}), | ||
}; | ||
autoBind(this); | ||
@@ -10,0 +15,0 @@ } |
@@ -10,3 +10,7 @@ import { BaseVisitor } from './index'; | ||
constructor(_fragments, rawConfig, additionalConfig) { | ||
super(rawConfig, Object.assign({ noGraphQLTag: getConfigValue(rawConfig.noGraphQLTag, false), gqlImport: rawConfig.gqlImport || null }, additionalConfig)); | ||
super(rawConfig, { | ||
noGraphQLTag: getConfigValue(rawConfig.noGraphQLTag, false), | ||
gqlImport: rawConfig.gqlImport || null, | ||
...additionalConfig, | ||
}); | ||
this._fragments = _fragments; | ||
@@ -13,0 +17,0 @@ autoBind(this); |
@@ -74,2 +74,5 @@ import { Kind, isObjectType, isUnionType, isInterfaceType, isEnumType, isEqualType, SchemaMetaFieldDef, TypeMetaFieldDef, isScalarType, } from 'graphql'; | ||
const loadedFragment = this._loadedFragments.find(f => f.name === node.name.value); | ||
if (!loadedFragment) { | ||
throw new Error(`Unable to find fragment matching then name "${node.name.value}"! Please make sure it's loaded.`); | ||
} | ||
if (!this._fragments[loadedFragment.onType]) { | ||
@@ -189,3 +192,3 @@ this._fragments[loadedFragment.onType] = []; | ||
const typeFragments = fragments[typeName]; | ||
const interfacesFragments = schemaType.getInterfaces().filter(gqlInterface => !!interfaces[gqlInterface.name]); | ||
const interfacesFragments = schemaType.getInterfaces === undefined ? [] : schemaType.getInterfaces().filter(gqlInterface => !!interfaces[gqlInterface.name]); | ||
if (interfacesFragments.length > 0) { | ||
@@ -203,3 +206,3 @@ for (const relevantInterface of interfacesFragments) { | ||
} | ||
const mergedResult = Object.assign({}, interfaces, types); | ||
const mergedResult = { ...interfaces, ...types }; | ||
return quoteIfNeeded(Object.keys(mergedResult).map(typeName => { | ||
@@ -206,0 +209,0 @@ const baseFragments = quoteIfNeeded(mergedResult[typeName].fragments, ' & '); |
@@ -1,2 +0,2 @@ | ||
import { NameNode, TypeNode, NamedTypeNode, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLOutputType, GraphQLNamedType, GraphQLSchema, StringValueNode } from 'graphql'; | ||
import { NameNode, TypeNode, NamedTypeNode, GraphQLOutputType, GraphQLNamedType, GraphQLSchema, StringValueNode } from 'graphql'; | ||
import { ScalarsMap } from './types'; | ||
@@ -39,9 +39,2 @@ export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T; | ||
export declare function toPascalCase(str: string, transformUnderscore?: boolean): string; | ||
export declare const wrapTypeWithModifiers: (prefix?: string) => (baseType: string, type: GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}> | GraphQLNonNull<GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}>> | GraphQLList<GraphQLObjectType<any, any, { | ||
[key: string]: any; | ||
}>>) => string; | ||
export declare function buildScalars(schema: GraphQLSchema, scalarsMapping: ScalarsMap): ScalarsMap; |
@@ -73,3 +73,8 @@ import { pascalCase } from 'change-case'; | ||
this._comment = null; | ||
this._config = Object.assign({ blockWrapper: '', blockTransformer: block => block, enumNameValueSeparator: ':' }, this._config); | ||
this._config = { | ||
blockWrapper: '', | ||
blockTransformer: block => block, | ||
enumNameValueSeparator: ':', | ||
...this._config, | ||
}; | ||
} | ||
@@ -164,17 +169,5 @@ export(exp = true) { | ||
} | ||
export const wrapTypeWithModifiers = (prefix = '') => (baseType, type) => { | ||
if (isNonNullType(type)) { | ||
return wrapTypeWithModifiers(prefix)(baseType, type.ofType).substr(1); | ||
} | ||
else if (isListType(type)) { | ||
const innerType = wrapTypeWithModifiers(prefix)(baseType, type.ofType); | ||
return `${prefix}Array<${innerType}>`; | ||
} | ||
else { | ||
return `${prefix}${baseType}`; | ||
} | ||
}; | ||
export function buildScalars(schema, scalarsMapping) { | ||
const typeMap = schema.getTypeMap(); | ||
let result = Object.assign({}, scalarsMapping); | ||
let result = { ...scalarsMapping }; | ||
Object.keys(typeMap) | ||
@@ -181,0 +174,0 @@ .map(typeName => typeMap[typeName]) |
{ | ||
"name": "@graphql-codegen/visitor-plugin-common", | ||
"version": "1.0.7-alpha-91766652.13+91766652", | ||
"version": "1.0.7-alpha-9b2216ab.39+9b2216ab", | ||
"license": "MIT", | ||
@@ -10,3 +10,3 @@ "scripts": { | ||
"dependencies": { | ||
"@graphql-codegen/plugin-helpers": "1.0.7-alpha-91766652.13+91766652", | ||
"@graphql-codegen/plugin-helpers": "1.0.7-alpha-9b2216ab.39+9b2216ab", | ||
"auto-bind": "2.0.0", | ||
@@ -18,12 +18,12 @@ "dependency-graph": "0.8.0", | ||
"peerDependencies": { | ||
"graphql": "14.2.0" | ||
"graphql": "14.2.1" | ||
}, | ||
"devDependencies": { | ||
"@graphql-codegen/testing": "1.0.7-alpha-91766652.13+91766652", | ||
"@graphql-codegen/testing": "1.0.7-alpha-9b2216ab.39+9b2216ab", | ||
"@types/graphql": "14.2.0", | ||
"@types/jest": "24.0.11", | ||
"graphql": "14.2.0", | ||
"jest": "24.5.0", | ||
"graphql": "14.2.1", | ||
"jest": "24.7.1", | ||
"ts-jest": "24.0.1", | ||
"typescript": "3.3.4000" | ||
"typescript": "3.4.1" | ||
}, | ||
@@ -40,3 +40,3 @@ "sideEffects": false, | ||
}, | ||
"gitHead": "917666520d5267cc4cdf4b0c6f0b0fec6b467060" | ||
"gitHead": "9b2216ab5c393559023fb8d1aaffa1f00e0eeb29" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
272156
3984
+ Addedgraphql@14.2.1(transitive)
- Removedgraphql@14.2.0(transitive)
Updated@graphql-codegen/plugin-helpers@1.0.7-alpha-9b2216ab.39+9b2216ab