Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a97df72
fixed typings
Oct 20, 2017
4dc942b
created generic description method & field decorator can set description
Oct 20, 2017
c861400
implemented NonNull as Field option
Oct 20, 2017
f4e62be
implemente4d description as schema option
Oct 20, 2017
02d5cd9
implemented description for Query & Mutation options
Oct 20, 2017
1137265
created description for List option
Oct 20, 2017
318734c
made option optional
Oct 20, 2017
30ae888
completed implementing description as part of other decoration option
Oct 20, 2017
fe0ee68
refactored setDescriptionMetadata, simplified
Oct 20, 2017
7fdbbe8
created new sample
playerx Oct 21, 2017
c40c450
removed unused decorators
playerx Oct 21, 2017
2a59e06
formatted
playerx Oct 21, 2017
30bf6fb
created DefaultOption
playerx Oct 21, 2017
109932e
created new options for field decorator & created tests
playerx Oct 21, 2017
e238e8d
updated sample
playerx Oct 21, 2017
b0ab52d
added:
playerx Oct 21, 2017
c664e20
updated documentation & samples
playerx Oct 21, 2017
81984d7
created initial subscription support
playerx Oct 22, 2017
7cafb4a
* removed debug info
playerx Oct 22, 2017
8d5e055
updated demo project, crated subscription sample with documentation
playerx Oct 22, 2017
d5101f8
fixed undefined parameter
playerx Oct 22, 2017
354ed22
updated types for graphql up to 0.11.5
playerx Oct 22, 2017
9e2bcc0
updated example project, created paging & orderby sample
playerx Oct 22, 2017
fe87cdf
* refactoring
playerx Oct 22, 2017
c52357b
updated documentation
playerx Oct 22, 2017
85a57d7
added printSchema endpoint
playerx Oct 22, 2017
2d8e76d
added esnext lib
playerx Oct 22, 2017
6adb24f
fixed examples
playerx Oct 22, 2017
eb59629
removed commented code
playerx Oct 24, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
"@types/graphql": "0.8.6",
"@types/mocha": "2.2.39",
"@types/node": "7.0.5"
}
}
},
"typings": "lib/index.d.ts"
}
241 changes: 171 additions & 70 deletions src/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,41 @@ export interface EnumValueMetadata {

export interface FieldOption {
type?: any;
description?: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the pagination? It would be nice to have it here as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I agree, but first I've implemented just description field to get your feedback and pagination can be implemented with the same way later.

nonNull?: boolean;
}

export interface ArgumentOption {
name: string;
type?: any;
}

export interface ListOption {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all these description fileds mean the same thing and it is part of every available option object, what if you'd extract them to an interface and then you'd extend that interface from all those options?

Something like:

export interface DefaultOption {
  description?: string;
}

export interface ObjectTypeOption extends DefaultOption { }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I thought about that also but kept it for next step, I was thinking about refactoring current code base, for now everything (about decorators) is in one file and maybe it would be good to split it in separate files, file per decorator + 1 common file.

description?: string;
}

export interface ObjectTypeOption {
description?: string;
}

export interface InputObjectTypeOption {
description?: string;
}

export interface QueryOption {
description?: string;
}

export interface MutationOption {
description?: string;
}

export interface SchemaOption {
description?: string;
type?: any;
}


export interface DescriptionMetadata {
description: string;
}
Expand Down Expand Up @@ -230,6 +258,81 @@ function setRootMetadata(target: any, propertyKey: any, index: number, metadata:
}
}

function setDescriptionMetadata(description: string, target: any, propertyKey: string = undefined, index: number = undefined) {
if (index >= 0) {
setArgumentMetadata(target, propertyKey, index, {
description: description,
});
} else if (propertyKey) {
if (getFieldMetadata(target, propertyKey) != null) {
createOrSetFieldTypeMetadata(target, {
name: propertyKey,
description: description,
});
} else if (getValueMetadata(target, propertyKey) != null) {
createOrSetValueTypeMetadata(target, {
name: propertyKey,
description: description,
});
} else {
createPropertyDescriptionMetadata(target, description, propertyKey);
}
} else {
if (Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, target.prototype)) {
createOrSetObjectTypeMetadata(target, {
description: description,
});
} else if (Reflect.hasMetadata(GQ_ENUM_METADATA_KEY, target.prototype)) {
createOrSetEnumTypeMetadata(target, {
description: description,
});
} else {
createDescriptionMetadata(target, description);
}
}
}

function setNonNullMetadata(target: any, propertyKey: string, index: number) {
if (index >= 0) {
setArgumentMetadata(target, propertyKey, index, {
isNonNull: true,
});
} else {
createOrSetFieldTypeMetadata(target, {
name: propertyKey,
isNonNull: true,
});
}
}

function setPaginationMetadata(target: any, propertyKey: string, methodDescriptor: TypedPropertyDescriptor<any>) {

createOrSetFieldTypeMetadata(target, {
name: propertyKey,
isPagination: true,
});

let originalMethod = methodDescriptor.value;

return {
value: async function (...args: any[]) {
let [data, count] = await originalMethod.apply(this, args);

let metadata: FieldTypeMetadata = Reflect.getMetadata(GQ_FIELDS_KEY, target)[0];
let indexMap: { [name: string]: number; } = {};
metadata.args.forEach((arg: ArgumentMetadata) => {
indexMap[arg.name] = arg.index;
});

let limit = args[indexMap['limit']];
let offset = args[indexMap['offset']];

return new PaginationResponse(count, data, new PageInfo(count, offset, limit));
},
};
}


export function EnumType() {
return function (target: any) {
createOrSetEnumTypeMetadata(target, {
Expand All @@ -238,21 +341,35 @@ export function EnumType() {
} as Function;
}

export function ObjectType() {
export function ObjectType(option?: ObjectTypeOption) {
return function (target: any) {
createOrSetObjectTypeMetadata(target, {
name: target.name,
isInput: false,
});

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target);
}
}
} as Function;
}

export function InputObjectType() {
export function InputObjectType(option?: InputObjectTypeOption) {
return function (target: any) {
createOrSetObjectTypeMetadata(target, {
name: target.name,
isInput: true,
});

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target);
}
}
} as Function;
}

Expand All @@ -262,6 +379,19 @@ export function Field(option?: FieldOption) {
name: propertyKey,
explicitType: option && option.type,
});

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target, propertyKey);
}

// nonNull
if (option.nonNull) {
setNonNullMetadata(target, propertyKey, 0);
}
}

} as Function;
}

Expand All @@ -276,16 +406,7 @@ export function Value(value?: any) {

export function NonNull() {
return function (target: any, propertyKey: any, index?: number) {
if (index >= 0) {
setArgumentMetadata(target, propertyKey, index, {
isNonNull: true,
});
} else {
createOrSetFieldTypeMetadata(target, {
name: propertyKey,
isNonNull: true,
});
}
setNonNullMetadata(target, propertyKey, index);
} as Function;
}

Expand All @@ -307,33 +428,12 @@ export function Before(middleware: Middleware) {
export function Pagination() {
return function (target: any, propertyKey: any, methodDescriptor: any) {

createOrSetFieldTypeMetadata(target, {
name: propertyKey,
isPagination: true,
});

let originalMethod = methodDescriptor.value;
setPaginationMetadata(target, propertyKey, methodDescriptor);

return {
value: async function (...args: any[]) {
let [data, count] = await originalMethod.apply(this, args);

let metadata: FieldTypeMetadata = Reflect.getMetadata(GQ_FIELDS_KEY, target)[0];
let indexMap: { [name: string]: number; } = {};
metadata.args.forEach((arg: ArgumentMetadata) => {
indexMap[arg.name] = arg.index;
});

let limit = args[indexMap['limit']];
let offset = args[indexMap['offset']];

return new PaginationResponse(count, data, new PageInfo(count, offset, limit));
},
};
} as Function;
}

export function List() {
export function List(option?: ListOption) {
return function (target: any, propertyKey: any, index?: number) {
if (index >= 0) {
setArgumentMetadata(target, propertyKey, index, {
Expand All @@ -345,6 +445,14 @@ export function List() {
isList: true,
});
}

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target, propertyKey, index);
}
}

} as Function;
}

Expand All @@ -370,7 +478,7 @@ export function Ctx() {
} as Function;
}

export function OrderBy(params?: {extraColumns: string[], shouldIgnoreSchemaFields?: boolean } | string[]) {
export function OrderBy(params?: { extraColumns: string[], shouldIgnoreSchemaFields?: boolean } | string[]) {
return function (target: any, propertyKey: any, index: number) {
setArgumentMetadata(target, propertyKey, index, {
name: 'orderBy',
Expand All @@ -381,41 +489,11 @@ export function OrderBy(params?: {extraColumns: string[], shouldIgnoreSchemaFiel

export function Description(body: string) {
return function (target: any, propertyKey?: any, index?: number) {
if (index >= 0) {
setArgumentMetadata(target, propertyKey, index, {
description: body,
});
} else if (propertyKey) {
if (getFieldMetadata(target, propertyKey) != null) {
createOrSetFieldTypeMetadata(target, {
name: propertyKey,
description: body,
});
} else if (getValueMetadata(target, propertyKey) != null) {
createOrSetValueTypeMetadata(target, {
name: propertyKey,
description: body,
});
} else {
createPropertyDescriptionMetadata(target, body, propertyKey);
}
} else {
if (Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, target.prototype)) {
createOrSetObjectTypeMetadata(target, {
description: body,
});
} else if (Reflect.hasMetadata(GQ_ENUM_METADATA_KEY, target.prototype)) {
createOrSetEnumTypeMetadata(target, {
description: body,
});
} else {
createDescriptionMetadata(target, body);
}
}
setDescriptionMetadata(body, target, propertyKey, index);
} as Function;
}

export function Query(option?: any) {
export function Query(option?: QueryOption) {
return function (target: any, propertyKey: any) {
if (Reflect.hasMetadata(GQ_QUERY_KEY, target)) {
let metadata = Reflect.getMetadata(GQ_QUERY_KEY, target);
Expand All @@ -424,10 +502,18 @@ export function Query(option?: any) {
} else {
Reflect.defineMetadata(GQ_QUERY_KEY, [propertyKey], target);
}

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target, propertyKey);
}
}

} as Function;
}

export function Mutation(option?: any) {
export function Mutation(option?: MutationOption) {
return function (target: any, propertyKey: any) {
if (Reflect.hasMetadata(GQ_MUTATION_KEY, target)) {
let metadata = Reflect.getMetadata(GQ_MUTATION_KEY, target);
Expand All @@ -436,12 +522,27 @@ export function Mutation(option?: any) {
} else {
Reflect.defineMetadata(GQ_MUTATION_KEY, [propertyKey], target);
}

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target, propertyKey);
}
}

} as Function;
}

export function Schema() {
export function Schema(option?: SchemaOption) {
return function (target: Function) {
Reflect.defineMetadata('gq_schema', {}, target);

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target);
}
}
} as Function;
}

Expand Down
6 changes: 4 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"outDir": "lib"
},
"exclude": [
"node_modules", "lib", "examples"
"node_modules",
"lib",
"examples"
]
}
}