@hazeljs/graphql 0.2.0-beta.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/README.md +120 -0
- package/dist/client/decorators.d.ts +44 -0
- package/dist/client/decorators.d.ts.map +1 -0
- package/dist/client/decorators.js +72 -0
- package/dist/client/graphql.client.d.ts +25 -0
- package/dist/client/graphql.client.d.ts.map +1 -0
- package/dist/client/graphql.client.js +47 -0
- package/dist/decorators/field.decorator.d.ts +23 -0
- package/dist/decorators/field.decorator.d.ts.map +1 -0
- package/dist/decorators/field.decorator.js +37 -0
- package/dist/decorators/object-type.decorator.d.ts +21 -0
- package/dist/decorators/object-type.decorator.d.ts.map +1 -0
- package/dist/decorators/object-type.decorator.js +34 -0
- package/dist/decorators/query-mutation.decorator.d.ts +25 -0
- package/dist/decorators/query-mutation.decorator.d.ts.map +1 -0
- package/dist/decorators/query-mutation.decorator.js +62 -0
- package/dist/decorators/resolver.decorator.d.ts +25 -0
- package/dist/decorators/resolver.decorator.d.ts.map +1 -0
- package/dist/decorators/resolver.decorator.js +35 -0
- package/dist/graphql.module.d.ts +31 -0
- package/dist/graphql.module.d.ts.map +1 -0
- package/dist/graphql.module.js +63 -0
- package/dist/graphql.server.d.ts +34 -0
- package/dist/graphql.server.d.ts.map +1 -0
- package/dist/graphql.server.js +74 -0
- package/dist/graphql.types.d.ts +36 -0
- package/dist/graphql.types.d.ts.map +1 -0
- package/dist/graphql.types.js +5 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/schema-builder.d.ts +9 -0
- package/dist/schema-builder.d.ts.map +1 -0
- package/dist/schema-builder.js +142 -0
- package/package.json +56 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ARG_METADATA_KEY = exports.MUTATION_METADATA_KEY = exports.QUERY_METADATA_KEY = void 0;
|
|
4
|
+
exports.Query = Query;
|
|
5
|
+
exports.Mutation = Mutation;
|
|
6
|
+
exports.Arg = Arg;
|
|
7
|
+
exports.getQueryMetadata = getQueryMetadata;
|
|
8
|
+
exports.getMutationMetadata = getMutationMetadata;
|
|
9
|
+
exports.getArgMetadata = getArgMetadata;
|
|
10
|
+
require("reflect-metadata");
|
|
11
|
+
exports.QUERY_METADATA_KEY = Symbol('graphql:query');
|
|
12
|
+
exports.MUTATION_METADATA_KEY = Symbol('graphql:mutation');
|
|
13
|
+
exports.ARG_METADATA_KEY = Symbol('graphql:arg');
|
|
14
|
+
/**
|
|
15
|
+
* Marks a method as a GraphQL Query
|
|
16
|
+
*/
|
|
17
|
+
function Query(nameOrOptions) {
|
|
18
|
+
return (target, propertyKey, _descriptor) => {
|
|
19
|
+
const meta = typeof nameOrOptions === 'string'
|
|
20
|
+
? { name: nameOrOptions }
|
|
21
|
+
: { name: String(propertyKey), ...nameOrOptions };
|
|
22
|
+
const existing = Reflect.getMetadata(exports.QUERY_METADATA_KEY, target.constructor) || [];
|
|
23
|
+
existing.push({ ...meta, name: meta.name || String(propertyKey), method: String(propertyKey) });
|
|
24
|
+
Reflect.defineMetadata(exports.QUERY_METADATA_KEY, existing, target.constructor);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Marks a method as a GraphQL Mutation
|
|
29
|
+
*/
|
|
30
|
+
function Mutation(nameOrOptions) {
|
|
31
|
+
return (target, propertyKey, _descriptor) => {
|
|
32
|
+
const meta = typeof nameOrOptions === 'string'
|
|
33
|
+
? { name: nameOrOptions }
|
|
34
|
+
: { name: String(propertyKey), ...nameOrOptions };
|
|
35
|
+
const existing = Reflect.getMetadata(exports.MUTATION_METADATA_KEY, target.constructor) || [];
|
|
36
|
+
existing.push({ ...meta, name: meta.name || String(propertyKey), method: String(propertyKey) });
|
|
37
|
+
Reflect.defineMetadata(exports.MUTATION_METADATA_KEY, existing, target.constructor);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Marks a parameter as a GraphQL argument
|
|
42
|
+
*/
|
|
43
|
+
function Arg(nameOrOptions, type) {
|
|
44
|
+
return (target, propertyKey, parameterIndex) => {
|
|
45
|
+
const meta = typeof nameOrOptions === 'string'
|
|
46
|
+
? { name: nameOrOptions, type }
|
|
47
|
+
: { name: nameOrOptions.name, type: nameOrOptions.type, ...nameOrOptions };
|
|
48
|
+
const key = propertyKey ?? '';
|
|
49
|
+
const existing = Reflect.getMetadata(exports.ARG_METADATA_KEY, target, key) || [];
|
|
50
|
+
existing[parameterIndex] = meta;
|
|
51
|
+
Reflect.defineMetadata(exports.ARG_METADATA_KEY, existing, target, key);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function getQueryMetadata(target) {
|
|
55
|
+
return Reflect.getMetadata(exports.QUERY_METADATA_KEY, target) || [];
|
|
56
|
+
}
|
|
57
|
+
function getMutationMetadata(target) {
|
|
58
|
+
return Reflect.getMetadata(exports.MUTATION_METADATA_KEY, target) || [];
|
|
59
|
+
}
|
|
60
|
+
function getArgMetadata(target, propertyKey) {
|
|
61
|
+
return Reflect.getMetadata(exports.ARG_METADATA_KEY, target, propertyKey) || [];
|
|
62
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import type { ResolverMetadata } from '../graphql.types';
|
|
3
|
+
export declare const RESOLVER_METADATA_KEY: unique symbol;
|
|
4
|
+
/**
|
|
5
|
+
* Marks a class as a GraphQL resolver (contains @Query and @Mutation handlers)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* @Resolver()
|
|
10
|
+
* class UserResolver {
|
|
11
|
+
* @Query()
|
|
12
|
+
* user(@Arg('id') id: string) {
|
|
13
|
+
* return { id, name: 'John' };
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* @Mutation()
|
|
17
|
+
* createUser(@Arg('name') name: string) {
|
|
18
|
+
* return { id: '1', name };
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function Resolver(name?: string): ClassDecorator;
|
|
24
|
+
export declare function getResolverMetadata(target: object): ResolverMetadata | undefined;
|
|
25
|
+
//# sourceMappingURL=resolver.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/resolver.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,eAAO,MAAM,qBAAqB,eAA6B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAKtD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEhF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESOLVER_METADATA_KEY = void 0;
|
|
4
|
+
exports.Resolver = Resolver;
|
|
5
|
+
exports.getResolverMetadata = getResolverMetadata;
|
|
6
|
+
require("reflect-metadata");
|
|
7
|
+
exports.RESOLVER_METADATA_KEY = Symbol('graphql:resolver');
|
|
8
|
+
/**
|
|
9
|
+
* Marks a class as a GraphQL resolver (contains @Query and @Mutation handlers)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* @Resolver()
|
|
14
|
+
* class UserResolver {
|
|
15
|
+
* @Query()
|
|
16
|
+
* user(@Arg('id') id: string) {
|
|
17
|
+
* return { id, name: 'John' };
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* @Mutation()
|
|
21
|
+
* createUser(@Arg('name') name: string) {
|
|
22
|
+
* return { id: '1', name };
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function Resolver(name) {
|
|
28
|
+
return (target) => {
|
|
29
|
+
const meta = name ? { name } : {};
|
|
30
|
+
Reflect.defineMetadata(exports.RESOLVER_METADATA_KEY, meta, target);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function getResolverMetadata(target) {
|
|
34
|
+
return Reflect.getMetadata(exports.RESOLVER_METADATA_KEY, target);
|
|
35
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { GraphQLServer } from './graphql.server';
|
|
2
|
+
import type { GraphQLModuleConfig } from './graphql.types';
|
|
3
|
+
import type { Type } from '@hazeljs/core';
|
|
4
|
+
/**
|
|
5
|
+
* GraphQL module for HazelJS
|
|
6
|
+
* Decorator-based schema with @Resolver, @Query, @Mutation, @ObjectType, @Field
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* @HazelModule({
|
|
11
|
+
* imports: [
|
|
12
|
+
* GraphQLModule.forRoot({
|
|
13
|
+
* path: '/graphql',
|
|
14
|
+
* resolvers: [UserResolver, PostResolver],
|
|
15
|
+
* })
|
|
16
|
+
* ],
|
|
17
|
+
* })
|
|
18
|
+
* export class AppModule {}
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class GraphQLModule {
|
|
22
|
+
static forRoot(options: GraphQLModuleConfig & {
|
|
23
|
+
resolvers: Type<object>[];
|
|
24
|
+
}): {
|
|
25
|
+
module: typeof GraphQLModule;
|
|
26
|
+
providers: unknown[];
|
|
27
|
+
exports: Array<typeof GraphQLServer>;
|
|
28
|
+
global: boolean;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=graphql.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.module.d.ts","sourceRoot":"","sources":["../src/graphql.module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAQ1C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG;QAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;KAAE,GAAG;QAC5E,MAAM,EAAE,OAAO,aAAa,CAAC;QAC7B,SAAS,EAAE,OAAO,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;QACrC,MAAM,EAAE,OAAO,CAAC;KACjB;CAuBF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.GraphQLModule = void 0;
|
|
13
|
+
const core_1 = require("@hazeljs/core");
|
|
14
|
+
const graphql_server_1 = require("./graphql.server");
|
|
15
|
+
/** Eagerly resolves GraphQLServer so the early handler gets registered */
|
|
16
|
+
let GraphQLBootstrap = class GraphQLBootstrap {
|
|
17
|
+
constructor(_server) { }
|
|
18
|
+
};
|
|
19
|
+
GraphQLBootstrap = __decorate([
|
|
20
|
+
(0, core_1.Injectable)(),
|
|
21
|
+
__metadata("design:paramtypes", [graphql_server_1.GraphQLServer])
|
|
22
|
+
], GraphQLBootstrap);
|
|
23
|
+
/**
|
|
24
|
+
* GraphQL module for HazelJS
|
|
25
|
+
* Decorator-based schema with @Resolver, @Query, @Mutation, @ObjectType, @Field
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* @HazelModule({
|
|
30
|
+
* imports: [
|
|
31
|
+
* GraphQLModule.forRoot({
|
|
32
|
+
* path: '/graphql',
|
|
33
|
+
* resolvers: [UserResolver, PostResolver],
|
|
34
|
+
* })
|
|
35
|
+
* ],
|
|
36
|
+
* })
|
|
37
|
+
* export class AppModule {}
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
class GraphQLModule {
|
|
41
|
+
static forRoot(options) {
|
|
42
|
+
const { resolvers, ...config } = options;
|
|
43
|
+
const graphqlProvider = {
|
|
44
|
+
provide: graphql_server_1.GraphQLServer,
|
|
45
|
+
useFactory: () => {
|
|
46
|
+
const container = core_1.Container.getInstance();
|
|
47
|
+
const hazelApp = container.resolve(core_1.HazelApp);
|
|
48
|
+
const server = new graphql_server_1.GraphQLServer(resolvers, container);
|
|
49
|
+
server.configure(config);
|
|
50
|
+
hazelApp.addEarlyHandler(server.getPath(), server.getHandler());
|
|
51
|
+
return server;
|
|
52
|
+
},
|
|
53
|
+
inject: [],
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
module: GraphQLModule,
|
|
57
|
+
providers: [graphqlProvider, GraphQLBootstrap],
|
|
58
|
+
exports: [graphql_server_1.GraphQLServer],
|
|
59
|
+
global: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.GraphQLModule = GraphQLModule;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import { GraphQLSchema } from 'graphql';
|
|
3
|
+
import { Container } from '@hazeljs/core';
|
|
4
|
+
import type { GraphQLModuleConfig } from './graphql.types';
|
|
5
|
+
/**
|
|
6
|
+
* GraphQL Server - builds schema from decorators and serves via graphql-http
|
|
7
|
+
*/
|
|
8
|
+
export declare class GraphQLServer {
|
|
9
|
+
private readonly resolvers;
|
|
10
|
+
private readonly container;
|
|
11
|
+
private schema;
|
|
12
|
+
private handler;
|
|
13
|
+
private path;
|
|
14
|
+
private config;
|
|
15
|
+
constructor(resolvers: (new (...args: unknown[]) => object)[], container: Container);
|
|
16
|
+
configure(config: GraphQLModuleConfig): void;
|
|
17
|
+
/**
|
|
18
|
+
* Build schema and create the HTTP handler
|
|
19
|
+
*/
|
|
20
|
+
build(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get the path where GraphQL is served
|
|
23
|
+
*/
|
|
24
|
+
getPath(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Handle incoming GraphQL request (call this for req.url matching path)
|
|
27
|
+
*/
|
|
28
|
+
getHandler(): (req: IncomingMessage, res: ServerResponse) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Get the built schema
|
|
31
|
+
*/
|
|
32
|
+
getSchema(): GraphQLSchema | null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=graphql.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.server.d.ts","sourceRoot":"","sources":["../src/graphql.server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,qBACa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP5B,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,OAAO,CAAsE;IACrF,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,MAAM,CAA2B;gBAGtB,SAAS,EAAE,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,EAAE,EACjD,SAAS,EAAE,SAAS;IAGvC,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAM5C;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,UAAU,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI;IAKjE;;OAEG;IACH,SAAS,IAAI,aAAa,GAAG,IAAI;CAGlC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GraphQLServer = void 0;
|
|
16
|
+
const core_1 = require("@hazeljs/core");
|
|
17
|
+
const http_1 = require("graphql-http/lib/use/http");
|
|
18
|
+
const core_2 = require("@hazeljs/core");
|
|
19
|
+
const core_3 = __importDefault(require("@hazeljs/core"));
|
|
20
|
+
const schema_builder_1 = require("./schema-builder");
|
|
21
|
+
/**
|
|
22
|
+
* GraphQL Server - builds schema from decorators and serves via graphql-http
|
|
23
|
+
*/
|
|
24
|
+
let GraphQLServer = class GraphQLServer {
|
|
25
|
+
constructor(resolvers, container) {
|
|
26
|
+
this.resolvers = resolvers;
|
|
27
|
+
this.container = container;
|
|
28
|
+
this.schema = null;
|
|
29
|
+
this.handler = null;
|
|
30
|
+
this.path = '/graphql';
|
|
31
|
+
this.config = {};
|
|
32
|
+
}
|
|
33
|
+
configure(config) {
|
|
34
|
+
this.config = config;
|
|
35
|
+
this.path = config.path ?? '/graphql';
|
|
36
|
+
core_3.default.info('GraphQL server configured', { path: this.path });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build schema and create the HTTP handler
|
|
40
|
+
*/
|
|
41
|
+
build() {
|
|
42
|
+
const builder = new schema_builder_1.SchemaBuilder();
|
|
43
|
+
this.schema = builder.buildSchema(this.resolvers, this.container);
|
|
44
|
+
this.handler = (0, http_1.createHandler)({
|
|
45
|
+
schema: this.schema,
|
|
46
|
+
});
|
|
47
|
+
core_3.default.info('GraphQL schema built from resolvers');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the path where GraphQL is served
|
|
51
|
+
*/
|
|
52
|
+
getPath() {
|
|
53
|
+
return this.path;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Handle incoming GraphQL request (call this for req.url matching path)
|
|
57
|
+
*/
|
|
58
|
+
getHandler() {
|
|
59
|
+
if (!this.handler)
|
|
60
|
+
this.build();
|
|
61
|
+
return this.handler;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the built schema
|
|
65
|
+
*/
|
|
66
|
+
getSchema() {
|
|
67
|
+
return this.schema;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
exports.GraphQLServer = GraphQLServer;
|
|
71
|
+
exports.GraphQLServer = GraphQLServer = __decorate([
|
|
72
|
+
(0, core_1.Injectable)(),
|
|
73
|
+
__metadata("design:paramtypes", [Array, core_2.Container])
|
|
74
|
+
], GraphQLServer);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for @hazeljs/graphql
|
|
3
|
+
*/
|
|
4
|
+
export interface GraphQLModuleConfig {
|
|
5
|
+
path?: string;
|
|
6
|
+
playground?: boolean;
|
|
7
|
+
introspection?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ObjectTypeMetadata {
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface FieldMetadata {
|
|
14
|
+
name: string;
|
|
15
|
+
type: unknown;
|
|
16
|
+
description?: string;
|
|
17
|
+
nullable?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ResolverMetadata {
|
|
20
|
+
name?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface QueryMetadata {
|
|
23
|
+
name?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface MutationMetadata {
|
|
27
|
+
name?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ArgMetadata {
|
|
31
|
+
name: string;
|
|
32
|
+
type: unknown;
|
|
33
|
+
description?: string;
|
|
34
|
+
nullable?: boolean;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=graphql.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.types.d.ts","sourceRoot":"","sources":["../src/graphql.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hazeljs/graphql - GraphQL server and client for HazelJS
|
|
3
|
+
*
|
|
4
|
+
* Server: decorator-based schema with @Resolver, @Query, @Mutation, @ObjectType, @Field
|
|
5
|
+
* Client: typed GraphQLClient for queries and mutations
|
|
6
|
+
*/
|
|
7
|
+
export { GraphQLModule } from './graphql.module';
|
|
8
|
+
export { GraphQLServer } from './graphql.server';
|
|
9
|
+
export { ObjectType, getObjectTypeMetadata } from './decorators/object-type.decorator';
|
|
10
|
+
export { Field, getFieldMetadata } from './decorators/field.decorator';
|
|
11
|
+
export { Resolver, getResolverMetadata } from './decorators/resolver.decorator';
|
|
12
|
+
export { Query, Mutation, Arg, getQueryMetadata, getMutationMetadata, getArgMetadata, } from './decorators/query-mutation.decorator';
|
|
13
|
+
export { GraphQLClient } from './client/graphql.client';
|
|
14
|
+
export { GraphQLQuery, GraphQLMutation, GraphQLClientClass, getGraphQLClientConfig, } from './client/decorators';
|
|
15
|
+
export type { GraphQLModuleConfig, ObjectTypeMetadata, FieldMetadata, ResolverMetadata, QueryMetadata, MutationMetadata, ArgMetadata, } from './graphql.types';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EACL,KAAK,EACL,QAAQ,EACR,GAAG,EACH,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @hazeljs/graphql - GraphQL server and client for HazelJS
|
|
4
|
+
*
|
|
5
|
+
* Server: decorator-based schema with @Resolver, @Query, @Mutation, @ObjectType, @Field
|
|
6
|
+
* Client: typed GraphQLClient for queries and mutations
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getGraphQLClientConfig = exports.GraphQLClientClass = exports.GraphQLMutation = exports.GraphQLQuery = exports.GraphQLClient = exports.getArgMetadata = exports.getMutationMetadata = exports.getQueryMetadata = exports.Arg = exports.Mutation = exports.Query = exports.getResolverMetadata = exports.Resolver = exports.getFieldMetadata = exports.Field = exports.getObjectTypeMetadata = exports.ObjectType = exports.GraphQLServer = exports.GraphQLModule = void 0;
|
|
10
|
+
// Module & Server
|
|
11
|
+
var graphql_module_1 = require("./graphql.module");
|
|
12
|
+
Object.defineProperty(exports, "GraphQLModule", { enumerable: true, get: function () { return graphql_module_1.GraphQLModule; } });
|
|
13
|
+
var graphql_server_1 = require("./graphql.server");
|
|
14
|
+
Object.defineProperty(exports, "GraphQLServer", { enumerable: true, get: function () { return graphql_server_1.GraphQLServer; } });
|
|
15
|
+
// Server decorators
|
|
16
|
+
var object_type_decorator_1 = require("./decorators/object-type.decorator");
|
|
17
|
+
Object.defineProperty(exports, "ObjectType", { enumerable: true, get: function () { return object_type_decorator_1.ObjectType; } });
|
|
18
|
+
Object.defineProperty(exports, "getObjectTypeMetadata", { enumerable: true, get: function () { return object_type_decorator_1.getObjectTypeMetadata; } });
|
|
19
|
+
var field_decorator_1 = require("./decorators/field.decorator");
|
|
20
|
+
Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return field_decorator_1.Field; } });
|
|
21
|
+
Object.defineProperty(exports, "getFieldMetadata", { enumerable: true, get: function () { return field_decorator_1.getFieldMetadata; } });
|
|
22
|
+
var resolver_decorator_1 = require("./decorators/resolver.decorator");
|
|
23
|
+
Object.defineProperty(exports, "Resolver", { enumerable: true, get: function () { return resolver_decorator_1.Resolver; } });
|
|
24
|
+
Object.defineProperty(exports, "getResolverMetadata", { enumerable: true, get: function () { return resolver_decorator_1.getResolverMetadata; } });
|
|
25
|
+
var query_mutation_decorator_1 = require("./decorators/query-mutation.decorator");
|
|
26
|
+
Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return query_mutation_decorator_1.Query; } });
|
|
27
|
+
Object.defineProperty(exports, "Mutation", { enumerable: true, get: function () { return query_mutation_decorator_1.Mutation; } });
|
|
28
|
+
Object.defineProperty(exports, "Arg", { enumerable: true, get: function () { return query_mutation_decorator_1.Arg; } });
|
|
29
|
+
Object.defineProperty(exports, "getQueryMetadata", { enumerable: true, get: function () { return query_mutation_decorator_1.getQueryMetadata; } });
|
|
30
|
+
Object.defineProperty(exports, "getMutationMetadata", { enumerable: true, get: function () { return query_mutation_decorator_1.getMutationMetadata; } });
|
|
31
|
+
Object.defineProperty(exports, "getArgMetadata", { enumerable: true, get: function () { return query_mutation_decorator_1.getArgMetadata; } });
|
|
32
|
+
// Client
|
|
33
|
+
var graphql_client_1 = require("./client/graphql.client");
|
|
34
|
+
Object.defineProperty(exports, "GraphQLClient", { enumerable: true, get: function () { return graphql_client_1.GraphQLClient; } });
|
|
35
|
+
var decorators_1 = require("./client/decorators");
|
|
36
|
+
Object.defineProperty(exports, "GraphQLQuery", { enumerable: true, get: function () { return decorators_1.GraphQLQuery; } });
|
|
37
|
+
Object.defineProperty(exports, "GraphQLMutation", { enumerable: true, get: function () { return decorators_1.GraphQLMutation; } });
|
|
38
|
+
Object.defineProperty(exports, "GraphQLClientClass", { enumerable: true, get: function () { return decorators_1.GraphQLClientClass; } });
|
|
39
|
+
Object.defineProperty(exports, "getGraphQLClientConfig", { enumerable: true, get: function () { return decorators_1.getGraphQLClientConfig; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphQLSchema } from 'graphql';
|
|
2
|
+
import { Container } from '@hazeljs/core';
|
|
3
|
+
export declare class SchemaBuilder {
|
|
4
|
+
private objectTypeCache;
|
|
5
|
+
buildSchema(resolvers: (new (...args: unknown[]) => object)[], container: Container): GraphQLSchema;
|
|
6
|
+
private inferType;
|
|
7
|
+
private buildObjectType;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=schema-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-builder.d.ts","sourceRoot":"","sources":["../src/schema-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAUd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAsB1C,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAAwC;IAE/D,WAAW,CACT,SAAS,EAAE,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,EAAE,EACjD,SAAS,EAAE,SAAS,GACnB,aAAa;IAwFhB,OAAO,CAAC,SAAS;IA6BjB,OAAO,CAAC,eAAe;CAuBxB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SchemaBuilder = void 0;
|
|
7
|
+
const graphql_1 = require("graphql");
|
|
8
|
+
const core_1 = __importDefault(require("@hazeljs/core"));
|
|
9
|
+
const object_type_decorator_1 = require("./decorators/object-type.decorator");
|
|
10
|
+
const field_decorator_1 = require("./decorators/field.decorator");
|
|
11
|
+
const query_mutation_decorator_1 = require("./decorators/query-mutation.decorator");
|
|
12
|
+
const resolver_decorator_1 = require("./decorators/resolver.decorator");
|
|
13
|
+
const SCALAR_MAP = {
|
|
14
|
+
String: graphql_1.GraphQLString,
|
|
15
|
+
Number: graphql_1.GraphQLFloat,
|
|
16
|
+
number: graphql_1.GraphQLFloat,
|
|
17
|
+
Boolean: graphql_1.GraphQLBoolean,
|
|
18
|
+
boolean: graphql_1.GraphQLBoolean,
|
|
19
|
+
Int: graphql_1.GraphQLInt,
|
|
20
|
+
Float: graphql_1.GraphQLFloat,
|
|
21
|
+
ID: graphql_1.GraphQLID,
|
|
22
|
+
};
|
|
23
|
+
class SchemaBuilder {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.objectTypeCache = new Map();
|
|
26
|
+
}
|
|
27
|
+
buildSchema(resolvers, container) {
|
|
28
|
+
const queryFields = {};
|
|
29
|
+
const mutationFields = {};
|
|
30
|
+
for (const ResolverClass of resolvers) {
|
|
31
|
+
void (0, resolver_decorator_1.getResolverMetadata)(ResolverClass);
|
|
32
|
+
const instance = container.resolve(ResolverClass);
|
|
33
|
+
const queries = (0, query_mutation_decorator_1.getQueryMetadata)(ResolverClass);
|
|
34
|
+
for (const q of queries) {
|
|
35
|
+
const args = {};
|
|
36
|
+
const argMeta = (0, query_mutation_decorator_1.getArgMetadata)(ResolverClass.prototype, q.method);
|
|
37
|
+
for (const a of argMeta.filter(Boolean)) {
|
|
38
|
+
args[a.name] = { type: this.inferType(a.type) };
|
|
39
|
+
}
|
|
40
|
+
queryFields[q.name] = {
|
|
41
|
+
type: this.inferType(undefined),
|
|
42
|
+
args,
|
|
43
|
+
resolve: (_, args) => {
|
|
44
|
+
const method = instance[q.method];
|
|
45
|
+
if (typeof method !== 'function') {
|
|
46
|
+
core_1.default.warn(`Query handler ${q.method} not found on ${ResolverClass.name}`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const orderedArgs = argMeta.map((a) => (a ? args[a.name] : undefined));
|
|
50
|
+
return method.apply(instance, orderedArgs);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const mutations = (0, query_mutation_decorator_1.getMutationMetadata)(ResolverClass);
|
|
55
|
+
for (const m of mutations) {
|
|
56
|
+
const args = {};
|
|
57
|
+
const argMeta = (0, query_mutation_decorator_1.getArgMetadata)(ResolverClass.prototype, m.method);
|
|
58
|
+
for (const a of argMeta.filter(Boolean)) {
|
|
59
|
+
args[a.name] = { type: this.inferType(a.type) };
|
|
60
|
+
}
|
|
61
|
+
mutationFields[m.name] = {
|
|
62
|
+
type: this.inferType(undefined),
|
|
63
|
+
args,
|
|
64
|
+
resolve: (_, args) => {
|
|
65
|
+
const method = instance[m.method];
|
|
66
|
+
if (typeof method !== 'function') {
|
|
67
|
+
core_1.default.warn(`Mutation handler ${m.method} not found on ${ResolverClass.name}`);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const orderedArgs = argMeta.map((a) => (a ? args[a.name] : undefined));
|
|
71
|
+
return method.apply(instance, orderedArgs);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const queryType = new graphql_1.GraphQLObjectType({
|
|
77
|
+
name: 'Query',
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
79
|
+
fields: () => queryFields,
|
|
80
|
+
});
|
|
81
|
+
const mutationType = Object.keys(mutationFields).length > 0
|
|
82
|
+
? new graphql_1.GraphQLObjectType({
|
|
83
|
+
name: 'Mutation',
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
85
|
+
fields: () => mutationFields,
|
|
86
|
+
})
|
|
87
|
+
: undefined;
|
|
88
|
+
return new graphql_1.GraphQLSchema({
|
|
89
|
+
query: queryType,
|
|
90
|
+
...(mutationType && { mutation: mutationType }),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
inferType(tsType, nullable = true) {
|
|
94
|
+
if (tsType === undefined || tsType === null)
|
|
95
|
+
return graphql_1.GraphQLString;
|
|
96
|
+
const type = tsType;
|
|
97
|
+
const name = type?.name || String(tsType);
|
|
98
|
+
if (name.endsWith('[]') || name === 'Array') {
|
|
99
|
+
const inner = this.inferType({ name: name.replace('[]', '') });
|
|
100
|
+
return nullable
|
|
101
|
+
? new graphql_1.GraphQLList(inner)
|
|
102
|
+
: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(inner));
|
|
103
|
+
}
|
|
104
|
+
const scalar = SCALAR_MAP[name];
|
|
105
|
+
if (scalar)
|
|
106
|
+
return nullable ? scalar : new graphql_1.GraphQLNonNull(scalar);
|
|
107
|
+
const objMeta = type?.prototype && (0, object_type_decorator_1.getObjectTypeMetadata)(type.prototype);
|
|
108
|
+
if (objMeta) {
|
|
109
|
+
let objType = this.objectTypeCache.get(type.prototype);
|
|
110
|
+
if (!objType) {
|
|
111
|
+
objType = this.buildObjectType(type);
|
|
112
|
+
this.objectTypeCache.set(type.prototype, objType);
|
|
113
|
+
}
|
|
114
|
+
return nullable ? objType : new graphql_1.GraphQLNonNull(objType);
|
|
115
|
+
}
|
|
116
|
+
return graphql_1.GraphQLString;
|
|
117
|
+
}
|
|
118
|
+
buildObjectType(cls) {
|
|
119
|
+
const meta = (0, object_type_decorator_1.getObjectTypeMetadata)(cls.prototype) || { name: cls.name };
|
|
120
|
+
const fieldsMeta = (0, field_decorator_1.getFieldMetadata)(cls.prototype) || [];
|
|
121
|
+
const fields = {};
|
|
122
|
+
for (const f of fieldsMeta) {
|
|
123
|
+
if (!f)
|
|
124
|
+
continue;
|
|
125
|
+
fields[f.name] = {
|
|
126
|
+
type: this.inferType(f.type),
|
|
127
|
+
resolve: (source) => {
|
|
128
|
+
const val = source?.[f.name];
|
|
129
|
+
if (typeof val === 'function')
|
|
130
|
+
return val.call(source);
|
|
131
|
+
return val;
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return new graphql_1.GraphQLObjectType({
|
|
136
|
+
name: meta.name,
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
138
|
+
fields: () => fields,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.SchemaBuilder = SchemaBuilder;
|