diff --git a/src/index.ts b/src/index.ts index 7232871e9d..d2d2bed087 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,8 +86,6 @@ export { GraphQLDeprecatedDirective, GraphQLSpecifiedByDirective, GraphQLOneOfDirective, - // "Enum" of Type Kinds - TypeKind, // Constant Deprecation Reason DEFAULT_DEPRECATION_REASON, // GraphQL Types for introspection. @@ -229,12 +227,17 @@ export type { GraphQLDefaultInput, } from './type/index.ts'; -// Parse and operate on GraphQL language source files. // @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 // Deno misclassifies this merged value+type re-export and requires `export type`. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore TS1205 +export { TypeKind } from './type/typeKind.ts'; +// Parse and operate on GraphQL language source files. +// @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 +// Deno misclassifies this merged value+type re-export and requires `export type`. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore TS1205 export { Kind } from './language/kinds.ts'; export { @@ -262,7 +265,6 @@ export { visitInParallel, getEnterLeaveForKind, BREAK, - DirectiveLocation, // Predicates isDefinitionNode, isExecutableDefinitionNode, @@ -278,6 +280,12 @@ export { isSubscriptionOperationDefinitionNode, } from './language/index.ts'; +// @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 +// Deno misclassifies this merged value+type re-export and requires `export type`. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore TS1205 +export { DirectiveLocation } from './language/directiveLocation.ts'; + export type { ParseOptions, SourceLocation, diff --git a/src/language/__tests__/directiveLocation-test.ts b/src/language/__tests__/directiveLocation-test.ts new file mode 100644 index 0000000000..64cfc3425d --- /dev/null +++ b/src/language/__tests__/directiveLocation-test.ts @@ -0,0 +1,30 @@ +/* eslint-disable no-unused-expressions */ +import { describe, it } from 'node:test'; + +import { DirectiveLocation } from '../index.ts'; + +describe('DirectiveLocation', () => { + it('is a term level namespace with term level enum members', () => { + const a: DirectiveLocation.QUERY = DirectiveLocation.QUERY; + a; + const b: DirectiveLocation = DirectiveLocation.QUERY; + b; + const c: DirectiveLocation = DirectiveLocation.FIELD_DEFINITION; + c; + }); + + it('is a type level namespace with type level enum members', () => { + // @ts-expect-error + const a: DirectiveLocation.QUERY = 'bad'; + a; + const b: DirectiveLocation.QUERY = 'QUERY'; + b; + // @ts-expect-error + const c: DirectiveLocation = 'bad'; + c; + const d: DirectiveLocation = 'QUERY'; + d; + const e: DirectiveLocation = 'FIELD_DEFINITION'; + e; + }); +}); diff --git a/src/language/directiveLocation.ts b/src/language/directiveLocation.ts index 0185905651..b60e793308 100644 --- a/src/language/directiveLocation.ts +++ b/src/language/directiveLocation.ts @@ -1,31 +1,10 @@ +/* eslint-disable import/no-namespace */ +import type * as DirectiveLocation_ from './directiveLocation_.ts'; + /** * The set of allowed directive location values. */ -export const DirectiveLocation = { - /** Request Definitions */ - QUERY: 'QUERY' as const, - MUTATION: 'MUTATION' as const, - SUBSCRIPTION: 'SUBSCRIPTION' as const, - FIELD: 'FIELD' as const, - FRAGMENT_DEFINITION: 'FRAGMENT_DEFINITION' as const, - FRAGMENT_SPREAD: 'FRAGMENT_SPREAD' as const, - INLINE_FRAGMENT: 'INLINE_FRAGMENT' as const, - VARIABLE_DEFINITION: 'VARIABLE_DEFINITION' as const, - FRAGMENT_VARIABLE_DEFINITION: 'FRAGMENT_VARIABLE_DEFINITION' as const, - /** Type System Definitions */ - SCHEMA: 'SCHEMA' as const, - SCALAR: 'SCALAR' as const, - OBJECT: 'OBJECT' as const, - FIELD_DEFINITION: 'FIELD_DEFINITION' as const, - ARGUMENT_DEFINITION: 'ARGUMENT_DEFINITION' as const, - INTERFACE: 'INTERFACE' as const, - UNION: 'UNION' as const, - ENUM: 'ENUM' as const, - ENUM_VALUE: 'ENUM_VALUE' as const, - INPUT_OBJECT: 'INPUT_OBJECT' as const, - INPUT_FIELD_DEFINITION: 'INPUT_FIELD_DEFINITION' as const, - DIRECTIVE_DEFINITION: 'DIRECTIVE_DEFINITION' as const, -} as const; -// eslint-disable-next-line @typescript-eslint/no-redeclare +export * as DirectiveLocation from './directiveLocation_.ts'; + export type DirectiveLocation = - (typeof DirectiveLocation)[keyof typeof DirectiveLocation]; + (typeof DirectiveLocation_)[keyof typeof DirectiveLocation_]; diff --git a/src/language/directiveLocation_.ts b/src/language/directiveLocation_.ts new file mode 100644 index 0000000000..f4e71ccd48 --- /dev/null +++ b/src/language/directiveLocation_.ts @@ -0,0 +1,47 @@ +/* eslint-disable @typescript-eslint/no-redeclare */ + +/** Request Definitions */ +export const QUERY = 'QUERY'; +export type QUERY = typeof QUERY; +export const MUTATION = 'MUTATION'; +export type MUTATION = typeof MUTATION; +export const SUBSCRIPTION = 'SUBSCRIPTION'; +export type SUBSCRIPTION = typeof SUBSCRIPTION; +export const FIELD = 'FIELD'; +export type FIELD = typeof FIELD; +export const FRAGMENT_DEFINITION = 'FRAGMENT_DEFINITION'; +export type FRAGMENT_DEFINITION = typeof FRAGMENT_DEFINITION; +export const FRAGMENT_SPREAD = 'FRAGMENT_SPREAD'; +export type FRAGMENT_SPREAD = typeof FRAGMENT_SPREAD; +export const INLINE_FRAGMENT = 'INLINE_FRAGMENT'; +export type INLINE_FRAGMENT = typeof INLINE_FRAGMENT; +export const VARIABLE_DEFINITION = 'VARIABLE_DEFINITION'; +export type VARIABLE_DEFINITION = typeof VARIABLE_DEFINITION; +export const FRAGMENT_VARIABLE_DEFINITION = 'FRAGMENT_VARIABLE_DEFINITION'; +export type FRAGMENT_VARIABLE_DEFINITION = typeof FRAGMENT_VARIABLE_DEFINITION; + +/** Type System Definitions */ +export const SCHEMA = 'SCHEMA'; +export type SCHEMA = typeof SCHEMA; +export const SCALAR = 'SCALAR'; +export type SCALAR = typeof SCALAR; +export const OBJECT = 'OBJECT'; +export type OBJECT = typeof OBJECT; +export const FIELD_DEFINITION = 'FIELD_DEFINITION'; +export type FIELD_DEFINITION = typeof FIELD_DEFINITION; +export const ARGUMENT_DEFINITION = 'ARGUMENT_DEFINITION'; +export type ARGUMENT_DEFINITION = typeof ARGUMENT_DEFINITION; +export const INTERFACE = 'INTERFACE'; +export type INTERFACE = typeof INTERFACE; +export const UNION = 'UNION'; +export type UNION = typeof UNION; +export const ENUM = 'ENUM'; +export type ENUM = typeof ENUM; +export const ENUM_VALUE = 'ENUM_VALUE'; +export type ENUM_VALUE = typeof ENUM_VALUE; +export const INPUT_OBJECT = 'INPUT_OBJECT'; +export type INPUT_OBJECT = typeof INPUT_OBJECT; +export const INPUT_FIELD_DEFINITION = 'INPUT_FIELD_DEFINITION'; +export type INPUT_FIELD_DEFINITION = typeof INPUT_FIELD_DEFINITION; +export const DIRECTIVE_DEFINITION = 'DIRECTIVE_DEFINITION'; +export type DIRECTIVE_DEFINITION = typeof DIRECTIVE_DEFINITION; diff --git a/src/language/index.ts b/src/language/index.ts index 70cdb1792a..dac0481a97 100644 --- a/src/language/index.ts +++ b/src/language/index.ts @@ -124,4 +124,8 @@ export { isSubscriptionOperationDefinitionNode, } from './predicates.ts'; +// @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 +// Deno misclassifies this merged value+type re-export and requires `export type`. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore TS1205 export { DirectiveLocation } from './directiveLocation.ts'; diff --git a/src/type/__tests__/typeKind-test.ts b/src/type/__tests__/typeKind-test.ts new file mode 100644 index 0000000000..3cf018312b --- /dev/null +++ b/src/type/__tests__/typeKind-test.ts @@ -0,0 +1,30 @@ +/* eslint-disable no-unused-expressions */ +import { describe, it } from 'node:test'; + +import { TypeKind } from '../index.ts'; + +describe('TypeKind', () => { + it('is a term level namespace with term level enum members', () => { + const a: TypeKind.SCALAR = TypeKind.SCALAR; + a; + const b: TypeKind = TypeKind.SCALAR; + b; + const c: TypeKind = TypeKind.NON_NULL; + c; + }); + + it('is a type level namespace with type level enum members', () => { + // @ts-expect-error + const a: TypeKind.SCALAR = 'bad'; + a; + const b: TypeKind.SCALAR = 'SCALAR'; + b; + // @ts-expect-error + const c: TypeKind = 'bad'; + c; + const d: TypeKind = 'SCALAR'; + d; + const e: TypeKind = 'NON_NULL'; + e; + }); +}); diff --git a/src/type/index.ts b/src/type/index.ts index 1c6d388683..08b14577e9 100644 --- a/src/type/index.ts +++ b/src/type/index.ts @@ -191,14 +191,18 @@ export { __InputValue, __EnumValue, __TypeKind, - // "Enum" of Type Kinds - TypeKind, // Meta-field definitions. SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, } from './introspection.ts'; +// @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 +// Deno misclassifies this merged value+type re-export and requires `export type`. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore TS1205 +export { TypeKind } from './typeKind.ts'; + // Validate GraphQL schema. export { validateSchema, assertValidSchema } from './validate.ts'; diff --git a/src/type/introspection.ts b/src/type/introspection.ts index 9cca352176..6043fdadbb 100644 --- a/src/type/introspection.ts +++ b/src/type/introspection.ts @@ -32,6 +32,13 @@ import { import type { GraphQLDirective } from './directives.ts'; import { GraphQLBoolean, GraphQLString } from './scalars.ts'; import type { GraphQLSchema } from './schema.ts'; +import { TypeKind } from './typeKind.ts'; + +// @see https://github.com/typescript-eslint/typescript-eslint/issues/10313 +// Deno misclassifies this merged value+type re-export and requires `export type`. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore TS1205 +export { TypeKind } from './typeKind.ts'; export const __Schema: GraphQLObjectType = new GraphQLObjectType({ name: '__Schema', @@ -478,20 +485,6 @@ export const __EnumValue: GraphQLObjectType = new GraphQLObjectType({ }) as GraphQLFieldConfigMap, }); -export const TypeKind = { - SCALAR: 'SCALAR' as const, - OBJECT: 'OBJECT' as const, - INTERFACE: 'INTERFACE' as const, - UNION: 'UNION' as const, - ENUM: 'ENUM' as const, - INPUT_OBJECT: 'INPUT_OBJECT' as const, - LIST: 'LIST' as const, - NON_NULL: 'NON_NULL' as const, -} as const; - -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type TypeKind = (typeof TypeKind)[keyof typeof TypeKind]; - export const __TypeKind: GraphQLEnumType = new GraphQLEnumType({ name: '__TypeKind', description: 'An enum describing what kind of type a given `__Type` is.', diff --git a/src/type/typeKind.ts b/src/type/typeKind.ts new file mode 100644 index 0000000000..6e0366f95a --- /dev/null +++ b/src/type/typeKind.ts @@ -0,0 +1,9 @@ +/* eslint-disable import/no-namespace */ +import type * as TypeKind_ from './typeKind_.ts'; + +/** + * The set of allowed introspection type kind values. + */ +export * as TypeKind from './typeKind_.ts'; + +export type TypeKind = (typeof TypeKind_)[keyof typeof TypeKind_]; diff --git a/src/type/typeKind_.ts b/src/type/typeKind_.ts new file mode 100644 index 0000000000..91e7dc6772 --- /dev/null +++ b/src/type/typeKind_.ts @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-redeclare */ + +export const SCALAR = 'SCALAR'; +export type SCALAR = typeof SCALAR; +export const OBJECT = 'OBJECT'; +export type OBJECT = typeof OBJECT; +export const INTERFACE = 'INTERFACE'; +export type INTERFACE = typeof INTERFACE; +export const UNION = 'UNION'; +export type UNION = typeof UNION; +export const ENUM = 'ENUM'; +export type ENUM = typeof ENUM; +export const INPUT_OBJECT = 'INPUT_OBJECT'; +export type INPUT_OBJECT = typeof INPUT_OBJECT; +export const LIST = 'LIST'; +export type LIST = typeof LIST; +export const NON_NULL = 'NON_NULL'; +export type NON_NULL = typeof NON_NULL; diff --git a/src/utilities/buildClientSchema.ts b/src/utilities/buildClientSchema.ts index a9bcfb078a..d54e8ea4fb 100644 --- a/src/utilities/buildClientSchema.ts +++ b/src/utilities/buildClientSchema.ts @@ -27,10 +27,11 @@ import { isOutputType, } from '../type/definition.ts'; import { GraphQLDirective } from '../type/directives.ts'; -import { introspectionTypes, TypeKind } from '../type/introspection.ts'; +import { introspectionTypes } from '../type/introspection.ts'; import { specifiedScalarTypes } from '../type/scalars.ts'; import type { GraphQLSchemaValidationOptions } from '../type/schema.ts'; import { GraphQLSchema } from '../type/schema.ts'; +import { TypeKind } from '../type/typeKind.ts'; import type { IntrospectionDirective, diff --git a/src/utilities/getIntrospectionQuery.ts b/src/utilities/getIntrospectionQuery.ts index 260fd3734e..2f4ed61813 100644 --- a/src/utilities/getIntrospectionQuery.ts +++ b/src/utilities/getIntrospectionQuery.ts @@ -2,7 +2,7 @@ import type { Maybe } from '../jsutils/Maybe.ts'; import type { DirectiveLocation } from '../language/directiveLocation.ts'; -import type { TypeKind } from '../type/introspection.ts'; +import type { TypeKind } from '../type/typeKind.ts'; export interface IntrospectionOptions { /** @@ -224,14 +224,14 @@ export type IntrospectionInputType = | IntrospectionInputObjectType; export interface IntrospectionScalarType { - readonly kind: typeof TypeKind.SCALAR; + readonly kind: TypeKind.SCALAR; readonly name: string; readonly description?: Maybe; readonly specifiedByURL?: Maybe; } export interface IntrospectionObjectType { - readonly kind: typeof TypeKind.OBJECT; + readonly kind: TypeKind.OBJECT; readonly name: string; readonly description?: Maybe; readonly fields: ReadonlyArray; @@ -241,7 +241,7 @@ export interface IntrospectionObjectType { } export interface IntrospectionInterfaceType { - readonly kind: typeof TypeKind.INTERFACE; + readonly kind: TypeKind.INTERFACE; readonly name: string; readonly description?: Maybe; readonly fields: ReadonlyArray; @@ -254,7 +254,7 @@ export interface IntrospectionInterfaceType { } export interface IntrospectionUnionType { - readonly kind: typeof TypeKind.UNION; + readonly kind: TypeKind.UNION; readonly name: string; readonly description?: Maybe; readonly possibleTypes: ReadonlyArray< @@ -263,14 +263,14 @@ export interface IntrospectionUnionType { } export interface IntrospectionEnumType { - readonly kind: typeof TypeKind.ENUM; + readonly kind: TypeKind.ENUM; readonly name: string; readonly description?: Maybe; readonly enumValues: ReadonlyArray; } export interface IntrospectionInputObjectType { - readonly kind: typeof TypeKind.INPUT_OBJECT; + readonly kind: TypeKind.INPUT_OBJECT; readonly name: string; readonly description?: Maybe; readonly inputFields: ReadonlyArray; @@ -280,14 +280,14 @@ export interface IntrospectionInputObjectType { export interface IntrospectionListTypeRef< T extends IntrospectionTypeRef = IntrospectionTypeRef, > { - readonly kind: typeof TypeKind.LIST; + readonly kind: TypeKind.LIST; readonly ofType: T; } export interface IntrospectionNonNullTypeRef< T extends IntrospectionTypeRef = IntrospectionTypeRef, > { - readonly kind: typeof TypeKind.NON_NULL; + readonly kind: TypeKind.NON_NULL; readonly ofType: T; }