Skip to content

Commit

Permalink
Add initial 4.0 migration guide
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes committed Apr 8, 2023
1 parent 3933323 commit 5b2726e
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 22 deletions.
2 changes: 0 additions & 2 deletions packages/plugin-dataloader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ const UserNode = builder.loadableNode('UserNode', {
id: {
resolve: (user) => user.id,
},
// For loadable nodes, we need to include an isTypeOf check if the first arg is a string
isTypeOf: (obj) => obj instanceof User,
load: (ids: string[], context: ContextType) => context.loadUsersById(ids),
fields: (t) => ({}),
});
Expand Down
15 changes: 2 additions & 13 deletions website/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import './util/build-index.mjs';
import dotenv from 'dotenv';
import graphql from 'highlightjs-graphql';
import highlight from 'rehype-highlight';
import slug from 'rehype-slug';
import frontmatter from 'remark-frontmatter';
Expand All @@ -13,18 +12,8 @@ export default withMDX({
extension: /\.mdx?$/,
options: {
providerImportSource: '@mdx-js/react',
remarkPlugins: [
frontmatter,
remarkMdxFrontmatter,
// [
// torchlight,
// {
// token: process.env.TORCH_LIGHT_TOKEN,
// theme: 'one-dark-pro',
// },
// ],
],
rehypePlugins: [slug, [highlight, { languages: { graphql: graphql.definer } }]],
remarkPlugins: [frontmatter, remarkMdxFrontmatter],
rehypePlugins: [slug, [highlight, { languages: {} }]],
},
})({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
Expand Down
214 changes: 214 additions & 0 deletions website/pages/docs/migrations/4.0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
---
title: '4.0 Migration guide'
name: '4.0'
menu: Migrations
description: Migration guide for upgrading from Pothos 3.x to Pothos 4.0
---

import { DocsPage } from '../../../components/Docs/Page';
import { buildNav } from '../../../util/build-nav';

export default DocsPage;

export const getStaticProps = () => ({ props: { nav: buildNav() } });

# Migrating from Pothos 3.x to 4.0

The `4.0` release of Pothos is largely focused on updating 4 things:

1. Improving outdated defaults to be more consistant and aligned with best practices
2. Updating naming of some config options to be more consistent
3. Updating minimum versions of peer dependencies
4. Updating internal types to support some previously challenging plugin patterns

For most users the first 2 sets of changes will cover the majority of changes affecting their
applications. To make the make the upgrade as simple as possible, some options were added to
maintain the defaults and option names from `3.x` which are described in the simple upgrade section
below.

## New minimum versions

- `typescript`: `4.7.0`
- `graphql`: `16.6.0`
- `node`: `14.0`

## Simple Upgrade (restore 3.0 options and defaults)

You can restore the 3.x defaults by adding the Defaults versions to both the SchemaTypes and the
builder options:

```ts
const builder = new SchemaBuilder<{
Defaults: 'v3';
}>({
defaults: 'v3',
});
```

This will restore all the defaults and config options from previous Pothos versions for both core
and plugins.

## Manual update

There are a number of new defaults and changes to options for various plugins. To fully upgrade to
4.0 see the full list of breaking changes below:

# Breaking API Changes:

This section covers breaking API changes that can be automatically reverted by using the Simple
Upgrade process described above.

Changes to types and classes outside the main Pothos API are described in the next section. Those
changes will primarily affect other plugins and tools written for pothos, but may be relevant to
some type helpers you have created.

## `@pothos/core`

### Default ID Scalar types

The default types for the built in `ID` Scalar has been changed to more closely match the behavior
of Javascript GraphQL server implementations:

```ts
interface IDType {
Input: string;
Output: number | string | bigint;
}
```

This will make working with IDs in arguments and input types easier by avoiding unnecissary type
checks to see if an `ID` is a `number` or `string`.

When returning an `ID` from a scalar you will be able to return a `string`, `number`, or `bigint`.

To restore the previous defaults you can customize the `ID` scalar types when creating your builder:

```ts
const builder = new SchemaBuilder<{
Scalars: {
ID: {
Input: number | string;
Output: number | string;
};
};
}>({});
```

## `@pothos/plugin-relay`

### Renamed options

The base relay plugin options have moved from `relayOptions` to `relay` to be more consistent with
options for other plugins.

```diff
const builder = new SchemaBuilder<{}>({
- relayOptions: {...}
+ relay: {...}
})
```

### New defaults

A number of the default values for relay options have changed:

- `clientMutationId`: Now defaults to `"omit"` and was previously `"required"`
- `clientMutationId` was only required in early versions of the relay client, and is no-longer
recommended.
- `cursorType`: Now defaults to `"String"` and was previously `"ID"`
- The previous defaults were inconsistent about the type of a cursor. Cursors generally should not
be treated as IDs as they are meant to indicate a position in a list, and may contain
information specific to other filters or arguments applied to the conenction.
- `brandLoadedObjects`: Now defaults to `true` and was previously `false`
- This change will imrpove developer experience for most node implementations, as it removes the
need for `isTypeOf` to be defined for most nodes.
- TODO: write docs for `brandLoadedObjects`
- `edgesFieldOptions.nullable`: Not defaults to `{ list: true, items: true }` and was previously
`{ list: false, items: true }`
- This new default is intended to align with the relay connection spec, which does not expect
connections to be NonNullable by default
- TODO: validate this assumption, I think following default field nullability of the builder may
make more sense, although edges in the list should likely remain nullable. Further investigation
required.

To restore the previous defaults you can pass the old values when setting up the builder:

```ts
const builder = new SchemaBuilder<{
// To change edgesFieldOptions.nullable you must also update the type here
DefaultEdgesNullability: { list: false; items: true };
}>({
relay: {
clientMutationId: 'required',
brandLoadedObjects: false,
edgesFieldOptions: {
nullable: { list: false, items: true },
},
cursorType: 'ID',
// the cursor fields on edges and pageInfo previously defaulted to `String`
// but will be overwrittedn by `cursorType` so you also need to explicity set them
edgeCursorType: 'String',
pageInfoCursorType: 'String',
},
});
```

## `@pothos/plugin-directives`

`useGraphQLToolsUnorderedDirectives` has been nested inside a `directives` options object:

```diff
const builder = new SchemaBuilder<{}>({
- useGraphQLToolsUnorderedDirectives: true
+ directives: {
+ useGraphQLToolsUnorderedDirectives: true
+ }
})
```

## `@pothos/plugin-errors`

### Renamed options

The base error plugin options have moved from `errorOptions` to `errors` to be more consistent with
options for other plugins.

```diff
const builder = new SchemaBuilder<{}>({
- errorOptions: {...}
+ errors: {...}
})
```

## `@pothos/plugin-scope-auth`

### Renamed options

The base scope-auth plugin options have moved from `scopeAuthOptions` to `scopeAuth` to be more
consistent with options for other plugins. The `authScopes` option has been moved to
`scopeAuth.authScopes` to keep all options for the plugin in one options object.

```diff
const builder = new SchemaBuilder<{}>({
- scopeAuthOptions: {...}
- authScopes: (ctx) => ({...})
+ scopeAuth: {
+ ...otherOptions,
+ authScopes: (ctx) => ({...})
+ }
})
```

## `@pothos/plugin-validation`

### Renamed options

The base validation plugin options have moved from `validationOptions` to `validation` to be more
consistent with options for other plugins.

```diff
const builder = new SchemaBuilder<{}>({
- validationOptions: {...}
+ validation: {...}
})
```
10 changes: 5 additions & 5 deletions website/pages/docs/migrations/giraphql-pothos.mdx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
title: 'Giraphql to Pothos migration guide'
bane: 'Giraphql to Pothos'
name: 'Giraphql to Pothos'
menu: Migrations
description: Migration guide for upgrading from GiraphQL 2.* to Pothos 3.0
---

import { DocsPage } from '../../../components/Docs/Page'
import { buildNav } from '../../../util/build-nav'
import { DocsPage } from '../../../components/Docs/Page';
import { buildNav } from '../../../util/build-nav';

export default DocsPage
export default DocsPage;

export const getStaticProps = () => ({ props: { nav: buildNav() }})
export const getStaticProps = () => ({ props: { nav: buildNav() } });

# Migrating from GiraphQL to Pothos

Expand Down
2 changes: 0 additions & 2 deletions website/pages/docs/plugins/dataloader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,6 @@ const UserNode = builder.loadableNode('UserNode', {
id: {
resolve: (user) => user.id,
},
// For loadable nodes, we need to include an isTypeOf check if the first arg is a string
isTypeOf: (obj) => obj instanceof User,
load: (ids: string[], context: ContextType) => context.loadUsersById(ids),
fields: (t) => ({}),
});
Expand Down

0 comments on commit 5b2726e

Please sign in to comment.