Skip to content

Commit 5bc522e

Browse files
committed
Initial commit for @interface decorator
1 parent 27a31cd commit 5bc522e

21 files changed

+259
-12
lines changed

src/array.utils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Concats two arrays
3+
* @param itemsA fist array argument
4+
* @param itemsB second array argument
5+
*/
6+
export const concat = (itemsA: any[], itemsB: any[]) => itemsA.concat(itemsB);
7+
8+
/**
9+
* Executes a flatMap modifier function to each elements of the array
10+
* @param λ the flatMap function
11+
* @param collection the array to apply the flatMap funtion to
12+
*/
13+
export const flatMap = (λ: (item: any) => any, collection: any[]) => collection.map(λ).reduce(concat, []);
14+
15+
/**
16+
* Flattens an array with nested arrays
17+
* @param collection the array argument
18+
*/
19+
export const flatten = (collection: any[]) => flatMap(items => {
20+
if (items.constructor === Array) {
21+
return flatMap(item => item, items);
22+
} else {
23+
return items;
24+
}
25+
}, collection);

src/decorator/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './context.decorator';
88
export * from './field.decorator';
99
export * from './order-by.decorator';
1010
export * from './before.decorator';
11+
export * from './interface-type.decorator';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { getMetadataArgsStorage } from '../metadata-builder';
2+
import { InterfaceOption } from '../index';
3+
4+
/**
5+
* Union Type.
6+
* See [GraphQL Documentation - Union Types]{@link http://graphql.org/learn/schema/#union-types}
7+
*
8+
* @param option Options for an Union Type
9+
*/
10+
export function InterfaceType<T>(option: InterfaceOption<T>) {
11+
return function (target: any) {
12+
getMetadataArgsStorage().interfaces.push({
13+
target: target,
14+
name: target.name,
15+
resolver: option.resolver,
16+
description: option.description,
17+
});
18+
} as Function;
19+
}

src/decorator/object-type.decorator.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { SchemaFactoryError, SchemaFactoryErrorType } from '../type-factory';
2+
13
import { ObjectOption } from '../metadata/options';
24
import { getMetadataArgsStorage } from '../metadata-builder';
35

@@ -23,11 +25,20 @@ export function InputObjectType(option?: ObjectOption) {
2325

2426
function CreateObjectType(isInput: boolean, option?: ObjectOption) {
2527
return function (target: any) {
28+
29+
if (isInput && option && option.interfaces) {
30+
throw new SchemaFactoryError(`Input types are not allowed to have interfaces: '${target.name}'`,
31+
SchemaFactoryErrorType.INPUT_FIELD_SHOULD_NOT_HAVE_INTERFACE);
32+
}
33+
2634
getMetadataArgsStorage().objects.push({
2735
target: target,
2836
name: target.name,
2937
description: option ? option.description : null,
3038
isInput: isInput,
39+
interfaces: option && option.interfaces ? (
40+
option.interfaces.constructor !== Array ? [option.interfaces as Function] : option.interfaces as Function[]
41+
) : [],
3142
});
3243
};
3344
}

src/metadata-builder/metadata-args.storage.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
RootArg,
1313
SchemaArg,
1414
UnionTypeArg,
15+
InterfaceTypeArg,
1516
} from '../metadata/args';
1617

1718
import { MetadataUtils } from './metadata.utils';
@@ -29,6 +30,7 @@ export class MetadataArgsStorage {
2930
roots: RootArg[] = [];
3031
orderBys: OrderByArg[] = [];
3132
befores: BeforeArg[] = [];
33+
interfaces: InterfaceTypeArg[] = [];
3234

3335
filterEnumsByClass(target: any): EnumTypeArg[] {
3436
return this.enums.filter(item => item.target === target);
@@ -42,6 +44,10 @@ export class MetadataArgsStorage {
4244
return this.union.filter(item => item.target === target);
4345
}
4446

47+
filterInterfaceTypeByClass(target: any): InterfaceTypeArg[] {
48+
return this.interfaces.filter(item => item.target === target);
49+
}
50+
4551
filterObjectTypeByClass(target: any): ObjectTypeArg[] {
4652
return this.objects.filter(item => item.target === target);
4753
}

src/metadata-builder/metadata.builder.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
RootMetadata,
1212
SchemaMetadata,
1313
UnionTypeMetadata,
14+
InterfaceTypeMetadata,
1415
} from '../metadata/types';
1516

1617
import { EntryType } from '../metadata/args';
@@ -41,6 +42,17 @@ export class MetadataBuilder {
4142
}));
4243
}
4344

45+
buildInterfaceTypeMetadata(target: any): InterfaceTypeMetadata[] | undefined {
46+
return getMetadataArgsStorage()
47+
.filterInterfaceTypeByClass(target)
48+
.map(arg => ({
49+
target: arg.target,
50+
name: arg.name,
51+
resolver: arg.resolver,
52+
description: arg.description,
53+
}));
54+
}
55+
4456
buildObjectTypeMetadata(target: any): ObjectTypeMetadata[] | undefined {
4557
return getMetadataArgsStorage()
4658
.filterObjectTypeByClass(target)
@@ -49,6 +61,7 @@ export class MetadataBuilder {
4961
name: arg.name,
5062
description: arg.description,
5163
isInput: arg.isInput,
64+
interfaces: Array.prototype.concat.apply([], arg.interfaces.map(this.buildInterfaceTypeMetadata)),
5265
}));
5366
}
5467

src/metadata/args/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export * from './context.arg';
99
export * from './root.arg';
1010
export * from './order-by.arg';
1111
export * from './before.arg';
12+
export * from './interface-type.arg';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Argument } from './argument';
2+
3+
export interface InterfaceTypeArg extends Argument {
4+
resolver: (obj: any, context: any, info: any) => Promise<string> | string | null;
5+
}

src/metadata/args/object-type.arg.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ import { Argument } from './argument';
22

33
export interface ObjectTypeArg extends Argument {
44
isInput: boolean;
5+
interfaces: Function[];
56
}

src/metadata/options/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './field.option';
77
export * from './argument.option';
88
export * from './order-by.option';
99
export * from './before.option';
10+
export * from './interface.option';

0 commit comments

Comments
 (0)