From 3aba127a9aee60d4a6f667a2873279dff9224544 Mon Sep 17 00:00:00 2001 From: Flavian DESVERNE Date: Mon, 14 Dec 2020 18:05:42 +0100 Subject: [PATCH 1/2] feat: remove backward compatible code and warnings BREAKING CHANGES: - Legacy resolveType is no longer part of the API - Legacy scalar shorthand is not longer possible - declarativeWrappingPlugin is no longer built-in - ScalarInputFieldConfig type is removed --- src/builder.ts | 20 +++-------------- src/definitions/definitionBlocks.ts | 33 ++++++++++------------------- src/definitions/extendType.ts | 2 +- src/definitions/interfaceType.ts | 17 +-------------- src/definitions/mutationField.ts | 4 ++-- src/definitions/objectType.ts | 8 +++---- src/definitions/unionType.ts | 11 +--------- src/messages.ts | 11 +--------- src/plugin.ts | 13 ++++++------ 9 files changed, 30 insertions(+), 89 deletions(-) diff --git a/src/builder.ts b/src/builder.ts index 53664212..42492ee1 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -121,7 +121,6 @@ import { NexusPlugin, PluginConfig, } from './plugin' -import { declarativeWrappingPlugin } from './plugins' import { fieldAuthorizePlugin } from './plugins/fieldAuthorizePlugin' import { SourceTypesConfigOptions } from './typegenAutoConfig' import { TypegenFormatFn } from './typegenFormatPrettier' @@ -412,11 +411,6 @@ export class SchemaBuilder { /** This array of plugin is used to keep retro-compatibility w/ older versions of nexus */ this.plugins = this.config.plugins.length > 0 ? this.config.plugins : [fieldAuthorizePlugin()] - // TODO(tim): In 1.0 change to declarativeWrappingPlugin({ disable: true }) - if (!this.plugins.find((f) => f.config.name === 'declarativeWrapping')) { - this.plugins.push(declarativeWrappingPlugin({ shouldWarn: true })) - } - this.builderLens = Object.freeze({ hasType: this.hasType, addType: this.addType, @@ -650,11 +644,9 @@ export class SchemaBuilder { // TODO(tim): remove anys/warning at 1.0 const installResult = pluginConfig.onInstall(this.builderLens) as any if (Array.isArray(installResult?.types)) { - console.warn( - `Since v0.19.0 Nexus no longer supports a return value from onInstall, you should instead use the hasType/addType api (seen in plugin ${pluginConfig.name}). ` + - `In the next major version of Nexus this will be a runtime error.` + throw new Error( + `Nexus no longer supports a return value from onInstall, you should instead use the hasType/addType api (seen in plugin ${pluginConfig.name}). ` ) - installResult.types.forEach((t: any) => this.addType(t)) } } if (pluginConfig.onCreateFieldResolver) { @@ -740,7 +732,6 @@ export class SchemaBuilder { addField: () => {}, addDynamicOutputMembers: (block, wrapping) => this.addDynamicOutputMembers(block, 'walk', wrapping), warn: () => {}, - setLegacyResolveType() {}, }) obj.definition(definitionBlock) alreadyChecked[obj.name] = true @@ -907,7 +898,6 @@ export class SchemaBuilder { addInterfaces: (interfaceDefs) => interfaces.push(...interfaceDefs), addModification: (modification) => (modifications[modification.field] = modification), addDynamicOutputMembers: (block, wrapping) => this.addDynamicOutputMembers(block, 'build', wrapping), - setLegacyResolveType: (fn) => (resolveType = fn), warn: consoleWarn, }) config.definition(definitionBlock) @@ -1022,7 +1012,6 @@ export class SchemaBuilder { new UnionDefinitionBlock({ typeName: config.name, addUnionMembers: (unionMembers) => (members = unionMembers), - setLegacyResolveType: (fn) => (resolveType = fn), }) ) @@ -1510,9 +1499,7 @@ export class SchemaBuilder { /* istanbul ignore if */ if (typeof opts === 'function') { - console.warn(messages.removedFunctionShorthand(block.typeName, fieldName)) - // @ts-ignore - fieldConfig.resolve = opts + throw new Error(messages.removedFunctionShorthand(block.typeName, fieldName)) } else { fieldConfig = { ...fieldConfig, ...opts } } @@ -1555,7 +1542,6 @@ export class SchemaBuilder { addField: (f) => this.maybeTraverseOutputFieldType(f), addDynamicOutputMembers: (block, wrapping) => this.addDynamicOutputMembers(block, 'walk', wrapping), warn: () => {}, - setLegacyResolveType: () => {}, }) obj.definition(definitionBlock) return obj diff --git a/src/definitions/definitionBlocks.ts b/src/definitions/definitionBlocks.ts index 97bda285..f1b3d373 100644 --- a/src/definitions/definitionBlocks.ts +++ b/src/definitions/definitionBlocks.ts @@ -109,16 +109,6 @@ export type CommonInputFieldConfig - -/** - * Deprecated, prefer core.CommonInputFieldConfig - * - * TODO(tim): Remove at 1.0 - */ -export interface ScalarInputFieldConfig extends CommonInputFieldConfig { - default?: T -} - export interface OutputScalarConfig extends CommonOutputFieldConfig { /** @@ -131,7 +121,7 @@ export interface OutputScalarConfig { * * In Nexus output types are nullable by default so this is useful to configure a field differently. Note if * you find yourself using this most of the time then what you probably what is to change the - * nonNullDefaults configuration either gloally in your makeSchema config or at the type definition level + * nonNullDefaults configuration either globally in your makeSchema config or at the type definition level * in one of your type configs to be false for outputs. * * Chains are read backwards, right to left, like function composition. In other words the thing on the left @@ -419,7 +409,7 @@ export class OutputDefinitionBlock { * Chain this property to _unwrap_ the right-hand-side type (the field type or a list) of a Non-Null type. * * In Nexus output types are nullable by default so this is only useful when you have changed your - * nonNullDefaults configuration either gloally in your makeSchema config or at the type definition level + * nonNullDefaults configuration either globally in your makeSchema config or at the type definition level * in one of your type configs to be false for outputs. * * Chains are read backwards, right to left, like function composition. In other words the thing on the left @@ -483,7 +473,7 @@ export class OutputDefinitionBlock { * * 1. Has a field whose name matches this one * - * 2. And whose type is compatable + * 2. And whose type is compatible * * 3. And is a scalar * @@ -501,7 +491,7 @@ export class OutputDefinitionBlock { * * String types are [scalars](https://spec.graphql.org/June2018/#sec-Scalars) representing UTF-8 (aka. * unicode) character sequences. It is most often used to represent free-form human-readable text. They are - * represented in JavaScript using the [string priimtive + * represented in JavaScript using the [string primitive * type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). * * This is a shorthand, equivalent to: @@ -525,7 +515,7 @@ export class OutputDefinitionBlock { * * 1. Has a field whose name matches this one * - * 2. And whose type is compatable + * 2. And whose type is compatible * * 3. And is a scalar * @@ -544,7 +534,7 @@ export class OutputDefinitionBlock { * ID types are [scalars](https://spec.graphql.org/June2018/#sec-Scalars) representing unique identifiers * often used to refetch an object or as the key for a cache. It is serialized in the same way as the * [String](https://spec.graphql.org/June2018/#sec-String) type but unlike String not intended to be - * human-readable. They are represented in JavaScript using the [string priimtive + * human-readable. They are represented in JavaScript using the [string primitive * type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). * * This is a shorthand, equivalent to: @@ -568,7 +558,7 @@ export class OutputDefinitionBlock { * * 1. Has a field whose name matches this one * - * 2. And whose type is compatable + * 2. And whose type is compatible * * 3. And is a scalar * @@ -609,7 +599,7 @@ export class OutputDefinitionBlock { * * 1. Has a field whose name matches this one * - * 2. And whose type is compatable + * 2. And whose type is compatible * * 3. And is a scalar * @@ -651,7 +641,7 @@ export class OutputDefinitionBlock { * * 1. Has a field whose name matches this one * - * 2. And whose type is compatable + * 2. And whose type is compatible * * 3. And is a scalar * @@ -719,8 +709,7 @@ export class OutputDefinitionBlock { /* istanbul ignore if */ if (typeof opts[0] === 'function') { - fieldConfig.resolve = opts[0] as any - console.warn(messages.removedFunctionShorthand(typeName, fieldName)) + throw new Error(messages.removedFunctionShorthand(typeName, fieldName)) } else { fieldConfig = { ...fieldConfig, ...opts[0] } } diff --git a/src/definitions/extendType.ts b/src/definitions/extendType.ts index 93276c3b..df8b6209 100644 --- a/src/definitions/extendType.ts +++ b/src/definitions/extendType.ts @@ -20,7 +20,7 @@ export interface NexusExtendTypeConfig { * Define the fields you want to extend the type with. This method works almost exactly like the objectType * "definition" method. * - * @param t The type builder. Usually the same as that passed to objectType "definition" method excecpt if + * @param t The type builder. Usually the same as that passed to objectType "definition" method except if * extending the Subscription type in which case you get a subscription type builder (which differs * slightly in that it requires implementation of a "subscribe" method on field configurations). */ diff --git a/src/definitions/interfaceType.ts b/src/definitions/interfaceType.ts index ba46f65d..957344ee 100644 --- a/src/definitions/interfaceType.ts +++ b/src/definitions/interfaceType.ts @@ -1,12 +1,5 @@ import { assertValidName, GraphQLInterfaceTypeConfig } from 'graphql' -import { messages } from '../messages' -import { - AbstractTypeResolver, - FieldResolver, - GetGen, - InterfaceFieldsFor, - ModificationType, -} from '../typegenTypeHelpers' +import { FieldResolver, GetGen, InterfaceFieldsFor, ModificationType } from '../typegenTypeHelpers' import { ArgsRecord } from './args' import { OutputDefinitionBlock, OutputDefinitionBuilder } from './definitionBlocks' import { AbstractTypes, NexusTypes, NonNullConfig, SourceTypingDef, withNexusSymbol } from './_types' @@ -63,8 +56,6 @@ export type NexusInterfaceTypeConfig = { } & AbstractTypes.MaybeTypeDefConfigFieldResolveType export interface InterfaceDefinitionBuilder extends OutputDefinitionBuilder { - // TODO(tim): Remove before 1.0 - setLegacyResolveType(fn: AbstractTypeResolver): void addInterfaces(toAdd: Implemented[]): void addModification(toAdd: FieldModificationDef): void } @@ -84,12 +75,6 @@ export class InterfaceDefinitionBlock extends OutputDef ) { this.typeBuilder.addModification({ ...modifications, field }) } - - /* istanbul ignore next */ - protected resolveType(fn: AbstractTypeResolver) { - console.error(new Error(messages.removedResolveType(this.typeBuilder.typeName))) - this.typeBuilder.setLegacyResolveType(fn) - } } export class NexusInterfaceTypeDef { diff --git a/src/definitions/mutationField.ts b/src/definitions/mutationField.ts index 819ab6b2..c697a115 100644 --- a/src/definitions/mutationField.ts +++ b/src/definitions/mutationField.ts @@ -12,7 +12,7 @@ export type MutationFieldConfig = * Define one or more fields on the Mutation type. * * Use this if you are going to modularize your schema and thus be wanting to contribute fields to Mutation - * type from multiple modules. You do not have to have previously defined a Mutatin type before using this. + * type from multiple modules. You do not have to have previously defined a Mutation type before using this. * If you haven't Nexus will create one automatically for you. * * This is shorthand for: @@ -72,7 +72,7 @@ export function mutationField( * * Use this instead of mutationType if you are going to modularize your schema and thus be wanting to * contribute fields to Mutation type from multiple modules. You do not have to have previously defined a - * Mutatin type before using this. If you haven't Nexus will create one automatically for you. + * Mutation type before using this. If you haven't Nexus will create one automatically for you. * * This is shorthand for: * diff --git a/src/definitions/objectType.ts b/src/definitions/objectType.ts index 9102f624..cca971ef 100644 --- a/src/definitions/objectType.ts +++ b/src/definitions/objectType.ts @@ -36,7 +36,7 @@ export type NexusObjectTypeConfig = { * [_A-Za-z][_0-9A-Za-z]* * * From the spec: Names in GraphQL are case‐sensitive. That is to say name, Name, and NAME all refer to - * dfferent names. Underscores are significant, which means other_name and othername are two differen names. + * dfferent names. Underscores are significant, which means other_name and othername are two different names. * * @example * 'Post' @@ -163,9 +163,9 @@ export type NexusObjectTypeConfig = { * * This method receives a type builder api that you will use to define the fields of your object type * within. You can leverage conditionals, loops, other functions (that take the builder api as an - * argument), pull in variables from higher sopes, and so on, to help define your fields. However avoid two things: + * argument), pull in variables from higher scopes, and so on, to help define your fields. However avoid two things: * - * 1. Doing asyncrous work when defining fields. + * 1. Doing asynchronous work when defining fields. * * 2. Triggering side-effects that you would NOT want run at _build_ time––as this code will run during * build to support [Nexus' reflection system](https://nxs.li/guides/reflection). @@ -212,7 +212,7 @@ withNexusSymbol(NexusObjectTypeDef, NexusTypes.Object) * Define a GraphQL Object Type. * * Object types are typically the most common kind of type present in a GraphQL schema. You give them a name - * and filds that model your domain. Fields are typed and can point to yet another object type you've defined. + * and fields that model your domain. Fields are typed and can point to yet another object type you've defined. * * @example * const Post = objectType({ diff --git a/src/definitions/unionType.ts b/src/definitions/unionType.ts index 332fb6da..f39e5949 100644 --- a/src/definitions/unionType.ts +++ b/src/definitions/unionType.ts @@ -1,14 +1,11 @@ import { assertValidName, GraphQLUnionTypeConfig } from 'graphql' -import { messages } from '../messages' -import { AbstractTypeResolver, GetGen } from '../typegenTypeHelpers' +import { GetGen } from '../typegenTypeHelpers' import { NexusObjectTypeDef } from './objectType' import { AbstractTypes, NexusTypes, SourceTypingDef, withNexusSymbol } from './_types' export interface UnionDefinitionBuilder { typeName: string addUnionMembers(members: UnionMembers): void - // TODO(tim): Remove before 1.0 - setLegacyResolveType(fn: AbstractTypeResolver): void } export type UnionMembers = Array | NexusObjectTypeDef> @@ -22,12 +19,6 @@ export class UnionDefinitionBlock { members(...unionMembers: UnionMembers) { this.typeBuilder.addUnionMembers(unionMembers) } - - /* istanbul ignore next */ - protected resolveType(fn: AbstractTypeResolver) { - console.error(new Error(messages.removedResolveType(this.typeBuilder.typeName))) - this.typeBuilder.setLegacyResolveType(fn) - } } export type NexusUnionTypeConfig = { diff --git a/src/messages.ts b/src/messages.ts index fde5c147..7b2e1bdc 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -1,13 +1,4 @@ export const messages = { - /* istanbul ignore next */ - removedResolveType: (location: string) => `\ -The .resolveType used in the ${location} has been moved to a property on the type definition object, -as part of of a more robust approach to handling abstract types. - -Visit https://nxs.li/guides/abstract-types for an explanation and upgrade info. - -Visit https://github.com/graphql-nexus/schema/issues/188 for the original motivation for the change. -`, /* istanbul ignore next */ removedDeclarativeWrapping: (location: string, used: string[]) => `\ [declarativeWrappingPlugin]: The ${used.join(' / ')} object prop${ @@ -38,5 +29,5 @@ makeSchema({ `, /* istanbul ignore next */ removedFunctionShorthand: (typeName: string, fieldName: string) => - `Since v0.18.0 Nexus no longer supports resolver shorthands like:\n\n t.string("${fieldName}", () => ...).\n\nInstead please write:\n\n t.string("${fieldName}", { resolve: () => ... })\n\nIn the next major version of Nexus this will be a runtime error (seen in type ${typeName}).`, + `Since v0.18.0, Nexus no longer supports resolver shorthands like:\n\n t.string("${fieldName}", () => ...).\n\nInstead please write:\n\n t.string("${fieldName}", { resolve: () => ... })\n\n.`, } diff --git a/src/plugin.ts b/src/plugin.ts index 859ffc3f..5f1f27a1 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -62,10 +62,9 @@ export interface PluginConfig { * `dynamicOutput{Method,Property}` / `dynamicInput{Method,Property}` */ /** - * Existing Description: The plugin callback to execute when onInstall lifecycle event occurs. OnInstall - * event occurs before type walking which means inline types are not visible at this point yet. - * `builderLens.hasType` will only return true for types the user has defined top level in their app, and - * any types added by upstream plugins. + * The onInstall event occurs before type walking which means inline types are not visible at this point + * yet. `builderLens.hasType` will only return true for types the user has defined top level in their app, + * and any types added by upstream plugins. */ onInstall?: (builder: PluginBuilderLens) => void /** @@ -114,7 +113,7 @@ export interface PluginConfig { onCreateFieldSubscribe?: (createSubscribeInfo: CreateFieldResolverInfo) => MiddlewareFn | undefined /** * Executed when a field is going to be printed to the nexus "generated types". Gives an opportunity to - * override the standard behavior for printing our inferrred type info + * override the standard behavior for printing our inferred type info */ // onPrint?: (visitor: Visitor) => void; } @@ -197,8 +196,8 @@ withNexusSymbol(NexusPlugin, NexusTypes.Plugin) * You can specify options which can be defined on the schema, the type or the plugin. The config from each of * these will be passed in during schema construction time, and used to augment the field as necessary. * - * You can either return a function, with the new defintion of a resolver implementation, or you can return an - * "enter" / "leave" pairing which will wrap the pre-execution of the resolver and the "result" of the + * You can either return a function, with the new definition of a resolver implementation, or you can return + * an "enter" / "leave" pairing which will wrap the pre-execution of the resolver and the "result" of the * resolver, respectively. */ export function plugin(config: PluginConfig) { From d9b350ddbf02cb4b420593b7755e8db13e11f41b Mon Sep 17 00:00:00 2001 From: Flavian DESVERNE Date: Mon, 14 Dec 2020 18:10:06 +0100 Subject: [PATCH 2/2] fix: keep declarativeWrappingPlugin but disable it --- src/builder.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/builder.ts b/src/builder.ts index 2f7c4d97..efdf1ad7 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -121,6 +121,7 @@ import { NexusPlugin, PluginConfig, } from './plugin' +import { declarativeWrappingPlugin } from './plugins' import { fieldAuthorizePlugin } from './plugins/fieldAuthorizePlugin' import { SourceTypesConfigOptions } from './typegenAutoConfig' import { TypegenFormatFn } from './typegenFormatPrettier' @@ -411,6 +412,10 @@ export class SchemaBuilder { /** This array of plugin is used to keep retro-compatibility w/ older versions of nexus */ this.plugins = this.config.plugins.length > 0 ? this.config.plugins : [fieldAuthorizePlugin()] + if (!this.plugins.find((f) => f.config.name === 'declarativeWrapping')) { + this.plugins.push(declarativeWrappingPlugin({ disable: true })) + } + this.builderLens = Object.freeze({ hasType: this.hasType, addType: this.addType,