@graphql-codegen/flow
Version:
GraphQL Code Generator plugin for generating Flow types
135 lines (134 loc) • 6.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowVisitor = void 0;
const tslib_1 = require("tslib");
const auto_bind_1 = tslib_1.__importDefault(require("auto-bind"));
const graphql_1 = require("graphql");
const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common");
const flow_variables_to_object_js_1 = require("./flow-variables-to-object.js");
class FlowVisitor extends visitor_plugin_common_1.BaseTypesVisitor {
constructor(schema, pluginConfig) {
super(schema, pluginConfig, {
useFlowExactObjects: (0, visitor_plugin_common_1.getConfigValue)(pluginConfig.useFlowExactObjects, true),
useFlowReadOnlyTypes: (0, visitor_plugin_common_1.getConfigValue)(pluginConfig.useFlowReadOnlyTypes, false),
});
(0, auto_bind_1.default)(this);
const enumNames = Object.values(schema.getTypeMap())
.map(type => (type instanceof graphql_1.GraphQLEnumType ? type.name : undefined))
.filter(t => t);
this.setArgumentsTransformer(new flow_variables_to_object_js_1.FlowOperationVariablesToObject(this.scalars, this.convertName, null, enumNames, pluginConfig.enumPrefix));
this.setDeclarationBlockConfig({
blockWrapper: this.config.useFlowExactObjects ? '|' : '',
});
}
_getScalar(name) {
return `$ElementType<Scalars, '${name}'>`;
}
InputValueDefinition(node, key, parent) {
const originalFieldNode = parent[key];
const addOptionalSign = originalFieldNode.type.kind !== graphql_1.Kind.NON_NULL_TYPE;
const comment = (0, visitor_plugin_common_1.transformComment)(node.description, 1);
return comment + (0, visitor_plugin_common_1.indent)(`${node.name}${addOptionalSign ? '?' : ''}: ${node.type},`);
}
NamedType(node, key, parent, path, ancestors) {
return `?${super.NamedType(node, key, parent, path, ancestors)}`;
}
ListType(node, key, parent, path, ancestors) {
return `?${super.ListType(node, key, parent, path, ancestors)}`;
}
NonNullType(node) {
const baseValue = super.NonNullType(node);
if (baseValue.startsWith('?')) {
return baseValue.substr(1);
}
return baseValue;
}
FieldDefinition(node) {
const typeString = node.type;
const namePostfix = typeString.startsWith('?') ? '?' : '';
const comment = (0, visitor_plugin_common_1.transformComment)(node.description, 1);
return (comment +
(0, visitor_plugin_common_1.indent)(`${this.config.useFlowReadOnlyTypes ? '+' : ''}${node.name}${namePostfix}: ${typeString},`));
}
ObjectTypeDefinition(node, key, parent) {
return super.ObjectTypeDefinition({
...node,
interfaces: node.interfaces && node.interfaces.length > 0
? node.interfaces.map(name => name.replace('?', ''))
: [],
}, key, parent);
}
_buildTypeImport(identifier, source) {
return `import { type ${identifier} } from '${source}';`;
}
mergeInterfaces(interfaces, hasOtherFields) {
if (!interfaces.length) {
return '';
}
return interfaces.map(i => (0, visitor_plugin_common_1.indent)(`...${i}`)).join(',\n') + (hasOtherFields ? ',\n ' : '');
}
appendInterfacesAndFieldsToBlock(block, interfaces, fields) {
block.withBlock(this.mergeInterfaces(interfaces, fields.length > 0) +
this.mergeAllFields(fields, interfaces.length > 0));
}
mergeAllFields(allFields, hasInterfaces) {
if (allFields.length === 0) {
return '';
}
if (!hasInterfaces) {
return allFields.join('\n');
}
return `...{${this.config.useFlowExactObjects ? '|' : ''}\n${allFields
.map(s => (0, visitor_plugin_common_1.indent)(s))
.join('\n')}\n ${this.config.useFlowExactObjects ? '|' : ''}}`;
}
handleEnumValueMapper(typeIdentifier, importIdentifier, sourceIdentifier, sourceFile) {
let identifier = sourceIdentifier;
if (sourceIdentifier !== typeIdentifier && !sourceIdentifier.includes(' as ')) {
identifier = `${sourceIdentifier} as ${typeIdentifier}`;
}
return [this._buildTypeImport(identifier, sourceFile)];
}
EnumTypeDefinition(node) {
const typeName = node.name;
if (this.config.enumValues[typeName] && this.config.enumValues[typeName].sourceFile) {
return null;
}
const enumValuesName = this.convertName(node, {
suffix: 'Values',
useTypesPrefix: this.config.enumPrefix,
});
const enumValues = new visitor_plugin_common_1.DeclarationBlock(this._declarationBlockConfig)
.export()
.asKind('const')
.withName(enumValuesName)
.withMethodCall('Object.freeze', true)
.withBlock(node.values
.map(enumOption => {
const comment = (0, visitor_plugin_common_1.transformComment)(enumOption.description, 1);
const optionName = this.convertName(enumOption, {
transformUnderscore: true,
useTypesPrefix: false,
});
let enumValue = enumOption.name;
if (this.config.enumValues[typeName] &&
this.config.enumValues[typeName].mappedValues &&
typeof this.config.enumValues[typeName].mappedValues[enumValue] !== 'undefined') {
enumValue = this.config.enumValues[typeName].mappedValues[enumValue];
}
return comment + (0, visitor_plugin_common_1.indent)(`${optionName}: ${(0, visitor_plugin_common_1.wrapWithSingleQuotes)(enumValue)}`);
})
.join(', \n')).string;
const enumType = new visitor_plugin_common_1.DeclarationBlock(this._declarationBlockConfig)
.export()
.asKind('type')
.withName(this.convertName(node, { useTypesPrefix: this.config.enumPrefix }))
.withComment(node.description)
.withContent(`$Values<typeof ${enumValuesName}>`).string;
return [enumValues, enumType].join('\n\n');
}
getPunctuation(declarationKind) {
return declarationKind === 'type' ? ',' : ';';
}
}
exports.FlowVisitor = FlowVisitor;