Compare commits
9 Commits
1.4.0-next
...
main
Author | SHA1 | Date |
---|---|---|
|
9e5c27c509 | |
|
601c2f03f4 | |
|
4e085dc7b2 | |
|
1e6b9212d3 | |
|
4d8e37177b | |
|
eec4b91091 | |
|
8e65081539 | |
|
7ee48c4f2c | |
|
e9dc7e0c4a |
|
@ -38,7 +38,7 @@ jobs:
|
|||
run: yarn -s test:ci
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '10.x'
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '14.x'
|
||||
with:
|
||||
directory: ./coverage
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
- name: Test
|
||||
run: yarn -s test:ci
|
||||
- name: Upload coverage to Codecov
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '10.x'
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '14.x'
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
directory: ./coverage
|
||||
|
|
|
@ -5,3 +5,4 @@ examples/*/dist
|
|||
website/static/playground-dist
|
||||
yarn-error.log
|
||||
coverage/*
|
||||
tests/esm/out/
|
|
@ -1,4 +1,4 @@
|
|||
(c) 2018-2019 Tim Griesser
|
||||
(c) 2018-2022 Tim Griesser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
|
|
@ -74,4 +74,4 @@ You can find the docs for Nexus [here](http://nexusjs.org/).
|
|||
|
||||
## Migrate from SDL
|
||||
|
||||
If you've been following an [SDL-first](https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3/) approach to build your GraphQL server and want to see what your code looks like when written with GraphQL Nexus, you can use the [**SDL converter**](https://nexus.js.org/converter).
|
||||
If you've been following an [SDL-first](https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3/) approach to build your GraphQL server and want to see what your code looks like when written with GraphQL Nexus, you can use the [**SDL converter**](https://nexusjs.org/converter).
|
||||
|
|
|
@ -28,18 +28,3 @@ Each public API is documented below, feel free to open a PR with more examples/c
|
|||
- [extendType / extendInputType](/api/extend-type)
|
||||
- [mutationField](/api/mutation-field)
|
||||
- [queryField](/api/query-field)
|
||||
|
||||
## Resolving: Inline Function
|
||||
|
||||
One common idiom in GraphQL is exposing fields that mask or rename the property name on the backing object. GraphQL Nexus makes this simple by allowing a function as the second parameter to any built-in scalar resolver function.
|
||||
|
||||
```ts
|
||||
const User = objectType({
|
||||
name: 'User',
|
||||
definition(t) {
|
||||
t.id('id', o => o.user_id)
|
||||
t.string('name', o => o.user_name)
|
||||
t.string('description', o => o.user_description)
|
||||
},
|
||||
})
|
||||
```
|
||||
|
|
|
@ -6,7 +6,7 @@ title: Overview
|
|||
|
||||
This plugin integrates [Prisma](https://www.prisma.io/) into [Nexus](https://nexusjs.org/). It gives you an API to project fields from models defined in your Prisma schema into your GraphQL API. It also gives you an API to build GraphQL root fields that allow your API clients to query and mutate data.
|
||||
|
||||
> **Note**: The Prisma team is currently [rewriting](https://github.com/graphql-nexus/nexus-plugin-prisma/issues/1039) the plugin to make it maintainable longterm.
|
||||
**Note**: You may also use [`nexus-prisma`](https://github.com/graphql-nexus/nexus-prisma), a newer API for integrating Nexus and Prisma.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
@ -214,8 +214,7 @@ const Footer = ({ footerProps }: FooterViewProps) => {
|
|||
}
|
||||
</div>
|
||||
|
||||
<p className="social-text">Prisma © 2018-2020</p>
|
||||
<p>Made with ❤️ in Berlin</p>
|
||||
<p className="social-text">Tim Griesser © 2018-2022</p>
|
||||
</div>
|
||||
</SocialWrapper>
|
||||
</div>
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
"@types/prettier": "^1.18.3",
|
||||
"@typescript-eslint/eslint-plugin": "2.7.0",
|
||||
"dripip": "^0.10.0",
|
||||
"esbuild": "^0.14.48",
|
||||
"eslint": "^6.6.0",
|
||||
"get-port": "^5.1.1",
|
||||
"graphql": "^16.3.0",
|
||||
|
|
|
@ -504,9 +504,6 @@ export class SchemaBuilder {
|
|||
/** All Schema Directives */
|
||||
// private schemaDirectives: GraphQLDirective[] = []
|
||||
|
||||
/** Whether we have used any custom directives within the schema construction */
|
||||
private hasSDLDirectives: boolean = false
|
||||
|
||||
/** All types that need to be traversed for children types */
|
||||
private typesToWalk: TypeToWalk[] = []
|
||||
|
||||
|
@ -999,14 +996,14 @@ export class SchemaBuilder {
|
|||
this.beforeBuildTypes()
|
||||
this.checkForInterfaceCircularDependencies()
|
||||
this.buildNexusTypes()
|
||||
|
||||
return {
|
||||
finalConfig: this.config,
|
||||
typeMap: this.finalTypeMap,
|
||||
schemaExtension: this.schemaExtension!,
|
||||
schemaExtension: this.schemaExtension,
|
||||
missingTypes: this.missingTypes,
|
||||
onAfterBuildFns: this.onAfterBuildFns,
|
||||
customDirectives: this.directivesMap,
|
||||
hasSDLDirectives: this.hasSDLDirectives,
|
||||
schemaDirectives: this.maybeAddDirectiveUses('SCHEMA', this.config.schemaDirectives),
|
||||
}
|
||||
}
|
||||
|
@ -1200,11 +1197,7 @@ export class SchemaBuilder {
|
|||
for (const directive of directives) {
|
||||
this.addDirective(directive)
|
||||
}
|
||||
const result = maybeAddDirectiveUses(kind, directives, this.directivesMap)
|
||||
if (result) {
|
||||
this.hasSDLDirectives = true
|
||||
}
|
||||
return result
|
||||
return maybeAddDirectiveUses(kind, directives, this.directivesMap)
|
||||
}
|
||||
|
||||
private buildEnumType(config: NexusEnumTypeConfig<any>) {
|
||||
|
@ -1901,7 +1894,6 @@ export interface BuildTypes<TypeMapDefs extends Record<string, GraphQLNamedType>
|
|||
schemaExtension: NexusSchemaExtension
|
||||
onAfterBuildFns: SchemaBuilder['onAfterBuildFns']
|
||||
customDirectives: Record<string, GraphQLDirective>
|
||||
hasSDLDirectives: boolean
|
||||
schemaDirectives?: Partial<{ astNode: ASTKindToNode['SchemaDefinition'] }>
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,36 @@ export type CommonOutputFieldConfig<TypeName extends string, FieldName extends s
|
|||
* directives: [addDirective('ExampleDirective', { arg: true })]
|
||||
*/
|
||||
directives?: Directives
|
||||
/**
|
||||
* Defines a typing for the field, overriding the default behavior to default to the scalar,
|
||||
* and omit the field if a resolver exists. Most useful in situations where we have a resolver
|
||||
* but we still want the field defined on the output type.
|
||||
*
|
||||
* @example
|
||||
* sourceType: 'string | number'
|
||||
*/
|
||||
sourceType?: string | FieldSourceType | NamedFieldSourceType[]
|
||||
} & NexusGenPluginFieldConfig<TypeName, FieldName>
|
||||
|
||||
export interface FieldSourceType {
|
||||
/**
|
||||
* String representing the TypeScript type output as the value
|
||||
*/
|
||||
type: string
|
||||
/**
|
||||
* If true, marks the field as optional `?:`
|
||||
* @default false
|
||||
*/
|
||||
optional?: boolean
|
||||
}
|
||||
|
||||
export interface NamedFieldSourceType extends FieldSourceType {
|
||||
/**
|
||||
* Property name in the output TypeScript field
|
||||
*/
|
||||
name: string
|
||||
}
|
||||
|
||||
export type CommonInputFieldConfig<TypeName extends string, FieldName extends string> = CommonFieldConfig & {
|
||||
/** The default value for the field, if any */
|
||||
default?: GetGen3<'inputTypes', TypeName, FieldName>
|
||||
|
|
|
@ -27,7 +27,7 @@ export const RequestDirectiveLocation = [
|
|||
'FRAGMENT_SPREAD',
|
||||
'INLINE_FRAGMENT',
|
||||
'VARIABLE_DEFINITION',
|
||||
]
|
||||
] as const
|
||||
|
||||
export const SchemaDirectiveLocation = [
|
||||
/** Type System Definitions */
|
||||
|
|
|
@ -5,13 +5,17 @@ import type { NexusOutputFieldConfig } from './definitions/definitionBlocks'
|
|||
import type { NexusInputObjectTypeConfig } from './definitions/inputObjectType'
|
||||
import type { NexusInterfaceTypeConfig } from './definitions/interfaceType'
|
||||
import type { NexusObjectTypeConfig } from './definitions/objectType'
|
||||
import type { Directives } from './core'
|
||||
import type { Directives, FieldSourceType, NamedFieldSourceType } from './core'
|
||||
|
||||
/** @internal */
|
||||
export function hasNexusExtension(val: any): val is any {
|
||||
return Boolean(val)
|
||||
}
|
||||
|
||||
export function isNexusFieldExtension(val: any): val is NexusFieldExtension {
|
||||
return Boolean(val?._type === 'NexusFieldExtension')
|
||||
}
|
||||
|
||||
export type NexusGraphQLNamedType = GraphQLNamedType & {
|
||||
extensions?: {
|
||||
nexus?: {
|
||||
|
@ -24,13 +28,17 @@ export type NexusTypeExtensions = NexusObjectTypeExtension | NexusInterfaceTypeE
|
|||
|
||||
/** Container object living on `fieldDefinition.extensions.nexus` */
|
||||
export class NexusFieldExtension<TypeName extends string = any, FieldName extends string = any> {
|
||||
readonly _type = 'NexusFieldExtension' as const
|
||||
readonly config: Omit<NexusOutputFieldConfig<TypeName, FieldName>, 'resolve'>
|
||||
/** Whether the user has provided a custom "resolve" function, or whether we're using GraphQL's defaultResolver */
|
||||
readonly hasDefinedResolver: boolean
|
||||
readonly sourceType: string | FieldSourceType | NamedFieldSourceType[] | undefined
|
||||
|
||||
constructor(config: NexusOutputFieldConfig<TypeName, FieldName>) {
|
||||
const { resolve, ...rest } = config
|
||||
this.config = rest
|
||||
this.hasDefinedResolver = Boolean(resolve && resolve !== defaultFieldResolver)
|
||||
this.sourceType = rest.sourceType
|
||||
}
|
||||
/** Called when there are modifications on the interface fields */
|
||||
modify(modifications: Partial<NexusOutputFieldConfig<any, any>>) {
|
||||
|
@ -40,6 +48,7 @@ export class NexusFieldExtension<TypeName extends string = any, FieldName extend
|
|||
|
||||
/** Container object living on `inputObjectType.extensions.nexus` */
|
||||
export class NexusInputObjectTypeExtension<TypeName extends string = any> {
|
||||
readonly _type = 'NexusInputObjectTypeExtension' as const
|
||||
readonly config: Omit<NexusInputObjectTypeConfig<TypeName>, 'definition'>
|
||||
constructor(config: NexusInputObjectTypeConfig<TypeName>) {
|
||||
const { definition, ...rest } = config
|
||||
|
@ -49,6 +58,7 @@ export class NexusInputObjectTypeExtension<TypeName extends string = any> {
|
|||
|
||||
/** Container object living on `objectType.extensions.nexus` */
|
||||
export class NexusObjectTypeExtension<TypeName extends string = any> {
|
||||
readonly _type = 'NexusObjectTypeExtension' as const
|
||||
readonly config: Omit<NexusObjectTypeConfig<TypeName>, 'definition' | 'isTypeOf'>
|
||||
constructor(config: NexusObjectTypeConfig<TypeName>) {
|
||||
const { definition, ...rest } = config
|
||||
|
@ -58,6 +68,7 @@ export class NexusObjectTypeExtension<TypeName extends string = any> {
|
|||
|
||||
/** Container object living on `interfaceType.extensions.nexus` */
|
||||
export class NexusInterfaceTypeExtension<TypeName extends string = any> {
|
||||
readonly _type = 'NexusInterfaceTypeExtension' as const
|
||||
readonly config: Omit<NexusInterfaceTypeConfig<TypeName>, 'definition' | 'resolveType'>
|
||||
constructor(config: NexusInterfaceTypeConfig<TypeName>) {
|
||||
const { definition, ...rest } = config
|
||||
|
|
|
@ -19,14 +19,14 @@ import { assertNoMissingTypes, objValues, runAbstractTypeRuntimeChecks } from '.
|
|||
* Requires at least one type be named "Query", which will be used as the root query type.
|
||||
*/
|
||||
export function makeSchema(config: SchemaConfig): NexusGraphQLSchema {
|
||||
const { schema, missingTypes, finalConfig, hasSDLDirectives } = makeSchemaInternal(config)
|
||||
const { schema, missingTypes, finalConfig } = makeSchemaInternal(config)
|
||||
const typegenConfig = resolveTypegenConfig(finalConfig)
|
||||
const sdl = typegenConfig.outputs.schema
|
||||
const typegen = typegenConfig.outputs.typegen
|
||||
if (sdl || typegen) {
|
||||
// Generating in the next tick allows us to use the schema
|
||||
// in the optional thunk for the typegen config
|
||||
const typegenPromise = new TypegenMetadata(typegenConfig).generateArtifacts(schema, hasSDLDirectives)
|
||||
const typegenPromise = new TypegenMetadata(typegenConfig).generateArtifacts(schema)
|
||||
if (config.shouldExitAfterGenerateArtifacts) {
|
||||
let typegenPath = '(not enabled)'
|
||||
if (typegenConfig.outputs.typegen) {
|
||||
|
@ -59,9 +59,9 @@ export function makeSchema(config: SchemaConfig): NexusGraphQLSchema {
|
|||
|
||||
/** Like makeSchema except that typegen is always run and waited upon. */
|
||||
export async function generateSchema(config: SchemaConfig): Promise<NexusGraphQLSchema> {
|
||||
const { schema, missingTypes, finalConfig, hasSDLDirectives } = makeSchemaInternal(config)
|
||||
const { schema, missingTypes, finalConfig } = makeSchemaInternal(config)
|
||||
const typegenConfig = resolveTypegenConfig(finalConfig)
|
||||
await new TypegenMetadata(typegenConfig).generateArtifacts(schema, hasSDLDirectives)
|
||||
await new TypegenMetadata(typegenConfig).generateArtifacts(schema)
|
||||
assertNoMissingTypes(schema, missingTypes)
|
||||
runAbstractTypeRuntimeChecks(schema, finalConfig.features)
|
||||
return schema
|
||||
|
@ -80,11 +80,11 @@ generateSchema.withArtifacts = async (
|
|||
tsTypes: string
|
||||
globalTypes: string | null
|
||||
}> => {
|
||||
const { schema, missingTypes, finalConfig, hasSDLDirectives } = makeSchemaInternal(config)
|
||||
const { schema, missingTypes, finalConfig } = makeSchemaInternal(config)
|
||||
const typegenConfig = resolveTypegenConfig(finalConfig)
|
||||
const { schemaTypes, tsTypes, globalTypes } = await new TypegenMetadata(
|
||||
typegenConfig
|
||||
).generateArtifactContents(schema, typegen, hasSDLDirectives)
|
||||
).generateArtifactContents(schema, typegen)
|
||||
assertNoMissingTypes(schema, missingTypes)
|
||||
runAbstractTypeRuntimeChecks(schema, finalConfig.features)
|
||||
return { schema, schemaTypes, tsTypes, globalTypes }
|
||||
|
@ -125,7 +125,6 @@ export function makeSchemaInternal(config: SchemaConfig) {
|
|||
onAfterBuildFns,
|
||||
customDirectives,
|
||||
schemaDirectives,
|
||||
hasSDLDirectives,
|
||||
} = builder.getFinalTypeMap()
|
||||
|
||||
const schema = new GraphQLSchema({
|
||||
|
@ -144,7 +143,7 @@ export function makeSchemaInternal(config: SchemaConfig) {
|
|||
|
||||
onAfterBuildFns.forEach((fn) => fn(schema))
|
||||
|
||||
return { schema, missingTypes, finalConfig, hasSDLDirectives }
|
||||
return { schema, missingTypes, finalConfig }
|
||||
}
|
||||
|
||||
type OmittedVals = Partial<{ [K in keyof MakeSchemaOptions]: never }>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
export function nodeImports() {
|
||||
const fs = require('fs') as typeof import('fs')
|
||||
const path = require('path') as typeof import('path')
|
||||
return {
|
||||
fs,
|
||||
path,
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { GraphQLNamedType, GraphQLSchema, isOutputType } from 'graphql'
|
||||
import * as path from 'path'
|
||||
import type { TypegenInfo } from './builder'
|
||||
import type { TypingImport } from './definitions/_types'
|
||||
import { TYPEGEN_HEADER } from './lang'
|
||||
import { nodeImports } from './node'
|
||||
import { getOwnPackage, log, objValues, relativePathTo, typeScriptFileExtension } from './utils'
|
||||
|
||||
/** Any common types / constants that would otherwise be circular-imported */
|
||||
|
@ -129,16 +129,12 @@ export function typegenAutoConfig(options: SourceTypesConfigOptions, contextType
|
|||
}
|
||||
})
|
||||
|
||||
const path = nodeImports().path
|
||||
const typeSources = await Promise.all(
|
||||
options.modules.map(async (source) => {
|
||||
// Keeping all of this in here so if we don't have any sources
|
||||
// e.g. in the Playground, it doesn't break things.
|
||||
|
||||
// Yeah, this doesn't exist in Node 6, but since this is a new
|
||||
// lib and Node 6 is close to EOL so if you really need it, open a PR :)
|
||||
const fs = require('fs') as typeof import('fs')
|
||||
const util = require('util') as typeof import('util')
|
||||
const readFile = util.promisify(fs.readFile)
|
||||
const { module: pathOrModule, glob = true, onlyTypes, alias, typeMatch } = source
|
||||
if (path.isAbsolute(pathOrModule) && path.extname(pathOrModule) !== '.ts') {
|
||||
return console.warn(
|
||||
|
@ -154,7 +150,7 @@ export function typegenAutoConfig(options: SourceTypesConfigOptions, contextType
|
|||
if (path.extname(resolvedPath) !== '.ts') {
|
||||
resolvedPath = findTypingForFile(resolvedPath, pathOrModule)
|
||||
}
|
||||
fileContents = await readFile(resolvedPath, 'utf-8')
|
||||
fileContents = String(await nodeImports().fs.promises.readFile(resolvedPath, 'utf-8'))
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message.indexOf('Cannot find module') !== -1) {
|
||||
console.error(`GraphQL Nexus: Unable to find file or module ${pathOrModule}, skipping`)
|
||||
|
@ -277,7 +273,7 @@ export function typegenAutoConfig(options: SourceTypesConfigOptions, contextType
|
|||
function findTypingForFile(absolutePath: string, pathOrModule: string) {
|
||||
// First try to find the "d.ts" adjacent to the file
|
||||
try {
|
||||
const typeDefPath = absolutePath.replace(path.extname(absolutePath), '.d.ts')
|
||||
const typeDefPath = absolutePath.replace(nodeImports().path.extname(absolutePath), '.d.ts')
|
||||
require.resolve(typeDefPath)
|
||||
return typeDefPath
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as path from 'path'
|
||||
import type * as Prettier from 'prettier'
|
||||
import { nodeImports } from './node'
|
||||
|
||||
export type TypegenFormatFn = (content: string, type: 'types' | 'schema') => string | Promise<string>
|
||||
|
||||
|
@ -22,6 +22,8 @@ export function typegenFormatPrettier(prettierConfig: string | object): TypegenF
|
|||
|
||||
let prettierConfigResolved: Prettier.Options
|
||||
|
||||
const path = nodeImports().path
|
||||
|
||||
if (typeof prettierConfig === 'string') {
|
||||
/* istanbul ignore if */
|
||||
if (!path.isAbsolute(prettierConfig)) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { GraphQLSchema, lexicographicSortSchema, printSchema } from 'graphql'
|
||||
import * as path from 'path'
|
||||
import { GraphQLSchema, lexicographicSortSchema } from 'graphql'
|
||||
import type { BuilderConfigInput, TypegenInfo } from './builder'
|
||||
import type { ConfiguredTypegen } from './core'
|
||||
import type { NexusGraphQLSchema } from './definitions/_types'
|
||||
import { SDL_HEADER, TYPEGEN_HEADER } from './lang'
|
||||
import { nodeImports } from './node'
|
||||
import { printSchemaWithDirectives } from './printSchemaWithDirectives'
|
||||
import { typegenAutoConfig } from './typegenAutoConfig'
|
||||
import { typegenFormatPrettier } from './typegenFormatPrettier'
|
||||
|
@ -26,15 +26,11 @@ export class TypegenMetadata {
|
|||
constructor(protected config: TypegenMetadataConfig) {}
|
||||
|
||||
/** Generates the artifacts of the build based on what we know about the schema and how it was defined. */
|
||||
async generateArtifacts(schema: NexusGraphQLSchema, hasSDLDirectives: boolean) {
|
||||
async generateArtifacts(schema: NexusGraphQLSchema) {
|
||||
const sortedSchema = this.sortSchema(schema)
|
||||
const { typegen } = this.config.outputs
|
||||
if (this.config.outputs.schema || typegen) {
|
||||
const { schemaTypes, tsTypes, globalTypes } = await this.generateArtifactContents(
|
||||
sortedSchema,
|
||||
typegen,
|
||||
hasSDLDirectives
|
||||
)
|
||||
const { schemaTypes, tsTypes, globalTypes } = await this.generateArtifactContents(sortedSchema, typegen)
|
||||
if (this.config.outputs.schema) {
|
||||
await this.writeFile('schema', schemaTypes, this.config.outputs.schema)
|
||||
}
|
||||
|
@ -51,13 +47,9 @@ export class TypegenMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
async generateArtifactContents(
|
||||
schema: NexusGraphQLSchema,
|
||||
typegen: string | null | ConfiguredTypegen,
|
||||
hasSDLDirectives: boolean
|
||||
) {
|
||||
async generateArtifactContents(schema: NexusGraphQLSchema, typegen: string | null | ConfiguredTypegen) {
|
||||
const result = {
|
||||
schemaTypes: this.generateSchemaFile(schema, hasSDLDirectives),
|
||||
schemaTypes: this.generateSchemaFile(schema),
|
||||
tsTypes: '',
|
||||
globalTypes: null as null | string,
|
||||
}
|
||||
|
@ -83,30 +75,26 @@ export class TypegenMetadata {
|
|||
}
|
||||
|
||||
async writeFile(type: 'schema' | 'types', output: string, filePath: string) {
|
||||
if (typeof filePath !== 'string' || !path.isAbsolute(filePath)) {
|
||||
if (typeof filePath !== 'string' || !nodeImports().path.isAbsolute(filePath)) {
|
||||
return Promise.reject(
|
||||
new Error(`Expected an absolute path to output the Nexus ${type}, saw ${filePath}`)
|
||||
)
|
||||
}
|
||||
const fs = require('fs') as typeof import('fs')
|
||||
const util = require('util') as typeof import('util')
|
||||
const [readFile, writeFile, removeFile, mkdir] = [
|
||||
util.promisify(fs.readFile),
|
||||
util.promisify(fs.writeFile),
|
||||
util.promisify(fs.unlink),
|
||||
util.promisify(fs.mkdir),
|
||||
]
|
||||
const fs = nodeImports().fs
|
||||
const formattedOutput =
|
||||
typeof this.config.formatTypegen === 'function' ? await this.config.formatTypegen(output, type) : output
|
||||
const content = this.config.prettierConfig
|
||||
? await typegenFormatPrettier(this.config.prettierConfig)(formattedOutput, type)
|
||||
: formattedOutput
|
||||
|
||||
const [toSave, existing] = await Promise.all([content, readFile(filePath, 'utf8').catch(() => '')])
|
||||
const [toSave, existing] = await Promise.all([
|
||||
content,
|
||||
fs.promises.readFile(filePath, 'utf8').catch(() => ''),
|
||||
])
|
||||
if (toSave !== existing) {
|
||||
const dirPath = path.dirname(filePath)
|
||||
const dirPath = nodeImports().path.dirname(filePath)
|
||||
try {
|
||||
await mkdir(dirPath, { recursive: true })
|
||||
await fs.promises.mkdir(dirPath, { recursive: true })
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') {
|
||||
throw e
|
||||
|
@ -116,23 +104,22 @@ export class TypegenMetadata {
|
|||
// apparently. See issue motivating this logic here:
|
||||
// https://github.com/graphql-nexus/schema/issues/247.
|
||||
try {
|
||||
await removeFile(filePath)
|
||||
await fs.promises.unlink(filePath)
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
if (e.code !== 'ENOENT' && e.code !== 'ENOTDIR') {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
return writeFile(filePath, toSave)
|
||||
return fs.promises.writeFile(filePath, toSave)
|
||||
}
|
||||
}
|
||||
|
||||
/** Generates the schema, adding any directives as necessary */
|
||||
generateSchemaFile(schema: GraphQLSchema, hasSDLDirectives: boolean): string {
|
||||
const printer = hasSDLDirectives ? printSchemaWithDirectives : printSchema
|
||||
generateSchemaFile(schema: GraphQLSchema): string {
|
||||
let printedSchema = this.config.customPrintSchemaFn
|
||||
? this.config.customPrintSchemaFn(schema)
|
||||
: printer(schema)
|
||||
: printSchemaWithDirectives(schema)
|
||||
return [SDL_HEADER, printedSchema].join('\n\n')
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import { isNexusPrintedGenTyping, isNexusPrintedGenTypingImport } from './defini
|
|||
import type { NexusGraphQLSchema } from './definitions/_types'
|
||||
import { TYPEGEN_HEADER } from './lang'
|
||||
import type { StringLike } from './plugin'
|
||||
import { hasNexusExtension } from './extensions'
|
||||
import { hasNexusExtension, isNexusFieldExtension } from './extensions'
|
||||
import {
|
||||
eachObj,
|
||||
getOwnPackage,
|
||||
|
@ -641,8 +641,17 @@ export class TypegenPrinter {
|
|||
} else {
|
||||
eachObj(type.getFields(), (field) => {
|
||||
const obj = (rootTypeMap[type.name] = rootTypeMap[type.name] || {})
|
||||
if (!this.hasResolver(field, type)) {
|
||||
if (typeof obj !== 'string') {
|
||||
const fieldSourceType = this.fieldSourceType(field, type)
|
||||
if (typeof obj !== 'string') {
|
||||
if (Array.isArray(fieldSourceType)) {
|
||||
for (const field of fieldSourceType) {
|
||||
obj[field.name] = [field.optional ? '?:' : ':', field.type]
|
||||
}
|
||||
} else if (typeof fieldSourceType === 'object') {
|
||||
obj[field.name] = [fieldSourceType.optional ? '?:' : ':', fieldSourceType.type]
|
||||
} else if (fieldSourceType) {
|
||||
obj[field.name] = [':', fieldSourceType]
|
||||
} else if (!this.hasResolver(field, type)) {
|
||||
obj[field.name] = [
|
||||
this.argSeparator(field.type as GraphQLInputType, false),
|
||||
this.printOutputType(field.type),
|
||||
|
@ -663,6 +672,17 @@ export class TypegenPrinter {
|
|||
return (this.typegenInfo.sourceTypeMap as any)[typeName]
|
||||
}
|
||||
|
||||
private fieldSourceType(
|
||||
field: GraphQLField<any, any>,
|
||||
// Used in test mocking
|
||||
_type: GraphQLObjectType
|
||||
) {
|
||||
if (field.extensions && isNexusFieldExtension(field.extensions.nexus)) {
|
||||
return field.extensions.nexus.sourceType
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
private hasResolver(
|
||||
field: GraphQLField<any, any>,
|
||||
// Used in test mocking
|
||||
|
|
|
@ -1,65 +1,75 @@
|
|||
import * as path from 'path'
|
||||
import type { BuilderConfigInput } from './builder'
|
||||
import type { ConfiguredTypegen } from './core'
|
||||
import { nodeImports } from './node'
|
||||
import type { TypegenMetadataConfig } from './typegenMetadata'
|
||||
import { assertAbsolutePath, getOwnPackage, isProductionStage } from './utils'
|
||||
|
||||
/** Normalizes the builder config into the config we need for typegen */
|
||||
export function resolveTypegenConfig(config: BuilderConfigInput): TypegenMetadataConfig {
|
||||
const {
|
||||
outputs,
|
||||
shouldGenerateArtifacts = Boolean(!process.env.NODE_ENV || process.env.NODE_ENV !== 'production'),
|
||||
...rest
|
||||
} = config
|
||||
const { outputs, shouldGenerateArtifacts = defaultShouldGenerateArtifacts(), ...rest } = config
|
||||
|
||||
const defaultSDLFilePath = path.join(process.cwd(), 'schema.graphql')
|
||||
function getOutputPaths() {
|
||||
const defaultSDLFilePath = nodeImports().path.join(process.cwd(), 'schema.graphql')
|
||||
|
||||
let typegenFilePath: ConfiguredTypegen | null = null
|
||||
let sdlFilePath: string | null = null
|
||||
let typegenFilePath: ConfiguredTypegen | null = null
|
||||
let sdlFilePath: string | null = null
|
||||
|
||||
if (outputs === undefined) {
|
||||
if (isProductionStage()) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
}
|
||||
} else if (outputs === true) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
} else if (typeof outputs === 'object') {
|
||||
if (outputs.schema === true) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
} else if (typeof outputs.schema === 'string') {
|
||||
sdlFilePath = assertAbsolutePath(outputs.schema, 'outputs.schema')
|
||||
} else if (outputs.schema === undefined && isProductionStage()) {
|
||||
}
|
||||
// handle typegen configuration
|
||||
if (typeof outputs.typegen === 'string') {
|
||||
typegenFilePath = {
|
||||
outputPath: assertAbsolutePath(outputs.typegen, 'outputs.typegen'),
|
||||
if (outputs === undefined) {
|
||||
if (isProductionStage()) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
}
|
||||
} else if (typeof outputs.typegen === 'object') {
|
||||
typegenFilePath = {
|
||||
...outputs.typegen,
|
||||
outputPath: assertAbsolutePath(outputs.typegen.outputPath, 'outputs.typegen.outputPath'),
|
||||
} as ConfiguredTypegen
|
||||
if (outputs.typegen.globalsPath) {
|
||||
typegenFilePath.globalsPath = assertAbsolutePath(
|
||||
outputs.typegen.globalsPath,
|
||||
'outputs.typegen.globalsPath'
|
||||
)
|
||||
} else if (outputs === true) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
} else if (typeof outputs === 'object') {
|
||||
if (outputs.schema === true) {
|
||||
sdlFilePath = defaultSDLFilePath
|
||||
} else if (typeof outputs.schema === 'string') {
|
||||
sdlFilePath = assertAbsolutePath(outputs.schema, 'outputs.schema')
|
||||
} else if (outputs.schema === undefined && isProductionStage()) {
|
||||
}
|
||||
// handle typegen configuration
|
||||
if (typeof outputs.typegen === 'string') {
|
||||
typegenFilePath = {
|
||||
outputPath: assertAbsolutePath(outputs.typegen, 'outputs.typegen'),
|
||||
}
|
||||
} else if (typeof outputs.typegen === 'object') {
|
||||
typegenFilePath = {
|
||||
...outputs.typegen,
|
||||
outputPath: assertAbsolutePath(outputs.typegen.outputPath, 'outputs.typegen.outputPath'),
|
||||
} as ConfiguredTypegen
|
||||
if (outputs.typegen.globalsPath) {
|
||||
typegenFilePath.globalsPath = assertAbsolutePath(
|
||||
outputs.typegen.globalsPath,
|
||||
'outputs.typegen.globalsPath'
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (outputs !== false) {
|
||||
console.warn(
|
||||
`You should specify a configuration value for outputs in Nexus' makeSchema. ` +
|
||||
`Provide one to remove this warning.`
|
||||
)
|
||||
}
|
||||
return {
|
||||
typegenFilePath,
|
||||
sdlFilePath,
|
||||
}
|
||||
} else if (outputs !== false) {
|
||||
console.warn(
|
||||
`You should specify a configuration value for outputs in Nexus' makeSchema. ` +
|
||||
`Provide one to remove this warning.`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
...rest,
|
||||
nexusSchemaImportId: getOwnPackage().name,
|
||||
outputs: {
|
||||
typegen: shouldGenerateArtifacts ? typegenFilePath : null,
|
||||
schema: shouldGenerateArtifacts ? sdlFilePath : null,
|
||||
typegen: shouldGenerateArtifacts ? getOutputPaths().typegenFilePath : null,
|
||||
schema: shouldGenerateArtifacts ? getOutputPaths().sdlFilePath : null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function defaultShouldGenerateArtifacts() {
|
||||
return Boolean(
|
||||
typeof process === 'object' &&
|
||||
typeof process.cwd === 'function' &&
|
||||
(!process.env.NODE_ENV || process.env.NODE_ENV !== 'production')
|
||||
)
|
||||
}
|
||||
|
|
24
src/utils.ts
24
src/utils.ts
|
@ -1,4 +1,3 @@
|
|||
import * as fs from 'fs'
|
||||
import {
|
||||
GraphQLEnumType,
|
||||
GraphQLInputObjectType,
|
||||
|
@ -22,7 +21,6 @@ import {
|
|||
isWrappingType,
|
||||
specifiedScalarTypes,
|
||||
} from 'graphql'
|
||||
import * as Path from 'path'
|
||||
import { decorateType } from './definitions/decorateType'
|
||||
import { isNexusMetaType, NexusMetaType, resolveNexusMetaType } from './definitions/nexusMeta'
|
||||
import {
|
||||
|
@ -42,6 +40,7 @@ import {
|
|||
TypingImport,
|
||||
withNexusSymbol,
|
||||
} from './definitions/_types'
|
||||
import { nodeImports } from './node'
|
||||
|
||||
export const isInterfaceField = (type: GraphQLObjectType, fieldName: string) => {
|
||||
return type.getInterfaces().some((i) => Boolean(i.getFields()[fieldName]))
|
||||
|
@ -150,7 +149,7 @@ export function eachObj<T>(obj: Record<string, T>, iter: (val: T, key: string, i
|
|||
export const isObject = (obj: any): boolean => obj !== null && typeof obj === 'object'
|
||||
|
||||
export const assertAbsolutePath = (pathName: string, property: string) => {
|
||||
if (!Path.isAbsolute(pathName)) {
|
||||
if (!nodeImports().path.isAbsolute(pathName)) {
|
||||
throw new Error(`Expected path for "${property}" to be an absolute path, saw "${pathName}"`)
|
||||
}
|
||||
return pathName
|
||||
|
@ -221,7 +220,7 @@ export function isPromiseLike(value: any): value is PromiseLike<any> {
|
|||
export const typeScriptFileExtension = /(\.d)?\.ts$/
|
||||
|
||||
function makeRelativePathExplicitlyRelative(path: string) {
|
||||
if (Path.isAbsolute(path)) return path
|
||||
if (nodeImports().path.isAbsolute(path)) return path
|
||||
if (path.startsWith('./')) return path
|
||||
return `./${path}`
|
||||
}
|
||||
|
@ -243,6 +242,7 @@ export function formatPathForModuleImport(path: string) {
|
|||
}
|
||||
|
||||
export function relativePathTo(absolutePath: string, fromPath: string): string {
|
||||
const Path = nodeImports().path
|
||||
const filename = Path.basename(absolutePath)
|
||||
const relative = Path.relative(Path.dirname(fromPath), Path.dirname(absolutePath))
|
||||
return formatPathForModuleImport(Path.join(relative, filename))
|
||||
|
@ -477,20 +477,18 @@ export function casesHandled(x: never): never {
|
|||
throw new Error(`A case was not handled for value: "${x}"`)
|
||||
}
|
||||
|
||||
/** Quickly log objects */
|
||||
export function dump(x: any) {
|
||||
console.log(require('util').inspect(x, { depth: null }))
|
||||
}
|
||||
|
||||
function isNodeModule(path: string) {
|
||||
// Avoid treating absolute windows paths as Node packages e.g. D:/a/b/c
|
||||
return !Path.isAbsolute(path) && /^([A-z0-9@])/.test(path)
|
||||
return !nodeImports().path.isAbsolute(path) && /^([A-z0-9@])/.test(path)
|
||||
}
|
||||
|
||||
export function resolveImportPath(rootType: TypingImport, typeName: string, outputPath: string) {
|
||||
const rootTypePath = rootType.module
|
||||
|
||||
if (typeof rootTypePath !== 'string' || (!Path.isAbsolute(rootTypePath) && !isNodeModule(rootTypePath))) {
|
||||
if (
|
||||
typeof rootTypePath !== 'string' ||
|
||||
(!nodeImports().path.isAbsolute(rootTypePath) && !isNodeModule(rootTypePath))
|
||||
) {
|
||||
throw new Error(
|
||||
`Expected an absolute path or Node package for the root typing path of the type "${typeName}", saw "${rootTypePath}"`
|
||||
)
|
||||
|
@ -502,7 +500,7 @@ export function resolveImportPath(rootType: TypingImport, typeName: string, outp
|
|||
} catch (e) {
|
||||
throw new Error(`Module "${rootTypePath}" for the type "${typeName}" does not exist`)
|
||||
}
|
||||
} else if (!fs.existsSync(rootTypePath)) {
|
||||
} else if (!nodeImports().fs.existsSync(rootTypePath)) {
|
||||
throw new Error(`Root typing path "${rootTypePath}" for the type "${typeName}" does not exist`)
|
||||
}
|
||||
|
||||
|
@ -510,7 +508,7 @@ export function resolveImportPath(rootType: TypingImport, typeName: string, outp
|
|||
return rootTypePath
|
||||
}
|
||||
|
||||
if (Path.isAbsolute(rootTypePath)) {
|
||||
if (nodeImports().path.isAbsolute(rootTypePath)) {
|
||||
return relativePathTo(rootTypePath, outputPath)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { GraphQLSchema } from 'graphql'
|
||||
import { makeSchema, queryType } from '../../dist'
|
||||
|
||||
const schema = makeSchema({
|
||||
types: [
|
||||
queryType({
|
||||
definition(t) {
|
||||
t.boolean('ok')
|
||||
},
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
if (!(schema instanceof GraphQLSchema)) {
|
||||
throw new Error('Not a schema')
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import esbuild from 'esbuild'
|
||||
import path from 'path'
|
||||
import vm from 'vm'
|
||||
import fs from 'fs'
|
||||
|
||||
describe('standalone esm', () => {
|
||||
it('should build the esbuild', async () => {
|
||||
const out = await esbuild.build({
|
||||
bundle: true,
|
||||
format: 'esm',
|
||||
target: 'esnext',
|
||||
// minify: true,
|
||||
mainFields: ['module', 'main'],
|
||||
external: ['path', 'fs', 'prettier'],
|
||||
entryPoints: [path.join(__dirname, 'esm-entry.js')],
|
||||
outdir: path.join(__dirname, 'out'),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
metafile: true,
|
||||
})
|
||||
|
||||
const context = vm.createContext()
|
||||
// @ts-ignore
|
||||
const outPath = path.join(__dirname, 'out', 'esm-entry.mjs')
|
||||
fs.writeFileSync(path.join(path.dirname(outPath), 'meta.json'), JSON.stringify(out.metafile))
|
||||
const script = new vm.Script(fs.readFileSync(outPath, 'utf8'), {
|
||||
filename: outPath,
|
||||
})
|
||||
script.runInNewContext(context)
|
||||
})
|
||||
})
|
|
@ -26,6 +26,19 @@ import {
|
|||
import { mockStream } from '../../__helpers'
|
||||
import './__typegen'
|
||||
|
||||
export const Node = interfaceType({
|
||||
name: 'Node',
|
||||
definition(t) {
|
||||
t.nonNull.id('id', {
|
||||
resolve: (source, args, ctx, info) => `${info.parentType.name}:${source.id}`,
|
||||
sourceType: 'number',
|
||||
})
|
||||
},
|
||||
resolveType(obj: any) {
|
||||
return obj.__typename
|
||||
},
|
||||
})
|
||||
|
||||
export const typeDirective = directive({
|
||||
name: 'TestTypeDirective',
|
||||
locations: ['OBJECT', 'INTERFACE', 'ENUM', 'SCALAR'],
|
||||
|
@ -116,12 +129,20 @@ export const i2 = objectType({
|
|||
extensionAdditionFromTypeConfig: true,
|
||||
},
|
||||
definition(t) {
|
||||
t.implements(Node)
|
||||
t.implements('I')
|
||||
t.modify('hello', {
|
||||
extensions: {
|
||||
extensionAdditionFromModifyMethod: true,
|
||||
},
|
||||
})
|
||||
t.string('composite', {
|
||||
resolve: (source) => `${source.fieldA} ${source.fieldB}`,
|
||||
sourceType: [
|
||||
{ name: 'fieldA', type: 'string' },
|
||||
{ name: 'fieldB', type: 'string' },
|
||||
],
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -180,8 +201,12 @@ export const Post = objectType({
|
|||
export const User = objectType({
|
||||
name: 'User',
|
||||
definition(t) {
|
||||
t.string('firstName')
|
||||
t.string('lastName')
|
||||
t.string('firstName', {
|
||||
sourceType: 'string',
|
||||
})
|
||||
t.string('lastName', {
|
||||
sourceType: 'string',
|
||||
})
|
||||
t.connectionField('posts', {
|
||||
type: Post,
|
||||
nodes() {
|
||||
|
@ -206,8 +231,11 @@ export const User = objectType({
|
|||
},
|
||||
},
|
||||
})
|
||||
t.string('telephone', {
|
||||
sourceType: { type: 'string', optional: true },
|
||||
resolve: (source) => (source.telephone ? `+1 ${source.telephone}` : null),
|
||||
})
|
||||
},
|
||||
sourceType: `{ firstName: string, lastName: string }`,
|
||||
})
|
||||
|
||||
export const Query = extendType({
|
||||
|
|
|
@ -39,12 +39,18 @@ No-Op scalar for testing purposes only
|
|||
"""
|
||||
scalar MyCustomScalar @TestAllDirective
|
||||
|
||||
interface Node {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type OfI implements I @TestTypeDirective {
|
||||
hello: String @TestFieldDirective(bool: true)
|
||||
}
|
||||
|
||||
type OfI2 implements I {
|
||||
type OfI2 implements I & Node {
|
||||
composite: String
|
||||
hello: String @TestFieldDirective(bool: true)
|
||||
id: ID!
|
||||
}
|
||||
|
||||
"""
|
||||
|
@ -156,6 +162,7 @@ type User {
|
|||
"""
|
||||
last: Int
|
||||
): PostConnection
|
||||
telephone: String
|
||||
}
|
||||
|
||||
enum UserStatus {
|
||||
|
|
|
@ -89,7 +89,10 @@ export interface NexusGenObjects {
|
|||
}
|
||||
OfI2: {
|
||||
// root type
|
||||
fieldA: string
|
||||
fieldB: string
|
||||
hello?: string | null // String
|
||||
id: number
|
||||
}
|
||||
PageInfo: {
|
||||
// root type
|
||||
|
@ -117,11 +120,17 @@ export interface NexusGenObjects {
|
|||
}
|
||||
Query: {}
|
||||
Subscription: {}
|
||||
User: { firstName: string; lastName: string }
|
||||
User: {
|
||||
// root type
|
||||
firstName: string
|
||||
lastName: string
|
||||
telephone?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface NexusGenInterfaces {
|
||||
I: NexusGenRootTypes['OfI'] | NexusGenRootTypes['OfI2']
|
||||
Node: NexusGenRootTypes['OfI2']
|
||||
}
|
||||
|
||||
export interface NexusGenUnions {}
|
||||
|
@ -141,7 +150,9 @@ export interface NexusGenFieldTypes {
|
|||
}
|
||||
OfI2: {
|
||||
// field return type
|
||||
composite: string | null // String
|
||||
hello: string | null // String
|
||||
id: string // ID!
|
||||
}
|
||||
PageInfo: {
|
||||
// field return type
|
||||
|
@ -192,11 +203,16 @@ export interface NexusGenFieldTypes {
|
|||
firstName: string | null // String
|
||||
lastName: string | null // String
|
||||
posts: NexusGenRootTypes['PostConnection'] | null // PostConnection
|
||||
telephone: string | null // String
|
||||
}
|
||||
I: {
|
||||
// field return type
|
||||
hello: string | null // String
|
||||
}
|
||||
Node: {
|
||||
// field return type
|
||||
id: string // ID!
|
||||
}
|
||||
}
|
||||
|
||||
export interface NexusGenFieldTypeNames {
|
||||
|
@ -210,7 +226,9 @@ export interface NexusGenFieldTypeNames {
|
|||
}
|
||||
OfI2: {
|
||||
// field return type name
|
||||
composite: 'String'
|
||||
hello: 'String'
|
||||
id: 'ID'
|
||||
}
|
||||
PageInfo: {
|
||||
// field return type name
|
||||
|
@ -261,11 +279,16 @@ export interface NexusGenFieldTypeNames {
|
|||
firstName: 'String'
|
||||
lastName: 'String'
|
||||
posts: 'PostConnection'
|
||||
telephone: 'String'
|
||||
}
|
||||
I: {
|
||||
// field return type name
|
||||
hello: 'String'
|
||||
}
|
||||
Node: {
|
||||
// field return type name
|
||||
id: 'ID'
|
||||
}
|
||||
}
|
||||
|
||||
export interface NexusGenArgTypes {
|
||||
|
@ -306,11 +329,12 @@ export interface NexusGenArgTypes {
|
|||
|
||||
export interface NexusGenAbstractTypeMembers {
|
||||
I: 'OfI' | 'OfI2'
|
||||
Node: 'OfI2'
|
||||
}
|
||||
|
||||
export interface NexusGenTypeInterfaces {
|
||||
OfI: 'I'
|
||||
OfI2: 'I'
|
||||
OfI2: 'I' | 'Node'
|
||||
}
|
||||
|
||||
export type NexusGenObjectNames = keyof NexusGenObjects
|
||||
|
@ -348,7 +372,7 @@ export interface NexusGenDirectiveArgs {
|
|||
|
||||
export type NexusGenObjectsUsingAbstractStrategyIsTypeOf = never
|
||||
|
||||
export type NexusGenAbstractsUsingStrategyResolveType = 'I'
|
||||
export type NexusGenAbstractsUsingStrategyResolveType = 'I' | 'Node'
|
||||
|
||||
export type NexusGenFeaturesConfig = {
|
||||
abstractTypeStrategies: {
|
||||
|
|
|
@ -292,6 +292,7 @@ it('extensions are inherited and deeply merged by field modifications', () => {
|
|||
"foo2": true,
|
||||
},
|
||||
"nexus": NexusFieldExtension {
|
||||
"_type": "NexusFieldExtension",
|
||||
"config": Object {
|
||||
"configFor": "outputField",
|
||||
"extensions": Object {
|
||||
|
@ -305,6 +306,7 @@ it('extensions are inherited and deeply merged by field modifications', () => {
|
|||
"wrapping": undefined,
|
||||
},
|
||||
"hasDefinedResolver": false,
|
||||
"sourceType": undefined,
|
||||
},
|
||||
}
|
||||
`)
|
||||
|
|
126
yarn.lock
126
yarn.lock
|
@ -2520,6 +2520,132 @@ es6-weak-map@^2.0.1:
|
|||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
esbuild-android-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.48.tgz#7e6394a0e517f738641385aaf553c7e4fb6d1ae3"
|
||||
integrity sha512-3aMjboap/kqwCUpGWIjsk20TtxVoKck8/4Tu19rubh7t5Ra0Yrpg30Mt1QXXlipOazrEceGeWurXKeFJgkPOUg==
|
||||
|
||||
esbuild-android-arm64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.48.tgz#6877566be0f82dd5a43030c0007d06ece7f7c02f"
|
||||
integrity sha512-vptI3K0wGALiDq+EvRuZotZrJqkYkN5282iAfcffjI5lmGG9G1ta/CIVauhY42MBXwEgDJkweiDcDMRLzBZC4g==
|
||||
|
||||
esbuild-darwin-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.48.tgz#ea3caddb707d88f844b1aa1dea5ff3b0a71ef1fd"
|
||||
integrity sha512-gGQZa4+hab2Va/Zww94YbshLuWteyKGD3+EsVon8EWTWhnHFRm5N9NbALNbwi/7hQ/hM1Zm4FuHg+k6BLsl5UA==
|
||||
|
||||
esbuild-darwin-arm64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.48.tgz#4e5eaab54df66cc319b76a2ac0e8af4e6f0d9c2f"
|
||||
integrity sha512-bFjnNEXjhZT+IZ8RvRGNJthLWNHV5JkCtuOFOnjvo5pC0sk2/QVk0Qc06g2PV3J0TcU6kaPC3RN9yy9w2PSLEA==
|
||||
|
||||
esbuild-freebsd-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.48.tgz#47b5abc7426eae66861490ffbb380acc67af5b15"
|
||||
integrity sha512-1NOlwRxmOsnPcWOGTB10JKAkYSb2nue0oM1AfHWunW/mv3wERfJmnYlGzL3UAOIUXZqW8GeA2mv+QGwq7DToqA==
|
||||
|
||||
esbuild-freebsd-arm64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.48.tgz#e8c54c8637cd44feed967ea12338b0a4da3a7b11"
|
||||
integrity sha512-gXqKdO8wabVcYtluAbikDH2jhXp+Klq5oCD5qbVyUG6tFiGhrC9oczKq3vIrrtwcxDQqK6+HDYK8Zrd4bCA9Gw==
|
||||
|
||||
esbuild-linux-32@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.48.tgz#229cf3246de2b7937c3ac13fac622d4d7a1344c5"
|
||||
integrity sha512-ghGyDfS289z/LReZQUuuKq9KlTiTspxL8SITBFQFAFRA/IkIvDpnZnCAKTCjGXAmUqroMQfKJXMxyjJA69c/nQ==
|
||||
|
||||
esbuild-linux-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.48.tgz#7c0e7226c02c42aacc5656c36977493dc1e96c4f"
|
||||
integrity sha512-vni3p/gppLMVZLghI7oMqbOZdGmLbbKR23XFARKnszCIBpEMEDxOMNIKPmMItQrmH/iJrL1z8Jt2nynY0bE1ug==
|
||||
|
||||
esbuild-linux-arm64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.48.tgz#0af1eda474b5c6cc0cace8235b74d0cb8fcf57a7"
|
||||
integrity sha512-3CFsOlpoxlKPRevEHq8aAntgYGYkE1N9yRYAcPyng/p4Wyx0tPR5SBYsxLKcgPB9mR8chHEhtWYz6EZ+H199Zw==
|
||||
|
||||
esbuild-linux-arm@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.48.tgz#de4d1fa6b77cdcd00e2bb43dd0801e4680f0ab52"
|
||||
integrity sha512-+VfSV7Akh1XUiDNXgqgY1cUP1i2vjI+BmlyXRfVz5AfV3jbpde8JTs5Q9sYgaoq5cWfuKfoZB/QkGOI+QcL1Tw==
|
||||
|
||||
esbuild-linux-mips64le@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.48.tgz#822c1778495f7868e990d4da47ad7281df28fd15"
|
||||
integrity sha512-cs0uOiRlPp6ymknDnjajCgvDMSsLw5mST2UXh+ZIrXTj2Ifyf2aAP3Iw4DiqgnyYLV2O/v/yWBJx+WfmKEpNLA==
|
||||
|
||||
esbuild-linux-ppc64le@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.48.tgz#55de0a9ec4a48fedfe82a63e083164d001709447"
|
||||
integrity sha512-+2F0vJMkuI0Wie/wcSPDCqXvSFEELH7Jubxb7mpWrA/4NpT+/byjxDz0gG6R1WJoeDefcrMfpBx4GFNN1JQorQ==
|
||||
|
||||
esbuild-linux-riscv64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.48.tgz#cd2b7381880b2f4b21a5a598fb673492120f18a5"
|
||||
integrity sha512-BmaK/GfEE+5F2/QDrIXteFGKnVHGxlnK9MjdVKMTfvtmudjY3k2t8NtlY4qemKSizc+QwyombGWTBDc76rxePA==
|
||||
|
||||
esbuild-linux-s390x@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.48.tgz#4b319eca2a5c64637fc7397ffbd9671719cdb6bf"
|
||||
integrity sha512-tndw/0B9jiCL+KWKo0TSMaUm5UWBLsfCKVdbfMlb3d5LeV9WbijZ8Ordia8SAYv38VSJWOEt6eDCdOx8LqkC4g==
|
||||
|
||||
esbuild-netbsd-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.48.tgz#c27cde8b5cb55dcc227943a18ab078fb98d0adbf"
|
||||
integrity sha512-V9hgXfwf/T901Lr1wkOfoevtyNkrxmMcRHyticybBUHookznipMOHoF41Al68QBsqBxnITCEpjjd4yAos7z9Tw==
|
||||
|
||||
esbuild-openbsd-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.48.tgz#af5ab2d1cb41f09064bba9465fc8bf1309150df1"
|
||||
integrity sha512-+IHf4JcbnnBl4T52egorXMatil/za0awqzg2Vy6FBgPcBpisDWT2sVz/tNdrK9kAqj+GZG/jZdrOkj7wsrNTKA==
|
||||
|
||||
esbuild-sunos-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.48.tgz#db3ae20526055cf6fd5c4582676233814603ac54"
|
||||
integrity sha512-77m8bsr5wOpOWbGi9KSqDphcq6dFeJyun8TA+12JW/GAjyfTwVtOnN8DOt6DSPUfEV+ltVMNqtXUeTeMAxl5KA==
|
||||
|
||||
esbuild-windows-32@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.48.tgz#021ffceb0a3f83078262870da88a912293c57475"
|
||||
integrity sha512-EPgRuTPP8vK9maxpTGDe5lSoIBHGKO/AuxDncg5O3NkrPeLNdvvK8oywB0zGaAZXxYWfNNSHskvvDgmfVTguhg==
|
||||
|
||||
esbuild-windows-64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.48.tgz#a4d3407b580f9faac51f61eec095fa985fb3fee4"
|
||||
integrity sha512-YmpXjdT1q0b8ictSdGwH3M8VCoqPpK1/UArze3X199w6u8hUx3V8BhAi1WjbsfDYRBanVVtduAhh2sirImtAvA==
|
||||
|
||||
esbuild-windows-arm64@0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.48.tgz#762c0562127d8b09bfb70a3c816460742dd82880"
|
||||
integrity sha512-HHaOMCsCXp0rz5BT2crTka6MPWVno121NKApsGs/OIW5QC0ggC69YMGs1aJct9/9FSUF4A1xNE/cLvgB5svR4g==
|
||||
|
||||
esbuild@^0.14.48:
|
||||
version "0.14.48"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.48.tgz#da5d8d25cd2d940c45ea0cfecdca727f7aee2b85"
|
||||
integrity sha512-w6N1Yn5MtqK2U1/WZTX9ZqUVb8IOLZkZ5AdHkT6x3cHDMVsYWC7WPdiLmx19w3i4Rwzy5LqsEMtVihG3e4rFzA==
|
||||
optionalDependencies:
|
||||
esbuild-android-64 "0.14.48"
|
||||
esbuild-android-arm64 "0.14.48"
|
||||
esbuild-darwin-64 "0.14.48"
|
||||
esbuild-darwin-arm64 "0.14.48"
|
||||
esbuild-freebsd-64 "0.14.48"
|
||||
esbuild-freebsd-arm64 "0.14.48"
|
||||
esbuild-linux-32 "0.14.48"
|
||||
esbuild-linux-64 "0.14.48"
|
||||
esbuild-linux-arm "0.14.48"
|
||||
esbuild-linux-arm64 "0.14.48"
|
||||
esbuild-linux-mips64le "0.14.48"
|
||||
esbuild-linux-ppc64le "0.14.48"
|
||||
esbuild-linux-riscv64 "0.14.48"
|
||||
esbuild-linux-s390x "0.14.48"
|
||||
esbuild-netbsd-64 "0.14.48"
|
||||
esbuild-openbsd-64 "0.14.48"
|
||||
esbuild-sunos-64 "0.14.48"
|
||||
esbuild-windows-32 "0.14.48"
|
||||
esbuild-windows-64 "0.14.48"
|
||||
esbuild-windows-arm64 "0.14.48"
|
||||
|
||||
escape-goat@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
|
||||
|
|
Loading…
Reference in New Issue