Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do "typecasting" the way graphql-codegen intends #14

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const config: CodegenConfig = {
"./src/gql/": {
preset: "client",
plugins: [],
presetConfig: {
fragmentMasking: { unmaskFunctionName: "getFragment" },
},
},
},
};
Expand Down
10 changes: 5 additions & 5 deletions src/gql/fragment-masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,26 @@ export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>>
: never;

// return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>(
export function getFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
export function getFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>(
export function getFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
): ReadonlyArray<TType>;
// return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>(
export function getFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>(
export function getFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
): TType | ReadonlyArray<TType> | null | undefined {
Expand Down
14 changes: 12 additions & 2 deletions src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
*/
const documents = {
"\n query ProjectQuery($projectId: ID!) {\n project(id: $projectId) {\n id\n name\n webUrl\n lastBuild {\n branch\n number\n }\n }\n }\n": types.ProjectQueryDocument,
"\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n": types.BuildDocument,
"\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n": types.BuildDocument,
"\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n": types.BuildFieldsFragmentDoc,
"\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n": types.TestFieldsFragmentDoc,
};

/**
Expand All @@ -38,7 +40,15 @@ export function graphql(source: "\n query ProjectQuery($projectId: ID!) {\n
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n"): (typeof documents)["\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n"];
export function graphql(source: "\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n"): (typeof documents)["\n query Build($hasBuildId: Boolean!, $buildId: ID!, $projectId: ID!, $branch: String!) {\n build(id: $buildId) @include(if: $hasBuildId) {\n ...BuildFields\n }\n project(id: $projectId) @skip(if: $hasBuildId) {\n lastBuild(branches: [$branch]) {\n ...BuildFields\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n"): (typeof documents)["\n fragment BuildFields on Build {\n __typename\n id\n number\n branch\n commit\n status\n browsers {\n id\n key\n name\n }\n ... on StartedBuild {\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n ... on CompletedBuild {\n result\n changeCount: testCount(results: [ADDED, CHANGED, FIXED])\n startedAt\n tests {\n nodes {\n ...TestFields\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n"): (typeof documents)["\n fragment TestFields on Test {\n id\n status\n result\n webUrl\n comparisons {\n id\n result\n browser {\n id\n key\n name\n version\n }\n captureDiff {\n diffImage {\n imageUrl\n }\n }\n headCapture {\n captureImage {\n imageUrl\n }\n }\n viewport {\n id\n name\n width\n isDefault\n }\n }\n parameters {\n viewport {\n id\n name\n width\n isDefault\n }\n }\n story {\n storyId\n }\n }\n"];

export function graphql(source: string) {
return (documents as any)[source] ?? {};
Expand Down
31 changes: 30 additions & 1 deletion src/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ export type Scalars = {
URL: { input: any; output: any; }
};

export type Account = Node & Temporal & {
__typename?: 'Account';
avatarUrl?: Maybe<Scalars['String']['output']>;
/** When the entity was first created in Chromatic. */
createdAt: Scalars['DateTime']['output'];
/** GraphQL node identifier */
id: Scalars['ID']['output'];
/** Account name, typically the repository owner. */
name: Scalars['String']['output'];
projects?: Maybe<Array<Maybe<Project>>>;
/** When the entity was last updated or created in Chromatic. */
updatedAt: Scalars['DateTime']['output'];
};


export type AccountProjectsArgs = {
limit?: InputMaybe<Scalars['Int']['input']>;
};

/** A build that has been pre-announced but not published yet. */
export type AnnouncedBuild = Build & Node & Temporal & {
__typename?: 'AnnouncedBuild';
Expand Down Expand Up @@ -695,6 +714,8 @@ export type Project = Node & Temporal & {
lastBuild?: Maybe<Build>;
/** Project name, typically the repository name. */
name: Scalars['String']['output'];
/** Project token to start builds with Chromatic CLI. */
projectToken: Scalars['String']['output'];
/** Account information which does not require the `account` scope. */
publicAccountInfo: PublicAccountInfo;
/** When the entity was last updated or created in Chromatic. */
Expand Down Expand Up @@ -763,12 +784,19 @@ export type PublishedBuild = Build & Node & Temporal & {

export type Query = {
__typename?: 'Query';
account?: Maybe<Account>;
build?: Maybe<Build>;
bulkFigmaMetadata?: Maybe<Array<Maybe<FigmaMetadata>>>;
figmaMetadata?: Maybe<FigmaMetadata>;
figmaMetadataById?: Maybe<FigmaMetadata>;
project?: Maybe<Project>;
storybook?: Maybe<Storybook>;
viewer?: Maybe<User>;
};


export type QueryAccountArgs = {
id: Scalars['ID']['input'];
};


Expand Down Expand Up @@ -1102,8 +1130,9 @@ export enum TestStatus {
Pending = 'PENDING'
}

export type User = Node & Temporal & {
export type User = Node & {
__typename?: 'User';
accounts: Array<Account>;
avatarUrl?: Maybe<Scalars['URL']['output']>;
/** When the entity was first created in Chromatic. */
createdAt: Scalars['DateTime']['output'];
Expand Down
12 changes: 8 additions & 4 deletions src/screens/VisualTests/VisualTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import { useQuery } from "urql";
import { IconButton } from "../../components/IconButton";
import { Bar, Col, Row, Section, Sections, Text } from "../../components/layout";
import { TooltipMenu } from "../../components/TooltipMenu";
import { graphql } from "../../gql";
import { getFragment, graphql } from "../../gql";
import {
BuildFieldsFragment,
BuildQuery,
BuildQueryVariables,
TestFieldsFragment,
Expand All @@ -34,6 +33,9 @@ const QueryBuild = graphql(/* GraphQL */ `
}
}
}
`);

const FragmentBuildFields = graphql(/* GraphQL */ `
fragment BuildFields on Build {
__typename
id
Expand Down Expand Up @@ -66,6 +68,8 @@ const QueryBuild = graphql(/* GraphQL */ `
}
}
}
`);
const FragmentTestFields = graphql(/* GraphQL */ `
fragment TestFields on Test {
id
status
Expand Down Expand Up @@ -149,7 +153,7 @@ export const VisualTests = ({
}
}, [isRunning, setIsOutdated, setIsRunning, data]);

const build = (data?.build || data?.project.lastBuild) as BuildFieldsFragment;
const build = getFragment(FragmentBuildFields, data?.build || data?.project.lastBuild);

useEffect(() => {
let interval: any;
Expand Down Expand Up @@ -206,7 +210,7 @@ export const VisualTests = ({
);
}

const allTests = ("tests" in build ? build.tests.nodes : []) as TestFieldsFragment[];
const allTests = getFragment(FragmentTestFields, "tests" in build ? build.tests.nodes : []);
const tests = allTests.filter((test) => test.story?.storyId === storyId);

const { changeCount, brokenCount, resultsByBrowser, resultsByViewport, viewportInfoById } =
Expand Down