Skip to content

Commit

Permalink
Add demo app
Browse files Browse the repository at this point in the history
  • Loading branch information
lukebennett88 committed Nov 8, 2022
1 parent 48168e5 commit 19e370f
Show file tree
Hide file tree
Showing 18 changed files with 722 additions and 128 deletions.
1 change: 1 addition & 0 deletions demo-app/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GRAPHQL_API_URL=https://countries.trevorblades.com/graphql
6 changes: 6 additions & 0 deletions demo-app/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"plugins": ["@ts-gql"],
"rules": {
"@ts-gql/ts-gql": "error"
}
}
39 changes: 39 additions & 0 deletions demo-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# ts-gql
__generated__
3 changes: 3 additions & 0 deletions demo-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ts-gql demo

Demo Next.js website showing how to configure the various ts-gql packages.
8 changes: 8 additions & 0 deletions demo-app/fetch-graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* We're using [@ts-gql/fetch](https://github.com/Thinkmill/ts-gql/tree/main/packages/fetch)
* here, but you can use any GraphQL client that supports [@graphql-typed-document-node/core](https://github.com/dotansimha/graphql-typed-document-node).
*/

import { createFetcher } from "@ts-gql/fetch";

export const fetchGraphQL = createFetcher(process.env.GRAPHQL_API_URL!);
20 changes: 20 additions & 0 deletions demo-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* `@ts-gql/next` starts ts-gql's watcher when you start Next.js's dev server.
* Note that it _does not_ generate the artifacts when running next build,
* you should run `ts-gql build` in a script before running `next build`.
*
* We're using the `@preconstruct/next` plugin here to make sure that local
* packages still work. Unless you are using preconstruct in your project,
* you shouldn't need to use this plugin.
*/

const withPreconstruct = require('@preconstruct/next');
const { withTsGql } = require('@ts-gql/next');

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}

module.exports = withTsGql(withPreconstruct(nextConfig))
40 changes: 40 additions & 0 deletions demo-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "ts-gql-demo",
"version": "0.1.0",
"private": true,
"repository": "https://github.com/Thinkmill/ts-gql/tree/main/demo-app",
"scripts": {
"postinstall": "ts-gql build",
"build": "ts-gql build && next build",
"dev": "next dev",
"lint": "next lint",
"start": "next start"
},
"dependencies": {
"@preconstruct/next": "^4.0.0",
"@ts-gql/compiler": "0.16.1",
"@ts-gql/eslint-plugin": "0.8.4",
"@ts-gql/fetch": "0.1.2",
"@ts-gql/next": "17.0.0",
"@ts-gql/tag": "0.7.0",
"@types/node": "^13.13.2",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"eslint": "^8.25.0",
"graphql": "^16.3.0",
"next": "^12.0.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"typescript": "^4.5.2"
},
"devDependencies": {
"autoprefixer": "^10.4.13",
"postcss": "^8.4.18",
"tailwindcss": "^3.2.2"
},
"ts-gql": {
"addTypenames": false,
"mode": "no-transform",
"schema": "./schema.graphql"
}
}
6 changes: 6 additions & 0 deletions demo-app/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import '../styles/globals.css'
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
97 changes: 97 additions & 0 deletions demo-app/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { OperationData } from "@ts-gql/tag/no-transform";
import { gql } from "@ts-gql/tag/no-transform";
import type { GetServerSideProps, InferGetServerSidePropsType } from "next";
import Head from "next/head";
import { Fragment } from "react";

import { fetchGraphQL } from "../fetch-graphql";

const getCountriesQuery = gql`
query getCountries {
continents {
name
countries {
name
emoji
}
}
}
` as import("../__generated__/ts-gql/getCountries").type;

// You can use `OperationData` to extract the types from a query or mutation.
type Continents = OperationData<typeof getCountriesQuery>["continents"];

export const getServerSideProps: GetServerSideProps<{
continents: Continents;
}> = async () => {
const result = await fetchGraphQL(getCountriesQuery);

if (!result.continents) {
throw new Error("Query failed");
}

return {
props: {
continents: result.continents,
},
};
};

export default function Home({
continents,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<Fragment>
<Head>
<title>ts-gql demo</title>
<meta
name="description"
content="Demo Next.js site showing how to set up ts-gql"
/>
<link rel="icon" href="/favicon.ico" />
</Head>

<main className="px-4 py-8 max-w-5xl mx-auto flex flex-col gap-4">
<h1 className="text-4xl font-semibold">ts-gql demo</h1>
<p>
This is a demo of ts-gql using the continent API found here:{" "}
<a
href="https://countries.trevorblades.com/"
className="text-blue-700 underline"
>
https://countries.trevorblades.com/
</a>
</p>
<p>
You can learn more about ts-gql here:{" "}
<a
href="https://github.com/thinkmill/ts-gql"
className="text-blue-700 underline"
>
https://github.com/thinkmill/ts-gql
</a>
</p>
<div className="flex flex-col gap-4">
{continents.map((continent) => (
<div
key={continent.name}
className="flex flex-col gap-8 border p-4 rounded shadow-inner bg-gray-100"
>
<h2 className="text-3xl font-semibold">{continent.name}</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{continent.countries.map((country) => (
<div key={country.name}>
<span aria-label={`Flag for ${country.name}`} role="img">
{country.emoji}
</span>{" "}
{country.name}
</div>
))}
</div>
</div>
))}
</div>
</main>
</Fragment>
);
}
6 changes: 6 additions & 0 deletions demo-app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file added demo-app/public/favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions demo-app/public/vercel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions demo-app/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copy of the Countries GraphQL API schema: https://countries.trevorblades.com/
#
# You can point GraphQL codegen at the API endpoint to generate this file and
# keep it up to date, but that is beyond the scope of this demo.

directive @extends on INTERFACE | OBJECT

directive @external on FIELD_DEFINITION | OBJECT

directive @key(fields: String!) on INTERFACE | OBJECT

directive @provides(fields: String!) on FIELD_DEFINITION

directive @requires(fields: String!) on FIELD_DEFINITION

type Continent {
code: ID!
countries: [Country!]!
name: String!
}

input ContinentFilterInput {
code: StringQueryOperatorInput
}

type Country {
capital: String
code: ID!
continent: Continent!
currency: String
emoji: String!
emojiU: String!
languages: [Language!]!
name: String!
native: String!
phone: String!
states: [State!]!
}

input CountryFilterInput {
code: StringQueryOperatorInput
continent: StringQueryOperatorInput
currency: StringQueryOperatorInput
}

type Language {
code: ID!
name: String
native: String
rtl: Boolean!
}

input LanguageFilterInput {
code: StringQueryOperatorInput
}

type Query {
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
continent(code: ID!): Continent
continents(filter: ContinentFilterInput): [Continent!]!
countries(filter: CountryFilterInput): [Country!]!
country(code: ID!): Country
language(code: ID!): Language
languages(filter: LanguageFilterInput): [Language!]!
}

type State {
code: String
country: Country!
name: String!
}

input StringQueryOperatorInput {
eq: String
glob: String
in: [String]
ne: String
nin: [String]
regex: String
}

scalar _Any

union _Entity = Continent | Country | Language

type _Service {
"""
The sdl representing the federated service capabilities. Includes federation directives, removes federation types, and includes rest of full schema after schema directives have been applied
"""
sdl: String
}
3 changes: 3 additions & 0 deletions demo-app/styles/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
8 changes: 8 additions & 0 deletions demo-app/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./pages/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
20 changes: 20 additions & 0 deletions demo-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
Loading

0 comments on commit 19e370f

Please sign in to comment.