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

GraphQL Codegen for generating gql types #2485

Merged
merged 24 commits into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7e55b4f
Add generate types cli function | Automatically trigger in dev
dac09 May 11, 2021
8f33a50
Setup watcher for generate types
dac09 May 11, 2021
b3d69d6
Add commented out code for makeMergeSchema
dac09 May 11, 2021
cc0bebe
Forgot to add codegen deps
dac09 May 11, 2021
07647f0
Add types to tsconfig
dac09 May 11, 2021
4b44d71
Remove prebuild tasks
dac09 May 11, 2021
f6ca2a7
Merge branch 'main' of github.com:redwoodjs/redwood into feat/graphql…
dac09 May 19, 2021
fd13069
Progress: query operation and mutation operation results are globals
dac09 May 20, 2021
597c92d
Generify graphqlHooksProvider
dac09 May 20, 2021
3fef77c
Fix createCell types to avoid hacking OperationResult
dac09 May 20, 2021
cb91955
Allow passing through of apollo error
dac09 May 20, 2021
34e027f
Update cell generator and template to have types
dac09 May 20, 2021
52b5835
Transform to js, when not a typescript project
dac09 May 20, 2021
9d5efe5
Bit of cleanup
dac09 May 20, 2021
22310cb
Update cell generator snapshots
dac09 May 21, 2021
aa493e8
Merge branch 'main' of github.com:redwoodjs/redwood into feat/graphql…
dac09 May 21, 2021
36d669a
Merge template changes
dac09 May 21, 2021
9fe1ef2
Update cell list template
dac09 May 21, 2021
1a67d1e
Get tests working | add compute for readablity
dac09 May 21, 2021
af6c749
Update formatting on cell template
dac09 May 21, 2021
2a14dd2
Merge branch 'main' of github.com:redwoodjs/redwood into feat/graphql…
dac09 May 24, 2021
b847c5d
PR Comments
dac09 May 24, 2021
c65c9e0
Lint
dac09 May 24, 2021
e02c4e6
Sometimes vscode just needs a refresh 🤷
dac09 May 24, 2021
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
7 changes: 6 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@
"prompts": "^2.4.1",
"rimraf": "^3.0.2",
"terminal-link": "^2.1.1",
"yargs": "^16.0.3"
"yargs": "^16.0.3",
"@graphql-codegen/cli": "^1.21.4",
"@graphql-codegen/typescript": "^1.22.0",
"@graphql-codegen/typescript-operations": "^1.17.16",
"@graphql-codegen/typescript-react-apollo": "^2.2.4",
"@graphql-codegen/typescript-resolvers": "^1.19.1"
},
"devDependencies": {
"@types/listr": "^0.14.3",
Expand Down
17 changes: 11 additions & 6 deletions packages/cli/src/commands/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import terminalLink from 'terminal-link'

import { getConfig } from '@redwoodjs/internal'
import { shutdownPort } from '@redwoodjs/internal/devtools'
import { getProject } from '@redwoodjs/structure'
const project = getProject()

import { getPaths } from 'src/lib'
import c from 'src/lib/colors'
import { generatePrismaClient } from 'src/lib/generatePrismaClient'
import runPreBuildTasks from 'src/lib/runPreBuildTasks'

export const command = 'dev [side..]'
export const description = 'Start development servers for api, and web'
Expand Down Expand Up @@ -53,9 +54,6 @@ export const handler = async ({
const API_DIR_SRC = getPaths().api.src
const WEB_DIR_SRC = getPaths().web.src

// Run tasks like type generate, etc.
runPreBuildTasks()

if (side.includes('api')) {
try {
await generatePrismaClient({
Expand Down Expand Up @@ -86,6 +84,7 @@ export const handler = async ({
}
}

/** @type {Record<string, import('concurrently').CommandObj>} */
const jobs = {
api: {
name: 'api',
Expand All @@ -101,10 +100,16 @@ export const handler = async ({
command: `cd "${path.join(
BASE_DIR,
'web'
)}" && yarn webpack-dev-server --config ../node_modules/@redwoodjs/core/config/webpack.development.js ${forward}`,
)}" && yarn cross-env NODE_ENV=development webpack-dev-server --config ../node_modules/@redwoodjs/core/config/webpack.development.js ${forward}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also allow us to use tailwind's JIT without more hassle

prefixColor: 'blue',
runWhen: () => fs.existsSync(WEB_DIR_SRC),
},
typeGenerator: {
name: 'typeGenerator',
command: 'yarn rw generate types --watch',
prefixColor: 'green',
runWhen: () => project.isTypeScriptProject,
},
}

if (esbuild) {
Expand All @@ -118,7 +123,7 @@ export const handler = async ({

concurrently(
Object.keys(jobs)
.map((n) => side.includes(n) && jobs[n])
.map((n) => (side.includes(n) || n === 'typeGenerator') && jobs[n])
.filter((job) => job && job.runWhen()),
{
prefix: '{name} |',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export const Success = ({ userProfile }) => {

exports[`creates a cell mock with a camelCase word name 1`] = `
"// Define your own mock data here:
export const standard = (/* vars, { ctx, req } */) => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dunno why the snapshots do this weird thing. Its not actually doing this when we actually generate 🤷‍♂️

export const standard = () => /* vars, { ctx, req } */ ({
userProfile: {
id: 42,
},
Expand All @@ -179,7 +179,7 @@ export const standard = (/* vars, { ctx, req } */) => ({

exports[`creates a cell mock with a kebabCase word name 1`] = `
"// Define your own mock data here:
export const standard = (/* vars, { ctx, req } */) => ({
export const standard = () => /* vars, { ctx, req } */ ({
userProfile: {
id: 42,
},
Expand All @@ -189,7 +189,7 @@ export const standard = (/* vars, { ctx, req } */) => ({

exports[`creates a cell mock with a multi word name 1`] = `
"// Define your own mock data here:
export const standard = (/* vars, { ctx, req } */) => ({
export const standard = () => /* vars, { ctx, req } */ ({
userProfile: {
id: 42,
},
Expand All @@ -199,7 +199,7 @@ export const standard = (/* vars, { ctx, req } */) => ({

exports[`creates a cell mock with a single word name 1`] = `
"// Define your own mock data here:
export const standard = (/* vars, { ctx, req } */) => ({
export const standard = () => /* vars, { ctx, req } */ ({
user: {
id: 42,
},
Expand All @@ -209,7 +209,7 @@ export const standard = (/* vars, { ctx, req } */) => ({

exports[`creates a cell mock with a snakeCase word name 1`] = `
"// Define your own mock data here:
export const standard = (/* vars, { ctx, req } */) => ({
export const standard = () => /* vars, { ctx, req } */ ({
userProfile: {
id: 42,
},
Expand Down Expand Up @@ -338,7 +338,7 @@ export default { title: 'Cells/UserProfileCell' }
`;

exports[`creates a cell test with a camelCase word name 1`] = `
"import { render, screen } from '@redwoodjs/testing'
"import { render } from '@redwoodjs/testing'
import { Loading, Empty, Failure, Success } from './UserProfileCell'
import { standard } from './UserProfileCell.mock'

Expand All @@ -364,7 +364,8 @@ describe('UserProfileCell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand All @@ -376,7 +377,7 @@ describe('UserProfileCell', () => {
`;

exports[`creates a cell test with a kebabCase word name 1`] = `
"import { render, screen } from '@redwoodjs/testing'
"import { render } from '@redwoodjs/testing'
import { Loading, Empty, Failure, Success } from './UserProfileCell'
import { standard } from './UserProfileCell.mock'

Expand All @@ -402,7 +403,8 @@ describe('UserProfileCell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand All @@ -414,7 +416,7 @@ describe('UserProfileCell', () => {
`;

exports[`creates a cell test with a multi word name 1`] = `
"import { render, screen } from '@redwoodjs/testing'
"import { render } from '@redwoodjs/testing'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another one of the weird snapshot things. Something to do with tsToJs maybe

import { Loading, Empty, Failure, Success } from './UserProfileCell'
import { standard } from './UserProfileCell.mock'

Expand All @@ -440,7 +442,8 @@ describe('UserProfileCell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand All @@ -452,7 +455,7 @@ describe('UserProfileCell', () => {
`;

exports[`creates a cell test with a single word name 1`] = `
"import { render, screen } from '@redwoodjs/testing'
"import { render } from '@redwoodjs/testing'
import { Loading, Empty, Failure, Success } from './UserCell'
import { standard } from './UserCell.mock'

Expand All @@ -478,7 +481,8 @@ describe('UserCell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand All @@ -490,7 +494,7 @@ describe('UserCell', () => {
`;

exports[`creates a cell test with a snakeCase word name 1`] = `
"import { render, screen } from '@redwoodjs/testing'
"import { render } from '@redwoodjs/testing'
import { Loading, Empty, Failure, Success } from './UserProfileCell'
import { standard } from './UserProfileCell.mock'

Expand All @@ -516,7 +520,8 @@ describe('UserProfileCell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand Down
10 changes: 8 additions & 2 deletions packages/cli/src/commands/generate/cell/cell.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pascalcase from 'pascalcase'
import pluralize from 'pluralize'

import { transformTSToJS } from 'src/lib'
import { getSchema } from 'src/lib'

import { yargsDefaults } from '../../generate'
Expand Down Expand Up @@ -87,7 +88,7 @@ export const files = async ({
extension: generateTypescript ? '.tsx' : '.js',
webPathSection: REDWOOD_WEB_PATH_NAME,
generator: 'cell',
templatePath: `cell${templateNameSuffix}.js.template`,
templatePath: `cell${templateNameSuffix}.tsx.template`,
templateVars: {
operationName,
idType,
Expand Down Expand Up @@ -141,8 +142,12 @@ export const files = async ({
// "path/to/fileB": "<<<template>>>",
// }
return files.reduce((acc, [outputPath, content]) => {
const template = generateTypescript
? content
: transformTSToJS(outputPath, content)

return {
[outputPath]: content,
[outputPath]: template,
...acc,
}
}, {})
Expand All @@ -152,6 +157,7 @@ export const { command, description, builder, handler } =
createYargsForComponentGeneration({
componentName: 'cell',
filesFn: files,
generateTypes: true,
optionsObj: {
...yargsDefaults,
list: {
Expand Down
17 changes: 0 additions & 17 deletions packages/cli/src/commands/generate/cell/templates/cell.js.template

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { ${operationName} } from 'types/gql-types'
import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web'

export const QUERY = gql`
query ${operationName}($id: ${idType}!) {
${camelName}: ${camelName}(id: $id) {
id
}
}
`

export const Loading = () => <div>Loading...</div>

export const Empty = () => <div>Empty</div>

export const Failure = ({ error }: CellFailureProps) => (
<div style={{ color: 'red' }}>Error: {error.message}</div>
)

export const Success = ({ ${camelName} }: CellSuccessProps<${operationName}>) => {
return <div>{JSON.stringify(${camelName})}</div>
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { ${operationName} } from 'types/gql-types'
import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web'


export const QUERY = gql`
query ${operationName} {
${camelName} {
id
}
}
`

export const Loading = () => <div>Loading...</div>

export const Empty = () => <div>Empty</div>

export const Failure = ({ error }: CellFailureProps) => (
<div style={{ color: 'red' }}>Error: {error.message}</div>
)

export const Success = ({ ${camelName} }: CellSuccessProps<${operationName}>) => {
return (
<ul>
{${camelName}.map((item) => {
return <li key={item.id}>{JSON.stringify(item)}</li>
})}
</ul>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ describe('${pascalName}Cell', () => {
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// expect(screen.getByText('Hello, world')).toBeInTheDocument()
// 1. import { screen } from '@redwoodjs/testing'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()

it('renders Success successfully', async () => {
expect(() => {
Expand Down
Loading