UNPKG

@graphql-codegen/flutter-freezed

Version:

GraphQL Code Generator plugin to generate Freezed models from your GraphQL schema

93 lines (92 loc) 4.24 kB
import { Kind } from 'graphql'; import { indent } from '@graphql-codegen/visitor-plugin-common'; import { Config } from '../config/config-value.js'; import { TypeName } from '../config/pattern.js'; import { APPLIES_ON_CLASS } from '../config/plugin-config.js'; import { nodeIsObjectType, stringIsNotEmpty } from '../utils.js'; import { FactoryBlock } from './factory-block.js'; import { Block } from './index.js'; export class ClassBlock { static build(config, node) { const typeName = TypeName.fromString(node.name.value); const _className = Block.buildBlockName(config, APPLIES_ON_CLASS, typeName.value, typeName, undefined, 'PascalCase'); let block = ''; // the comments should be on the factory block instead // block += Block.buildComment(node); block += this.buildDecorators(config, node); block += this.buildHeader(config, typeName, _className); block += this.buildBody(config, node); block += this.buildFooter(_className); return block; } } ClassBlock.buildDecorators = (config, node) => { const freezedDecorator = ClassBlock.buildFreezedDecorator(config, node); // TODO: consider implementing custom decorators return [freezedDecorator].join(''); }; ClassBlock.buildFreezedDecorator = (config, node) => { // this is the start of the pipeline of decisions to determine which Freezed decorator to use return ClassBlock.decorateAsFreezed(config, node); }; ClassBlock.decorateAsFreezed = (config, node) => { const typeName = TypeName.fromString(node.name.value); const copyWith = Config.copyWith(config, typeName); const equal = Config.equal(config, typeName); const makeCollectionsUnmodifiable = Config.makeCollectionsUnmodifiable(config, typeName); const unionKey = Config.unionKey(); const unionValueCase = Config.unionValueCase(); const body = [ copyWith !== undefined ? `copyWith: ${copyWith},\n` : undefined, equal !== undefined ? `equal: ${equal},\n` : undefined, makeCollectionsUnmodifiable !== undefined ? `makeCollectionsUnmodifiable: ${makeCollectionsUnmodifiable},\n` : undefined, unionKey !== undefined ? `unionKey: ${unionKey},\n` : undefined, unionValueCase !== undefined ? `unionValueCase: '${unionValueCase}',\n` : undefined, ] .filter(value => value !== undefined) .map(value => indent(value)) .join(''); return stringIsNotEmpty(body) ? `@Freezed(\n${body})\n` : ClassBlock.decorateAsUnfreezed(config, node); }; ClassBlock.decorateAsUnfreezed = (config, node) => { const typeName = TypeName.fromString(node.name.value); const immutable = Config.immutable(config, typeName); const mutableInputs = Config.mutableInputs(config, typeName); const mutable = immutable !== true || (node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && mutableInputs); return mutable ? '@unfreezed\n' : '@freezed\n'; }; ClassBlock.buildHeader = (config, typeName, _className) => { const privateEmptyConstructor = Config.privateEmptyConstructor(config, typeName) ? indent(`const ${_className}._();\n\n`) : ''; return `class ${_className} with _$${_className} {\n${privateEmptyConstructor}`; }; ClassBlock.buildBody = (config, node) => { var _a; const className = TypeName.fromString(node.name.value); let body = ''; if (nodeIsObjectType(node)) { body += FactoryBlock.serializeDefaultFactory(className); } else if (node.kind === Kind.UNION_TYPE_DEFINITION) { body += ((_a = node.types) !== null && _a !== void 0 ? _a : []) .map(value => { const factoryName = TypeName.fromString(value.name.value); return FactoryBlock.serializeUnionFactory(className, factoryName); }) .join(''); } body += Config.mergeTypes(config, className) .map(factoryName => { return FactoryBlock.serializeMergedFactory(className, factoryName); }) .join(''); return body; }; ClassBlock.buildFooter = (_className) => { return indent(`factory ${_className}.fromJson(Map<String, dynamic> json) => _$${_className}FromJson(json);\n}\n\n`); };