Typescript OneGraph和Graphql Codegen输出带有数值的枚举

Typescript OneGraph和Graphql Codegen输出带有数值的枚举,typescript,enums,graphql,next.js,code-generation,Typescript,Enums,Graphql,Next.js,Code Generation,因此,我刚刚将一个项目的整个代码库从使用直接无头Wordpress GraphQL端点迁移到使用OneGraph for Google+Facebook业务支持。OneGraph是一个神奇的工具,我打算在一个我正在写的无头WordPress上的科技课程中使用它。无论如何,我得到了这个阿波罗错误,它引用了输出codegen。以下是错误: graphQLErrors: [ { message: 'Variable "$idTypeFoot" got inv

因此,我刚刚将一个项目的整个代码库从使用直接无头Wordpress GraphQL端点迁移到使用OneGraph for Google+Facebook业务支持。OneGraph是一个神奇的工具,我打算在一个我正在写的无头WordPress上的科技课程中使用它。无论如何,我得到了这个阿波罗错误,它引用了输出codegen。以下是错误:

  graphQLErrors: [
    {
      message: 'Variable "$idTypeFoot" got invalid value 2; Expected type MenuNodeIdTypeEnum.',
      path: [Array],
      extensions: [Object]
    },
    {
      message: 'Variable "$idTypeFoot" got invalid value 2; Expected type MenuNodeIdTypeEnum.',
      path: [Array],
      extensions: [Object]
    }
  ],

以下是我生成的/graphql.tsx文件中的输出codegen定义:


export enum WordpressMenuNodeIdTypeEnum {
    /** Identify a menu node by the Database ID. */
    DATABASE_ID = 0,
    /** Identify a menu node by the (hashed) Global ID. */
    ID = 1,
    /** Identify a menu node by it's name */
    NAME = 2
}
以下是将我的代码库迁移到onegraph之前相同枚举的先前定义:


/** The Type of Identifier used to fetch a single node. Default is "ID". To be used along with the "id" field. */
export enum MenuNodeIdTypeEnum {
    /** Identify a menu node by the Database ID. */
    DatabaseId = 'DATABASE_ID',
    /** Identify a menu node by the (hashed) Global ID. */
    Id = 'ID',
    /** Identify a menu node by it's name */
    Name = 'NAME'
}
以下是父查询中使用的
动态导航字段。graphql
partial:

fragment DynamicNavFragment on WordpressMenuItem {
    id
    label
    path
    parentId
}

# import DynamicNavFragment from './Partials/dynamic-nav-fields.graphql'

query DynamicNav(
  $idHead: ID!
  $idTypeHead: WordpressMenuNodeIdTypeEnum!
  $idFoot: ID!
  $idTypeFoot: WordpressMenuNodeIdTypeEnum!
    ) {
    Header: wordpress {
        menu(id: $idHead, idType: $idTypeHead) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                    childItems {
                                        edges {
                                            node {
                                                ...DynamicNavFragment
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    Footer: wordpress {
        menu(id: $idFoot, idType: idTypeFoot) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

以下是
动态导航图ql
父查询:

fragment DynamicNavFragment on WordpressMenuItem {
    id
    label
    path
    parentId
}

# import DynamicNavFragment from './Partials/dynamic-nav-fields.graphql'

query DynamicNav(
  $idHead: ID!
  $idTypeHead: WordpressMenuNodeIdTypeEnum!
  $idFoot: ID!
  $idTypeFoot: WordpressMenuNodeIdTypeEnum!
    ) {
    Header: wordpress {
        menu(id: $idHead, idType: $idTypeHead) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                    childItems {
                                        edges {
                                            node {
                                                ...DynamicNavFragment
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    Footer: wordpress {
        menu(id: $idFoot, idType: idTypeFoot) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

这是我的codegen.yml配置文件:

覆盖:true
模式:
${WORDPRESS\u API\u URL\u YML}:
标题:
授权:承载${WORDPRESS\u AUTH\u REFRESH\u TOKEN\u YML}
文档:“graphql/***.graphql”
生成:
graphql/generated/graphql.tsx:
插件:
-打字稿:
常量:false
枚举类型:false
数字:对
未来证明:错误
枚举常量:false
仅限操作类型:false
maybeValue:T | null |未定义
noExport:false
枚举前缀:true
fieldWrapperValue:T
wrapFieldDefinitions:true
skipTypename:false
非可选类型名称:false
useTypeImports:false
避免选项:正确
声明种类:
输入:接口
类型:接口
-类型脚本操作:
声明种类:
输入:接口
类型:接口
避免选项:正确
ExportFragments子类型:true
-阿波罗的打字脚本:
addDocBlocks:正确
新版本:3
documentMode:documentNodeImportFragments
配置:
maybeValue:T | null |未定义
声明种类:
输入:接口
类型:接口
documentNodeImportFragments:true
新版本:3
胡克:没错
withHOC:错误
避免选项:正确
withComponent:false
ExportFragments子类型:true
addDocBlocks:正确
graphql/graphql.schema.graphql:
插件:
-模式ast
配置:
注释说明:正确
graphql/graphql.schema.json:
插件:
-内省
配置:
注释说明:正确
挂钩:
文件写入后:
-更漂亮——写

为什么OneGraph用apollo客户端无法读取的数字替换生成的枚举值?如果有人知道如何解决这个问题,请让我知道更新-见@sgrove的答案,他很棒,帮助我解决了这个问题

好的,我有两个选择:(1)覆盖从以前表示_类型的字符串值转换的每个枚举,或者(2)硬编码这些值。要获取自定义枚举值,我必须将以下内容添加到codegen.yml中:

config:
枚举值:
WordPressMenuodedTypeEnum:“@/types/global enum#WordPressMenuodedTypeEnum”
它指示生成的代码从@/types/global-enums.ts导入此枚举定义

/** The Type of Identifier used to fetch a single node. Default is "ID". To be used along with the "id" field. */
export enum WordpressMenuNodeIdTypeEnum {
    /** Identify a menu node by the Database ID. */
    DatabaseId = 'DATABASE_ID',
    /** Identify a menu node by the (hashed) Global ID. */
    Id = 'ID',
    /** Identify a menu node by it's name */
    Name = 'NAME'
}
但是,我随后遇到了另一个问题,决定直接在我的graphql模式中为WordPressMenuDeidTypeEnum硬编码
名称
值:

# import DynamicNavFragment from './Partials/dynamic-nav-fields.graphql'

query DynamicNav($idHead: ID!, $idFoot: ID!) {
    Header: wordpress {
        menu(id: $idHead, idType: NAME) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                    childItems {
                                        edges {
                                            node {
                                                ...DynamicNavFragment
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    Footer: wordpress {
        menu(id: $idFoot, idType: NAME) {
            menuItems(where: { parentId: 0 }) {
                edges {
                    node {
                        ...DynamicNavFragment
                        childItems {
                            edges {
                                node {
                                    ...DynamicNavFragment
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
然后,我遇到了apollo缓存的另一个问题,因为顶级ServicesTopQuery和DynamicNavQuery都有一个共享的顶级
wordpress
字段,其中有一个对应的u typename“WordPressRootQuery”

ServicesTopQuery
ServicesTopQueryVariables
的代码生成定义:

export type ServicesTopQueryVariables = Exact<{
    popular: Scalars['String'];
    other: Scalars['String'];
}>;

export type ServicesTopQuery = { __typename?: 'Query' } & {
    popular: Maybe<
        { __typename?: 'WordpressRootQuery' } & {
            services: Maybe<
                { __typename?: 'WordpressRootQueryToServiceConnection' } & {
                    edges: Maybe<
                        Array<
                            Maybe<
                                {
                                    __typename?: 'WordpressRootQueryToServiceConnectionEdge';
                                } & {
                                    node: Maybe<
                                        {
                                            __typename?: 'WordpressService';
                                        } & ServiceFieldsTopFragment
                                    >;
                                }
                            >
                        >
                    >;
                }
            >;
        }
    >;
    other: Maybe<
        { __typename?: 'WordpressRootQuery' } & {
            services: Maybe<
                { __typename?: 'WordpressRootQueryToServiceConnection' } & {
                    edges: Maybe<
                        Array<
                            Maybe<
                                {
                                    __typename?: 'WordpressRootQueryToServiceConnectionEdge';
                                } & {
                                    node: Maybe<
                                        {
                                            __typename?: 'WordpressService';
                                        } & ServiceFieldsTopFragment
                                    >;
                                }
                            >
                        >
                    >;
                }
            >;
        }
    >;
};

export type DynamicNavQueryVariables = Exact<{
    idHead: Scalars['ID'];
    idFoot: Scalars['ID'];
}>;

export type DynamicNavQuery = { __typename?: 'Query' } & {
    Header: Maybe<
        { __typename?: 'WordpressRootQuery' } & {
            menu: Maybe<
                { __typename?: 'WordpressMenu' } & {
                    menuItems: Maybe<
                        { __typename?: 'WordpressMenuToMenuItemConnection' } & {
                            edges: Maybe<
                                Array<
                                    Maybe<
                                        {
                                            __typename?: 'WordpressMenuToMenuItemConnectionEdge';
                                        } & {
                                            node: Maybe<
                                                { __typename?: 'WordpressMenuItem' } & {
                                                    childItems: Maybe<
                                                        {
                                                            __typename?: 'WordpressMenuItemToMenuItemConnection';
                                                        } & {
                                                            edges: Maybe<
                                                                Array<
                                                                    Maybe<
                                                                        {
                                                                            __typename?: 'WordpressMenuItemToMenuItemConnectionEdge';
                                                                        } & {
                                                                            node: Maybe<
                                                                                { __typename?: 'WordpressMenuItem' } & {
                                                                                    childItems: Maybe<
                                                                                        {
                                                                                            __typename?: 'WordpressMenuItemToMenuItemConnection';
                                                                                        } & {
                                                                                            edges: Maybe<
                                                                                                Array<
                                                                                                    Maybe<
                                                                                                        {
                                                                                                            __typename?: 'WordpressMenuItemToMenuItemConnectionEdge';
                                                                                                        } & {
                                                                                                            node: Maybe<
                                                                                                                {
                                                                                                                    __typename?: 'WordpressMenuItem';
                                                                                                                } & DynamicNavFragmentFragment
                                                                                                            >;
                                                                                                        }
                                                                                                    >
                                                                                                >
                                                                                            >;
                                                                                        }
                                                                                    >;
                                                                                } & DynamicNavFragmentFragment
                                                                            >;
                                                                        }
                                                                    >
                                                                >
                                                            >;
                                                        }
                                                    >;
                                                } & DynamicNavFragmentFragment
                                            >;
                                        }
                                    >
                                >
                            >;
                        }
                    >;
                }
            >;
        }
    >;
    Footer: Maybe<
        { __typename?: 'WordpressRootQuery' } & {
            menu: Maybe<
                { __typename?: 'WordpressMenu' } & {
                    menuItems: Maybe<
                        { __typename?: 'WordpressMenuToMenuItemConnection' } & {
                            edges: Maybe<
                                Array<
                                    Maybe<
                                        {
                                            __typename?: 'WordpressMenuToMenuItemConnectionEdge';
                                        } & {
                                            node: Maybe<
                                                { __typename?: 'WordpressMenuItem' } & {
                                                    childItems: Maybe<
                                                        {
                                                            __typename?: 'WordpressMenuItemToMenuItemConnection';
                                                        } & {
                                                            edges: Maybe<
                                                                Array<
                                                                    Maybe<
                                                                        {
                                                                            __typename?: 'WordpressMenuItemToMenuItemConnectionEdge';
                                                                        } & {
                                                                            node: Maybe<
                                                                                {
                                                                                    __typename?: 'WordpressMenuItem';
                                                                                } & DynamicNavFragmentFragment
                                                                            >;
                                                                        }
                                                                    >
                                                                >
                                                            >;
                                                        }
                                                    >;
                                                } & DynamicNavFragmentFragment
                                            >;
                                        }
                                    >
                                >
                            >;
                        }
                    >;
                }
            >;
        }
    >;
};
来自pages/index.tsx的代码,其中最初填充了DynamicNavQuery数据,然后被ServicesTopQuery数据迅速覆盖

import { Container } from '@/components/UI';
import { initializeApollo, addApolloState } from '@/lib/apollo';
import { LandingHero } from '@/components/Landing';
import ServiceTopCoalesced from '@/components/ServicesTop/services-top-coalesced';
import AppLayout from '@/components/Layout/layout';
import {
    GetStaticPropsContext,
    GetStaticPropsResult,
    InferGetStaticPropsType
} from 'next';
import {
    ServicesTopQuery,
    ServicesTopQueryVariables,
    ServicesTopDocument,
    DynamicNavDocument,
    DynamicNavQueryVariables,
    DynamicNavQuery
} from '@/graphql/generated/graphql';

export function Index({
    other,
    popular,
    Header,
    Footer
}: InferGetStaticPropsType<typeof getStaticProps>) {
    return (
        <>
            <AppLayout
                title={'✂ The Fade Room Inc. ✂'}
                Header={Header}
                Footer={Footer}
                hero={<LandingHero />}
            >
                <Container clean className='fit'>
                    <ServiceTopCoalesced other={other} popular={popular} />
                </Container>
            </AppLayout>
        </>
    );
}

export async function getStaticProps(
    ctx: GetStaticPropsContext
): Promise<
    GetStaticPropsResult<{
        other: ServicesTopQuery['other'];
        popular: ServicesTopQuery['popular'];
        Header: DynamicNavQuery['Header'];
        Footer: DynamicNavQuery['Footer'];
    }>
> {
    const apolloClient = initializeApollo();
    await apolloClient.query<
        DynamicNavQuery,
        DynamicNavQueryVariables
    >({
        query: DynamicNavDocument,
        variables: {
            idHead: 'Header',
            idFoot: 'Footer'
        }
    });

    await apolloClient.query<
        ServicesTopQuery,
        ServicesTopQueryVariables
    >({
        query: ServicesTopDocument,
        variables: {
            other: 'all',
            popular: 'popular-service'
        }
    });
    return addApolloState(apolloClient, {
        props: {},
        revalidate: 10
    });
}
export default Index;


上述措施防止了现有的
wordpress
字段数据被传入的
wordpress
字段数据覆盖,从而解决了问题。事实证明,从无头WordPress端点迁移到OneGraph端点的过程比最初预期的要复杂得多,因此我想,如果有人在迁移过程中遇到类似问题,我会给出详细的响应;将
codegen.yml
更改为使用
numericEnums:false

生成:
graphql/generated/graphql.tsx:
插件:
-打字稿:
数字:假
为了找到这一点,我使用了
wordpressMenuodedTypeEnum的GraphQL SDL定义:

enum WordpressMenuNodeIdTypeEnum {
    # Identify a menu node by the Database ID.
    DATABASE_ID
    # Identify a menu node by the (hashed) Global ID.
    ID
    # Identify a menu node by it's name
    NAME
}

与前面的
codegen.yml
中的
numericEnums:true
设置一起使用,并在

正如您在屏幕截图中看到的,SDL定义被编译为数字枚举(运行时typescript枚举的标准)

然后我用
numericEnums:false
进行测试:


该输出看起来与您期望的一样,其中
wordpressMenuodedTypeEnum.Name
等于
“Name”
,因此Apollo获得的是期望值,而不是运行时typescript枚举值(
2
).

numericEnums:true
?它在此之前抛出了一个错误,因为onegraph输出数值枚举时不考虑标志。最初我将其设置为false,唯一的区别是将2包装为“2”,仅使用单独生成的WP类型。。。您可以在以后[通过手动工作]通过几个步骤自定义枚举。。。您可以设置自己的联合API;)架构是否可以在某个地方进行测试?我想看看数字枚举是从哪里来的!