Skip to content

Commit

Permalink
Merge pull request #1439 from nestjs/8.0.0
Browse files Browse the repository at this point in the history
chore(): 8.0.0 major release WIP
  • Loading branch information
kamilmysliwiec committed Jul 7, 2021
2 parents 6e1013b + 1eec21f commit 83b4919
Show file tree
Hide file tree
Showing 41 changed files with 1,171 additions and 1,112 deletions.
49 changes: 35 additions & 14 deletions lib/graphql-ast.explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ export class GraphQLAstExplorer {
? `${DEFINITIONS_FILE_HEADER}\n${options.additionalHeader}\n\n`
: DEFINITIONS_FILE_HEADER;
tsFile.insertText(0, header);
tsFile.addTypeAlias({
name: 'Nullable',
isExported: false,
type: 'T | null',
typeParameters: [
{
name: 'T',
},
],
});

return tsFile;
}

Expand Down Expand Up @@ -288,6 +299,7 @@ export class GraphQLAstExplorer {
});
return;
}

if (options.skipResolverArgs) {
(parentRef as ClassDeclaration).addProperty({
name: propertyName,
Expand All @@ -298,9 +310,7 @@ export class GraphQLAstExplorer {
(parentRef as ClassDeclaration).addMethod({
isAbstract: mode === 'class',
name: propertyName,
returnType: `${this.addSymbolIfRoot(
type,
)} | Promise<${this.addSymbolIfRoot(type)}>`,
returnType: `${type} | Promise<${type}>`,
parameters: this.getFunctionParameters(
(item as FieldDefinitionNode).arguments,
options,
Expand All @@ -310,29 +320,38 @@ export class GraphQLAstExplorer {
}

getFieldTypeDefinition(
type: TypeNode,
typeNode: TypeNode,
options: DefinitionsGeneratorOptions,
): {
name: string;
required: boolean;
} {
const { required, type: nestedType } = this.getNestedType(type);
type = nestedType;
const { required, type } = this.getNestedType(typeNode);

const isArray = type.kind === 'ListType';
if (isArray) {
const { type: nestedType } = this.getNestedType(get(type, 'type'));
type = nestedType;
const {
type: arrayType,
required: arrayTypeRequired,
} = this.getNestedType(get(type, 'type'));

const typeName = this.addSymbolIfRoot(get(arrayType, 'name.value'));
const name = arrayTypeRequired
? this.getType(typeName, options)
: `Nullable<${this.getType(typeName, options)}>`;

const typeName = get(type, 'name.value');
return {
name: this.getType(typeName, options) + '[]',
name: required ? name + '[]' : `Nullable<${name}[]>`,
required,
};
}
const typeName = get(type, 'name.value');

const typeName = this.addSymbolIfRoot(get(type, 'name.value'));

return {
name: this.getType(typeName, options),
name: required
? this.getType(typeName, options)
: `Nullable<${this.getType(typeName, options)}>`,
required,
};
}
Expand Down Expand Up @@ -453,12 +472,14 @@ export class GraphQLAstExplorer {
return;
}
if (options.enumsAsTypes) {
const values = item.values.map((value) => `"${get(value, 'name.value')}"`)
const values = item.values.map(
(value) => `"${get(value, 'name.value')}"`,
);
return tsFile.addTypeAlias({
name,
type: values.join(' | '),
isExported: true,
})
});
}
const members = map(item.values, (value) => ({
name: get(value, 'name.value'),
Expand Down
24 changes: 16 additions & 8 deletions lib/graphql-definitions.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
GraphQLAstExplorer,
} from './graphql-ast.explorer';
import { GraphQLTypesLoader } from './graphql-types.loader';
import { removeTempField } from './utils';
import { extend, removeTempField } from './utils';

export class GraphQLDefinitionsFactory {
private readonly gqlAstExplorer = new GraphQLAstExplorer();
Expand All @@ -23,6 +23,7 @@ export class GraphQLDefinitionsFactory {
watch?: boolean;
debug?: boolean;
federation?: boolean;
typeDefs?: string | string[];
} & DefinitionsGeneratorOptions,
) {
const isDebugEnabled = !(options && options.debug === false);
Expand Down Expand Up @@ -60,6 +61,7 @@ export class GraphQLDefinitionsFactory {
isFederation,
isDebugEnabled,
definitionsGeneratorOptions,
options.typeDefs
);
});
}
Expand All @@ -70,6 +72,7 @@ export class GraphQLDefinitionsFactory {
isFederation,
isDebugEnabled,
definitionsGeneratorOptions,
options.typeDefs
);
}

Expand All @@ -80,6 +83,7 @@ export class GraphQLDefinitionsFactory {
isFederation: boolean,
isDebugEnabled: boolean,
definitionsGeneratorOptions: DefinitionsGeneratorOptions = {},
typeDefs?: string | string[]
) {
if (isFederation) {
return this.exploreAndEmitFederation(
Expand All @@ -88,6 +92,7 @@ export class GraphQLDefinitionsFactory {
outputAs,
isDebugEnabled,
definitionsGeneratorOptions,
typeDefs
);
}
return this.exploreAndEmitRegular(
Expand All @@ -96,6 +101,7 @@ export class GraphQLDefinitionsFactory {
outputAs,
isDebugEnabled,
definitionsGeneratorOptions,
typeDefs
);
}

Expand All @@ -105,8 +111,10 @@ export class GraphQLDefinitionsFactory {
outputAs: 'class' | 'interface',
isDebugEnabled: boolean,
definitionsGeneratorOptions: DefinitionsGeneratorOptions,
typeDefs?: string | string[]
) {
const typeDefs = await this.gqlTypesLoader.mergeTypesByPaths(typePaths);
const typePathDefs = await this.gqlTypesLoader.mergeTypesByPaths(typePaths);
const mergedTypeDefs = extend(typePathDefs, typeDefs);

const {
buildFederatedSchema,
Expand All @@ -118,7 +126,7 @@ export class GraphQLDefinitionsFactory {
const schema = buildFederatedSchema([
{
typeDefs: gql`
${typeDefs}
${mergedTypeDefs}
`,
resolvers: {},
},
Expand All @@ -144,15 +152,15 @@ export class GraphQLDefinitionsFactory {
outputAs: 'class' | 'interface',
isDebugEnabled: boolean,
definitionsGeneratorOptions: DefinitionsGeneratorOptions,
typeDefs?: string | string[]
) {
const typeDefs = await this.gqlTypesLoader.mergeTypesByPaths(
typePaths || [],
);
if (!typeDefs) {
const typePathDefs = await this.gqlTypesLoader.mergeTypesByPaths(typePaths || []);
const mergedTypeDefs = extend(typePathDefs, typeDefs);
if (!mergedTypeDefs) {
throw new Error(`"typeDefs" property cannot be null.`);
}
let schema = makeExecutableSchema({
typeDefs,
typeDefs: mergedTypeDefs,
resolverValidationOptions: { requireResolversToMatchSchema: 'ignore' },
});
schema = removeTempField(schema);
Expand Down
2 changes: 1 addition & 1 deletion lib/graphql.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const SUBSCRIPTION_TYPE = 'Subscription';

export const DEFINITIONS_FILE_HEADER = `
/*
* ------------------------------------------------------
* -------------------------------------------------------
* THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
* -------------------------------------------------------
*/
Expand Down
6 changes: 6 additions & 0 deletions lib/interfaces/gql-module-options.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export interface GqlModuleOptions
* Apply `transformSchema` to the `autoSchemaFile`
*/
transformAutoSchemaFile?: boolean;
/**
* If enabled, will register a global interceptor that automatically maps
* "HttpException" class instances to corresponding Apollo errors.
* @default true
*/
autoTransformHttpErrors?: boolean;
}

export interface GqlOptionsFactory {
Expand Down
25 changes: 25 additions & 0 deletions lib/plugin/utils/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
CommentRange,
getLeadingCommentRanges,
getTrailingCommentRanges,
UnionTypeNode,
TypeNode,
} from 'typescript';
import { isDynamicallyAdded } from './plugin-utils';

Expand Down Expand Up @@ -70,6 +72,22 @@ export function isEnumLiteral(type: Type) {
return hasFlag(type, TypeFlags.EnumLiteral) && !type.isUnion();
}

export function isNull(type: Type) {
if (type.isUnion()) {
return Boolean(type.types.find((t) => hasFlag(t, TypeFlags.Null)));
} else {
return hasFlag(type, TypeFlags.Null);
}
}

export function isUndefined(type: Type) {
if (type.isUnion()) {
return Boolean(type.types.find((t) => hasFlag(t, TypeFlags.Undefined)));
} else {
return hasFlag(type, TypeFlags.Undefined);
}
}

export function hasFlag(type: Type, flag: TypeFlags) {
return (type.flags & flag) === flag;
}
Expand Down Expand Up @@ -172,3 +190,10 @@ export function getDescriptionOfNode(
}
return description.join('\n');
}

export function findNullableTypeFromUnion(typeNode: UnionTypeNode, typeChecker: TypeChecker) {
return typeNode.types.find(
(tNode: TypeNode) =>
hasFlag(typeChecker.getTypeAtLocation(tNode), TypeFlags.Null)
);
}
4 changes: 2 additions & 2 deletions lib/plugin/utils/plugin-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function getTypeReferenceAsString(
return Boolean.name;
}
if (isEnum(type)) {
return getText(type, typeChecker);
return text;
}
const isEnumMember =
type.symbol && type.symbol.flags === ts.SymbolFlags.EnumMember;
Expand All @@ -76,7 +76,7 @@ export function getTypeReferenceAsString(
if (!type) {
return undefined;
}
return getText(type, typeChecker);
return text;
}
if (
isAutoGeneratedTypeUnion(type) ||
Expand Down

0 comments on commit 83b4919

Please sign in to comment.