Skip to content

Commit

Permalink
fix vitest-typescript-graphql relation. Correct the @app-types path (#11
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mahmoudmoravej authored Nov 14, 2023
1 parent 63602be commit dd7bab9
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 45 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ cp -R ../my-old-remix-app/app app

## Generate GraphQL types

run `yarn graphql`
run `yarn graphql` .

- Note: You need to have the API server mentioned in process.env.GRAPHQL_SCHEMA_URL run.

if it fails, run `yarn graphql --verbose`
configurations are in: graphql.codegen.ts
Note: GraphQL is introspective. This means you can query a GraphQL schema for details about itself.

## Helps / Docs
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,85 @@
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
import { FragmentDefinitionNode } from 'graphql';
import { Incremental } from './graphql';
import {
ResultOf,
DocumentTypeDecoration,
TypedDocumentNode,
} from "@graphql-typed-document-node/core";
import { FragmentDefinitionNode } from "graphql";
import { Incremental } from ".";


export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
infer TType,
any
>
? [TType] extends [{ ' $fragmentName'?: infer TKey }]
export type FragmentType<
TDocumentType extends DocumentTypeDecoration<any, any>,
> = TDocumentType extends DocumentTypeDecoration<infer TType, any>
? [TType] extends [{ " $fragmentName"?: infer TKey }]
? TKey extends string
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
? { " $fragmentRefs"?: { [key in TKey]: TType } }
: never
: never
: never;

// return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>,
): TType;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
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>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<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>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
fragmentType:
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined,
): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
fragmentType:
| FragmentType<DocumentTypeDecoration<TType, any>>
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined,
): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any;
}


export function makeFragmentData<
F extends DocumentTypeDecoration<any, any>,
FT extends ResultOf<F>
FT extends ResultOf<F>,
>(data: FT, _fragment: F): FragmentType<F> {
return data as FragmentType<F>;
}
export function isFragmentReady<TQuery, TFrag>(
queryNode: DocumentTypeDecoration<TQuery, any>,
fragmentNode: TypedDocumentNode<TFrag>,
data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
data:
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
| null
| undefined,
): data is FragmentType<typeof fragmentNode> {
const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
?.deferredFields;
const deferredFields = (
queryNode as {
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> };
}
).__meta__?.deferredFields;

if (!deferredFields) return true;

const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
const fragDef = fragmentNode.definitions[0] as
| FragmentDefinitionNode
| undefined;
const fragName = fragDef?.name?.value;

const fields = (fragName && deferredFields[fragName]) || [];
return fields.length > 0 && fields.every(field => data && field in data);
return fields.length > 0 && fields.every((field) => data && field in data);
}
1 change: 1 addition & 0 deletions app/@types/index.ts → app/@types/graphql/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./fragment-masking";
export * from "./schema";
File renamed without changes.
2 changes: 1 addition & 1 deletion app/routes/managers/route.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useManagersQuery } from "@app-types/graphql";
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { PencilIcon, UserPlusIcon, HomeIcon } from "@heroicons/react/24/solid";
import {
Expand All @@ -17,7 +18,6 @@ import {
Tooltip,
} from "@material-tailwind/react";
import { useNavigate } from "@remix-run/react";
import { useManagersQuery } from "~/@types/graphql";

const TABS = [
{
Expand Down
25 changes: 13 additions & 12 deletions app/routes/managers/tests/route.test.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
// import { json } from "@remix-run/node";
// import { useLoaderData } from "@remix-run/react";
import { createRemixStub } from "@remix-run/testing";
import { render, screen, waitFor } from "@testing-library/react";
import Managers from "../route";

describe("Group of tests", () => {
it("renders loader data", async () => {
// ⚠️ This would usually be a component you import from your app code
function MyComponent() {
const data = useLoaderData() as { message: string };
return <p>Message: {data.message}</p>;
}
it.skip("renders loader data", async () => {
// // ⚠️ This would usually be a component you import from your app code
// function MyComponent() {
// const data = useLoaderData() as { message: string };
// return <p>Message: {data.message}</p>;
// }

const RemixStub = createRemixStub([
{
path: "/",
Component: MyComponent,
loader() {
return json({ message: "hello" });
},
Component: Managers,
// loader() {
// return json({ message: "hello" });
// },
},
]);

Expand Down
2 changes: 1 addition & 1 deletion graphql.codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const config: CodegenConfig = {
schema: url,
documents: ["app/**/*.graphql"],
generates: {
"./app/@types/graphql.ts": {
"./app/@types/graphql/schema.ts": {
// preset: "client", we don't need gql version
plugins: [
"typescript",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"tailwindcss": "^3.3.3",
"typescript": "^5.1.6",
"vite": "^4.5.0",
"vite-tsconfig-paths": "^4.2.1",
"vitest": "^0.34.6"
},
"engines": {
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@app-types/*": ["app/@types/*"], //the reason that I use @app-types is https://stackoverflow.com/a/67892812/790811
"~/*": ["./app/*"]
},
"typeRoots": ["node_modules/@types", "app/@types", "./node_modules"],
"typeRoots": ["node_modules/@types", "./node_modules"],
"types": ["vitest/globals"],

"skipLibCheck": true, //becuase we have types in app/@types, we cannot exlude the node_modules folder. having this skip "*.d.ts" files.
Expand Down
8 changes: 8 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

const viteConfig = defineConfig({
plugins: [tsconfigPaths()],
});

export default viteConfig;
18 changes: 11 additions & 7 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { defineConfig } from "vitest/config";
import { defineConfig, mergeConfig } from "vitest/config";
import viteConfig from "./vite.config";

export default defineConfig({
test: {
environment: "jsdom",
globals: true,
},
});
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: "jsdom",
globals: true,
},
}),
);
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4796,6 +4796,11 @@ globby@^11.0.3, globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"

globrex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==

gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
Expand Down Expand Up @@ -8343,6 +8348,11 @@ ts-log@^2.2.3:
resolved "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz"
integrity sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==

tsconfck@^2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-2.1.2.tgz#f667035874fa41d908c1fe4d765345fcb1df6e35"
integrity sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==

tsconfig-paths@^3.14.2:
version "3.14.2"
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz"
Expand Down Expand Up @@ -8754,6 +8764,15 @@ vite-node@^0.28.5:
source-map-support "^0.5.21"
vite "^3.0.0 || ^4.0.0"

vite-tsconfig-paths@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.1.tgz#e53b89096b91d31a6d1e26f75999ea8c336a89ed"
integrity sha512-GNUI6ZgPqT3oervkvzU+qtys83+75N/OuDaQl7HmOqFTb0pjZsuARrRipsyJhJ3enqV8beI1xhGbToR4o78nSQ==
dependencies:
debug "^4.1.1"
globrex "^0.1.2"
tsconfck "^2.1.0"

"vite@^3.0.0 || ^4.0.0", "vite@^3.0.0 || ^4.0.0 || ^5.0.0-0", "vite@^3.1.0 || ^4.0.0 || ^5.0.0-0", vite@^4.1.4:
version "4.4.9"
resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz"
Expand Down

0 comments on commit dd7bab9

Please sign in to comment.