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

yarn rw setup graphql fragments #9811

Merged
merged 7 commits into from
Jan 11, 2024
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = {
'packages/babel-config/src/__tests__/__fixtures__/**/*',
'packages/core/**/__fixtures__/**/*',
'packages/codemods/**/__testfixtures__/**/*',
'packages/cli/**/__testfixtures__/**/*',
'packages/core/config/storybook/**/*',
'packages/studio/dist-*/**/*',
],
Expand Down
35 changes: 34 additions & 1 deletion docs/docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1999,11 +1999,44 @@ We perform a simple compatibility check in an attempt to make you aware of poten

It's the author of the npm package's responsibility to specify the correct compatibility range, so **you should always research the packages you use with this command**. Especially since they will be executing code on your machine!

### setup graphql

This command creates the necessary files to support GraphQL features like fragments.

#### Usage

Run `yarn rw setup graphql <feature>`

#### setup graphql fragments

This command creates the necessary configuration to start using [GraphQL Fragments](./graphql/fragments.md).

```
yarn redwood setup graphql fragments
```

| Arguments & Options | Description |
| :------------------ | :--------------------------------------- |
| `--force, -f` | Overwrite existing files and skip checks |

#### Usage

Run `yarn rw setup graphql fragments`

#### Example

```bash
~/redwood-app$ yarn rw setup graphql fragments
✔ Update Redwood Project Configuration to enable GraphQL Fragments
✔ Generate possibleTypes.ts
✔ Import possibleTypes in App.tsx
✔ Add possibleTypes to the GraphQL cache config
```

### setup realtime

This command creates the necessary files, installs the required packages, and provides examples to setup RedwoodJS Realtime from GraphQL live queries and subscriptions. See the Realtime docs for more information.


```
yarn redwood setup realtime
```
Expand Down
28 changes: 18 additions & 10 deletions docs/docs/graphql/fragments.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ With `registerFragment`, you can register a fragment with the registry and get b

which can then be used to work with the registered fragment.

### Setup

`yarn rw setup graphql fragments`

See more in [cli commands - setup graphql fragments](../cli-commands.md#setup-graphql-fragments).

### registerFragment

To register a fragment, you can simply register it with `registerFragment`.
Expand Down Expand Up @@ -200,7 +206,7 @@ the `getCacheKey` is a function where `getCacheKey(42)` would return `Book:42`.
import { registerFragment } from '@redwoodjs/web/apollo'

const { useRegisteredFragment } = registerFragment(
...
// ...
)
```

Expand Down Expand Up @@ -281,17 +287,19 @@ To make this easier to maintain, RedwoodJS GraphQL CodeGen automatically generat


```ts
// web/src/App.tsx

import possibleTypes from 'src/graphql/possibleTypes'

...
/// web/src/App.tsx
<RedwoodApolloProvider
graphQLClientConfig={{
cacheConfig: {
...possibleTypes,
},
}}
>
// ...

const graphQLClientConfig = {
cacheConfig: {
...possibleTypes,
},
}

<RedwoodApolloProvider graphQLClientConfig={graphQLClientConfig}>
```

To generate the `src/graphql/possibleTypes` file, enable fragments in `redwood.toml`:
Expand Down
12 changes: 11 additions & 1 deletion packages/cli-helpers/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,17 @@ export const transformTSToJS = (filename: string, content: string) => {
*/
export const prettierOptions = () => {
try {
return require(path.join(getPaths().base, 'prettier.config.js'))
const options = require(path.join(getPaths().base, 'prettier.config.js'))

if (options.tailwindConfig?.startsWith('.')) {
// Make this work with --cwd
options.tailwindConfig = path.join(
process.env.RWJS_CWD ?? process.cwd(),
options.tailwindConfig
)
}

return options
} catch (e) {
return undefined
}
Expand Down
9 changes: 0 additions & 9 deletions packages/cli/jest.config.js

This file was deleted.

39 changes: 39 additions & 0 deletions packages/cli/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Config } from 'jest'

const config: Config = {
projects: [
{
displayName: 'root',
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/*.test.[jt]s?(x)'],
testPathIgnorePatterns: [
'__fixtures__',
'__testfixtures__',
'__codemod_tests__',
'__tests__/utils/*',
'__tests__/fixtures/*',
'.d.ts',
'dist',
],
moduleNameMapper: {
'^src/(.*)': '<rootDir>/src/$1',
},
setupFilesAfterEnv: ['./jest.setup.js'],
},
{
displayName: 'setup codemods',
testMatch: ['**/commands/setup/**/__codemod_tests__/*.ts'],
testPathIgnorePatterns: [
'__fixtures__',
'__testfixtures__',
'__tests__/utils/*',
'__tests__/fixtures/*',
'.d.ts',
'dist',
],
setupFilesAfterEnv: ['./src/jest.codemods.setup.ts'],
},
],
testTimeout: 20_000,
}

export default config
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"scripts": {
"build": "yarn build:js",
"build:clean-dist": "rimraf 'dist/**/*/__tests__' --glob",
"build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\" --copy-files --no-copy-ignored && yarn build:clean-dist",
"build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\" --ignore \"src/**/__tests__/**\" --ignore \"src/**/__testfixtures__/**\" --copy-files --no-copy-ignored && yarn build:clean-dist",
"build:pack": "yarn pack -o redwoodjs-cli.tgz",
"build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build && yarn fix:permissions\"",
"dev": "RWJS_CWD=../../__fixtures__/example-todo-main node dist/index.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import fs from 'node:fs'
import path from 'node:path'

import { findUp } from '@redwoodjs/project-config'

describe('fragments graphQLClientConfig', () => {
test('App.tsx with no graphQLClientConfig', async () => {
await matchFolderTransform('appGqlConfigTransform', 'config-simple', {
useJsCodeshift: true,
})
})

test('App.tsx with existing inline graphQLClientConfig', async () => {
await matchFolderTransform('appGqlConfigTransform', 'existingPropInline', {
useJsCodeshift: true,
})
})

test('App.tsx with existing graphQLClientConfig in separate variable', async () => {
await matchFolderTransform(
'appGqlConfigTransform',
'existingPropVariable',
{
useJsCodeshift: true,
}
)
})

test('App.tsx with existing graphQLClientConfig in separate variable, without cacheConfig property', async () => {
await matchFolderTransform(
'appGqlConfigTransform',
'existingPropVariableNoCacheConfig',
{
useJsCodeshift: true,
}
)
})

test('App.tsx with existing graphQLClientConfig in separate variable with non-standard name', async () => {
await matchFolderTransform(
'appGqlConfigTransform',
'existingPropVariableCustomName',
{
useJsCodeshift: true,
}
)
})

test('test-project App.tsx', async () => {
const rootFwPath = path.dirname(findUp('lerna.json') || '')
const testProjectAppTsx = fs.readFileSync(
path.join(
rootFwPath,
'__fixtures__',
'test-project',
'web',
'src',
'App.tsx'
),
'utf-8'
)
await matchInlineTransformSnapshot(
'appGqlConfigTransform',
testProjectAppTsx,
`import { FatalErrorBoundary, RedwoodProvider } from \"@redwoodjs/web\";
import { RedwoodApolloProvider } from \"@redwoodjs/web/apollo\";

import FatalErrorPage from \"src/pages/FatalErrorPage\";
import Routes from \"src/Routes\";

import { AuthProvider, useAuth } from \"./auth\";

import \"./scaffold.css\";
import \"./index.css\";

const graphQLClientConfig = {
cacheConfig: {
possibleTypes: possibleTypes.possibleTypes,
},
};

const App = () => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate=\"%PageTitle | %AppTitle\">
<AuthProvider>
<RedwoodApolloProvider
useAuth={useAuth}
graphQLClientConfig={graphQLClientConfig}
>
<Routes />
</RedwoodApolloProvider>
</AuthProvider>
</RedwoodProvider>
</FatalErrorBoundary>
);

export default App;
`
)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
describe('fragments possibleTypes import', () => {
test('Default App.tsx', async () => {
await matchFolderTransform('appImportTransform', 'import-simple', {
useJsCodeshift: true,
})
})

test('App.tsx with existing import', async () => {
await matchFolderTransform('appImportTransform', 'existingImport', {
useJsCodeshift: true,
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import possibleTypes from 'src/graphql/possibleTypes'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './scaffold.css'
import './index.css'

const App = () => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
<Routes />
</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)

export default App
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import possibleTypes from 'src/graphql/possibleTypes'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './scaffold.css'
import './index.css'

const graphQLClientConfig = {
cacheConfig: {
possibleTypes: possibleTypes.possibleTypes,
},
}

const App = () => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider graphQLClientConfig={graphQLClientConfig}>
<Routes />
</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)

export default App
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import possibleTypes from 'src/graphql/possibleTypes'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './scaffold.css'
import './index.css'

const App = () => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
<Routes />
</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)

export default App
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import possibleTypes from 'src/graphql/possibleTypes'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './scaffold.css'
import './index.css'

const App = () => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
<Routes />
</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)

export default App
Loading
Loading