@hazeljs/graphql 0.2.0-beta.54 → 0.2.0-beta.56

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.
Files changed (28) hide show
  1. package/dist/client/decorators.test.d.ts +2 -0
  2. package/dist/client/decorators.test.d.ts.map +1 -0
  3. package/dist/client/decorators.test.js +102 -0
  4. package/dist/client/graphql.client.test.d.ts +2 -0
  5. package/dist/client/graphql.client.test.d.ts.map +1 -0
  6. package/dist/client/graphql.client.test.js +79 -0
  7. package/dist/decorators/field.decorator.test.d.ts +2 -0
  8. package/dist/decorators/field.decorator.test.d.ts.map +1 -0
  9. package/dist/decorators/field.decorator.test.js +67 -0
  10. package/dist/decorators/object-type.decorator.test.d.ts +2 -0
  11. package/dist/decorators/object-type.decorator.test.d.ts.map +1 -0
  12. package/dist/decorators/object-type.decorator.test.js +45 -0
  13. package/dist/decorators/query-mutation.decorator.test.d.ts +2 -0
  14. package/dist/decorators/query-mutation.decorator.test.d.ts.map +1 -0
  15. package/dist/decorators/query-mutation.decorator.test.js +176 -0
  16. package/dist/decorators/resolver.decorator.test.d.ts +2 -0
  17. package/dist/decorators/resolver.decorator.test.d.ts.map +1 -0
  18. package/dist/decorators/resolver.decorator.test.js +36 -0
  19. package/dist/graphql.module.test.d.ts +2 -0
  20. package/dist/graphql.module.test.d.ts.map +1 -0
  21. package/dist/graphql.module.test.js +85 -0
  22. package/dist/graphql.server.test.d.ts +2 -0
  23. package/dist/graphql.server.test.d.ts.map +1 -0
  24. package/dist/graphql.server.test.js +79 -0
  25. package/dist/schema-builder.test.d.ts +2 -0
  26. package/dist/schema-builder.test.d.ts.map +1 -0
  27. package/dist/schema-builder.test.js +182 -0
  28. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=decorators.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.test.d.ts","sourceRoot":"","sources":["../../src/client/decorators.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,102 @@
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
+ require("reflect-metadata");
13
+ const decorators_1 = require("./decorators");
14
+ describe('GraphQL client decorators', () => {
15
+ describe('GraphQLQuery', () => {
16
+ it('should apply without error', () => {
17
+ class TestClient {
18
+ getUsers() {
19
+ return 'query { users { id } }';
20
+ }
21
+ }
22
+ __decorate([
23
+ (0, decorators_1.GraphQLQuery)(),
24
+ __metadata("design:type", Function),
25
+ __metadata("design:paramtypes", []),
26
+ __metadata("design:returntype", void 0)
27
+ ], TestClient.prototype, "getUsers", null);
28
+ expect(new TestClient().getUsers()).toBe('query { users { id } }');
29
+ });
30
+ it('should support multiple methods', () => {
31
+ class TestClient {
32
+ one() {
33
+ return 'query { one }';
34
+ }
35
+ two() {
36
+ return 'query { two }';
37
+ }
38
+ }
39
+ __decorate([
40
+ (0, decorators_1.GraphQLQuery)(),
41
+ __metadata("design:type", Function),
42
+ __metadata("design:paramtypes", []),
43
+ __metadata("design:returntype", void 0)
44
+ ], TestClient.prototype, "one", null);
45
+ __decorate([
46
+ (0, decorators_1.GraphQLQuery)(),
47
+ __metadata("design:type", Function),
48
+ __metadata("design:paramtypes", []),
49
+ __metadata("design:returntype", void 0)
50
+ ], TestClient.prototype, "two", null);
51
+ const client = new TestClient();
52
+ expect(client.one()).toBe('query { one }');
53
+ expect(client.two()).toBe('query { two }');
54
+ });
55
+ });
56
+ describe('GraphQLMutation', () => {
57
+ it('should apply without error', () => {
58
+ class TestClient {
59
+ createUser() {
60
+ return 'mutation { createUser { id } }';
61
+ }
62
+ }
63
+ __decorate([
64
+ (0, decorators_1.GraphQLMutation)(),
65
+ __metadata("design:type", Function),
66
+ __metadata("design:paramtypes", []),
67
+ __metadata("design:returntype", void 0)
68
+ ], TestClient.prototype, "createUser", null);
69
+ expect(new TestClient().createUser()).toBe('mutation { createUser { id } }');
70
+ });
71
+ });
72
+ describe('GraphQLClientClass', () => {
73
+ it('should store url in metadata', () => {
74
+ let TestClient = class TestClient {
75
+ };
76
+ TestClient = __decorate([
77
+ (0, decorators_1.GraphQLClientClass)('http://localhost:3000/graphql')
78
+ ], TestClient);
79
+ const config = (0, decorators_1.getGraphQLClientConfig)(TestClient);
80
+ expect(config.url).toBe('http://localhost:3000/graphql');
81
+ expect(config.headers).toEqual({});
82
+ });
83
+ it('should store url and headers in metadata', () => {
84
+ let TestClient = class TestClient {
85
+ };
86
+ TestClient = __decorate([
87
+ (0, decorators_1.GraphQLClientClass)('http://api.example.com/gql', { Authorization: 'Bearer x' })
88
+ ], TestClient);
89
+ const config = (0, decorators_1.getGraphQLClientConfig)(TestClient);
90
+ expect(config.url).toBe('http://api.example.com/gql');
91
+ expect(config.headers).toEqual({ Authorization: 'Bearer x' });
92
+ });
93
+ });
94
+ describe('getGraphQLClientConfig', () => {
95
+ it('should return defaults for class without decorator', () => {
96
+ class Plain {
97
+ }
98
+ const config = (0, decorators_1.getGraphQLClientConfig)(Plain);
99
+ expect(config).toEqual({ url: '', headers: {} });
100
+ });
101
+ });
102
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=graphql.client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.client.test.d.ts","sourceRoot":"","sources":["../../src/client/graphql.client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphql_client_1 = require("./graphql.client");
4
+ describe('GraphQLClient', () => {
5
+ const mockFetch = jest.fn();
6
+ beforeEach(() => {
7
+ global.fetch = mockFetch;
8
+ mockFetch.mockReset();
9
+ });
10
+ it('should execute query', async () => {
11
+ mockFetch.mockResolvedValue({
12
+ ok: true,
13
+ json: async () => ({ data: { hello: 'world' } }),
14
+ });
15
+ const client = new graphql_client_1.GraphQLClient({ url: 'http://localhost/graphql' });
16
+ const result = await client.query('{ hello }');
17
+ expect(result).toEqual({ hello: 'world' });
18
+ expect(mockFetch).toHaveBeenCalledWith('http://localhost/graphql', expect.objectContaining({
19
+ method: 'POST',
20
+ headers: expect.objectContaining({ 'Content-Type': 'application/json' }),
21
+ body: JSON.stringify({ query: '{ hello }', variables: undefined }),
22
+ }));
23
+ });
24
+ it('should execute query with variables', async () => {
25
+ mockFetch.mockResolvedValue({
26
+ ok: true,
27
+ json: async () => ({ data: { user: { id: '1' } } }),
28
+ });
29
+ const client = new graphql_client_1.GraphQLClient({ url: 'http://localhost/graphql' });
30
+ await client.query('query($id: ID!) { user(id: $id) { id } }', { id: '1' });
31
+ expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
32
+ body: JSON.stringify({
33
+ query: 'query($id: ID!) { user(id: $id) { id } }',
34
+ variables: { id: '1' },
35
+ }),
36
+ }));
37
+ });
38
+ it('should execute mutation', async () => {
39
+ mockFetch.mockResolvedValue({
40
+ ok: true,
41
+ json: async () => ({ data: { createUser: { id: '1' } } }),
42
+ });
43
+ const client = new graphql_client_1.GraphQLClient({ url: 'http://localhost/graphql' });
44
+ const result = await client.mutate('mutation { createUser(name: "x") { id } }');
45
+ expect(result).toEqual({ createUser: { id: '1' } });
46
+ });
47
+ it('should pass custom headers', async () => {
48
+ mockFetch.mockResolvedValue({
49
+ ok: true,
50
+ json: async () => ({ data: {} }),
51
+ });
52
+ const client = new graphql_client_1.GraphQLClient({
53
+ url: 'http://localhost/graphql',
54
+ headers: { Authorization: 'Bearer token' },
55
+ });
56
+ await client.query('{ x }');
57
+ expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
58
+ headers: expect.objectContaining({
59
+ 'Content-Type': 'application/json',
60
+ Authorization: 'Bearer token',
61
+ }),
62
+ }));
63
+ });
64
+ it('should throw on HTTP error', async () => {
65
+ mockFetch.mockResolvedValue({ ok: false, status: 500, statusText: 'Internal Error' });
66
+ const client = new graphql_client_1.GraphQLClient({ url: 'http://localhost/graphql' });
67
+ await expect(client.query('{ x }')).rejects.toThrow('GraphQL request failed: 500 Internal Error');
68
+ });
69
+ it('should throw on GraphQL errors', async () => {
70
+ mockFetch.mockResolvedValue({
71
+ ok: true,
72
+ json: async () => ({
73
+ errors: [{ message: 'Invalid query' }, { message: 'Second error' }],
74
+ }),
75
+ });
76
+ const client = new graphql_client_1.GraphQLClient({ url: 'http://localhost/graphql' });
77
+ await expect(client.query('{ bad }')).rejects.toThrow('Invalid query; Second error');
78
+ });
79
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=field.decorator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.decorator.test.d.ts","sourceRoot":"","sources":["../../src/decorators/field.decorator.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,67 @@
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
+ require("reflect-metadata");
13
+ const field_decorator_1 = require("./field.decorator");
14
+ describe('Field decorator', () => {
15
+ it('should add metadata for property with default name', () => {
16
+ class User {
17
+ }
18
+ __decorate([
19
+ (0, field_decorator_1.Field)(),
20
+ __metadata("design:type", String)
21
+ ], User.prototype, "id", void 0);
22
+ const meta = (0, field_decorator_1.getFieldMetadata)(User.prototype);
23
+ expect(meta).toHaveLength(1);
24
+ expect(meta[0].name).toBe('id');
25
+ });
26
+ it('should add metadata with custom name as string', () => {
27
+ class User {
28
+ }
29
+ __decorate([
30
+ (0, field_decorator_1.Field)('userId'),
31
+ __metadata("design:type", String)
32
+ ], User.prototype, "id", void 0);
33
+ const meta = (0, field_decorator_1.getFieldMetadata)(User.prototype);
34
+ expect(meta[0].name).toBe('userId');
35
+ });
36
+ it('should add metadata with options object', () => {
37
+ class User {
38
+ }
39
+ __decorate([
40
+ (0, field_decorator_1.Field)({ name: 'fullName', description: 'Full name' }),
41
+ __metadata("design:type", String)
42
+ ], User.prototype, "name", void 0);
43
+ const meta = (0, field_decorator_1.getFieldMetadata)(User.prototype);
44
+ expect(meta[0]).toMatchObject({ name: 'fullName', description: 'Full name' });
45
+ });
46
+ it('should add metadata for multiple fields', () => {
47
+ class User {
48
+ }
49
+ __decorate([
50
+ (0, field_decorator_1.Field)(),
51
+ __metadata("design:type", String)
52
+ ], User.prototype, "id", void 0);
53
+ __decorate([
54
+ (0, field_decorator_1.Field)(),
55
+ __metadata("design:type", String)
56
+ ], User.prototype, "name", void 0);
57
+ const meta = (0, field_decorator_1.getFieldMetadata)(User.prototype);
58
+ expect(meta).toHaveLength(2);
59
+ expect(meta.map((m) => m.name)).toEqual(['id', 'name']);
60
+ });
61
+ it('should return empty array for class without @Field', () => {
62
+ class Plain {
63
+ }
64
+ const meta = (0, field_decorator_1.getFieldMetadata)(Plain.prototype);
65
+ expect(meta).toEqual([]);
66
+ });
67
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=object-type.decorator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-type.decorator.test.d.ts","sourceRoot":"","sources":["../../src/decorators/object-type.decorator.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,45 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ require("reflect-metadata");
10
+ const object_type_decorator_1 = require("./object-type.decorator");
11
+ describe('ObjectType decorator', () => {
12
+ it('should add metadata with class name when no options', () => {
13
+ let User = class User {
14
+ };
15
+ User = __decorate([
16
+ (0, object_type_decorator_1.ObjectType)()
17
+ ], User);
18
+ const meta = (0, object_type_decorator_1.getObjectTypeMetadata)(User);
19
+ expect(meta).toEqual({ name: 'User' });
20
+ });
21
+ it('should add metadata with custom name as string', () => {
22
+ let User = class User {
23
+ };
24
+ User = __decorate([
25
+ (0, object_type_decorator_1.ObjectType)('CustomUser')
26
+ ], User);
27
+ const meta = (0, object_type_decorator_1.getObjectTypeMetadata)(User);
28
+ expect(meta).toEqual({ name: 'CustomUser' });
29
+ });
30
+ it('should add metadata with options object', () => {
31
+ let Person = class Person {
32
+ };
33
+ Person = __decorate([
34
+ (0, object_type_decorator_1.ObjectType)({ name: 'Person', description: 'A person type' })
35
+ ], Person);
36
+ const meta = (0, object_type_decorator_1.getObjectTypeMetadata)(Person);
37
+ expect(meta).toEqual({ name: 'Person', description: 'A person type' });
38
+ });
39
+ it('should return undefined for class without decorator', () => {
40
+ class Plain {
41
+ }
42
+ const meta = (0, object_type_decorator_1.getObjectTypeMetadata)(Plain.prototype);
43
+ expect(meta).toBeUndefined();
44
+ });
45
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=query-mutation.decorator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-mutation.decorator.test.d.ts","sourceRoot":"","sources":["../../src/decorators/query-mutation.decorator.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,176 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ require("reflect-metadata");
16
+ const query_mutation_decorator_1 = require("./query-mutation.decorator");
17
+ describe('Query decorator', () => {
18
+ it('should add metadata with method name as default', () => {
19
+ class TestResolver {
20
+ hello() {
21
+ return 'hi';
22
+ }
23
+ }
24
+ __decorate([
25
+ (0, query_mutation_decorator_1.Query)(),
26
+ __metadata("design:type", Function),
27
+ __metadata("design:paramtypes", []),
28
+ __metadata("design:returntype", void 0)
29
+ ], TestResolver.prototype, "hello", null);
30
+ const meta = (0, query_mutation_decorator_1.getQueryMetadata)(TestResolver);
31
+ expect(meta).toHaveLength(1);
32
+ expect(meta[0].name).toBe('hello');
33
+ expect(meta[0].method).toBe('hello');
34
+ });
35
+ it('should add metadata with custom name', () => {
36
+ class TestResolver {
37
+ hello() {
38
+ return 'hi';
39
+ }
40
+ }
41
+ __decorate([
42
+ (0, query_mutation_decorator_1.Query)('getHello'),
43
+ __metadata("design:type", Function),
44
+ __metadata("design:paramtypes", []),
45
+ __metadata("design:returntype", void 0)
46
+ ], TestResolver.prototype, "hello", null);
47
+ const meta = (0, query_mutation_decorator_1.getQueryMetadata)(TestResolver);
48
+ expect(meta[0].name).toBe('getHello');
49
+ expect(meta[0].method).toBe('hello');
50
+ });
51
+ it('should support multiple queries', () => {
52
+ class TestResolver {
53
+ one() { }
54
+ two() { }
55
+ }
56
+ __decorate([
57
+ (0, query_mutation_decorator_1.Query)(),
58
+ __metadata("design:type", Function),
59
+ __metadata("design:paramtypes", []),
60
+ __metadata("design:returntype", void 0)
61
+ ], TestResolver.prototype, "one", null);
62
+ __decorate([
63
+ (0, query_mutation_decorator_1.Query)(),
64
+ __metadata("design:type", Function),
65
+ __metadata("design:paramtypes", []),
66
+ __metadata("design:returntype", void 0)
67
+ ], TestResolver.prototype, "two", null);
68
+ const meta = (0, query_mutation_decorator_1.getQueryMetadata)(TestResolver);
69
+ expect(meta).toHaveLength(2);
70
+ expect(meta.map((m) => m.name)).toEqual(['one', 'two']);
71
+ });
72
+ });
73
+ describe('Mutation decorator', () => {
74
+ it('should add metadata with method name as default', () => {
75
+ class TestResolver {
76
+ createUser() {
77
+ return { id: '1' };
78
+ }
79
+ }
80
+ __decorate([
81
+ (0, query_mutation_decorator_1.Mutation)(),
82
+ __metadata("design:type", Function),
83
+ __metadata("design:paramtypes", []),
84
+ __metadata("design:returntype", void 0)
85
+ ], TestResolver.prototype, "createUser", null);
86
+ const meta = (0, query_mutation_decorator_1.getMutationMetadata)(TestResolver);
87
+ expect(meta).toHaveLength(1);
88
+ expect(meta[0].name).toBe('createUser');
89
+ expect(meta[0].method).toBe('createUser');
90
+ });
91
+ it('should add metadata with custom name', () => {
92
+ class TestResolver {
93
+ createUser() {
94
+ return {};
95
+ }
96
+ }
97
+ __decorate([
98
+ (0, query_mutation_decorator_1.Mutation)('addUser'),
99
+ __metadata("design:type", Function),
100
+ __metadata("design:paramtypes", []),
101
+ __metadata("design:returntype", void 0)
102
+ ], TestResolver.prototype, "createUser", null);
103
+ const meta = (0, query_mutation_decorator_1.getMutationMetadata)(TestResolver);
104
+ expect(meta[0].name).toBe('addUser');
105
+ });
106
+ });
107
+ describe('Arg decorator', () => {
108
+ it('should add metadata for parameter with string name', () => {
109
+ class TestResolver {
110
+ user(_id) {
111
+ return {};
112
+ }
113
+ }
114
+ __decorate([
115
+ (0, query_mutation_decorator_1.Query)(),
116
+ __param(0, (0, query_mutation_decorator_1.Arg)('id')),
117
+ __metadata("design:type", Function),
118
+ __metadata("design:paramtypes", [String]),
119
+ __metadata("design:returntype", void 0)
120
+ ], TestResolver.prototype, "user", null);
121
+ const meta = (0, query_mutation_decorator_1.getArgMetadata)(TestResolver.prototype, 'user');
122
+ expect(meta).toHaveLength(1);
123
+ expect(meta[0]?.name).toBe('id');
124
+ });
125
+ it('should add metadata with type', () => {
126
+ class TestResolver {
127
+ item(_id) {
128
+ return {};
129
+ }
130
+ }
131
+ __decorate([
132
+ (0, query_mutation_decorator_1.Query)(),
133
+ __param(0, (0, query_mutation_decorator_1.Arg)('id', String)),
134
+ __metadata("design:type", Function),
135
+ __metadata("design:paramtypes", [String]),
136
+ __metadata("design:returntype", void 0)
137
+ ], TestResolver.prototype, "item", null);
138
+ const meta = (0, query_mutation_decorator_1.getArgMetadata)(TestResolver.prototype, 'item');
139
+ expect(meta[0]?.name).toBe('id');
140
+ expect(meta[0]?.type).toBe(String);
141
+ });
142
+ it('should add metadata for multiple args in order', () => {
143
+ class TestResolver {
144
+ create(_a, _b) {
145
+ return {};
146
+ }
147
+ }
148
+ __decorate([
149
+ (0, query_mutation_decorator_1.Mutation)(),
150
+ __param(0, (0, query_mutation_decorator_1.Arg)('a')),
151
+ __param(1, (0, query_mutation_decorator_1.Arg)('b')),
152
+ __metadata("design:type", Function),
153
+ __metadata("design:paramtypes", [String, Number]),
154
+ __metadata("design:returntype", void 0)
155
+ ], TestResolver.prototype, "create", null);
156
+ const meta = (0, query_mutation_decorator_1.getArgMetadata)(TestResolver.prototype, 'create');
157
+ expect(meta).toHaveLength(2);
158
+ expect(meta[0]?.name).toBe('a');
159
+ expect(meta[1]?.name).toBe('b');
160
+ });
161
+ it('should return empty array when no args', () => {
162
+ class TestResolver {
163
+ hello() {
164
+ return 'hi';
165
+ }
166
+ }
167
+ __decorate([
168
+ (0, query_mutation_decorator_1.Query)(),
169
+ __metadata("design:type", Function),
170
+ __metadata("design:paramtypes", []),
171
+ __metadata("design:returntype", void 0)
172
+ ], TestResolver.prototype, "hello", null);
173
+ const meta = (0, query_mutation_decorator_1.getArgMetadata)(TestResolver.prototype, 'hello');
174
+ expect(meta).toEqual([]);
175
+ });
176
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=resolver.decorator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.decorator.test.d.ts","sourceRoot":"","sources":["../../src/decorators/resolver.decorator.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,36 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ require("reflect-metadata");
10
+ const resolver_decorator_1 = require("./resolver.decorator");
11
+ describe('Resolver decorator', () => {
12
+ it('should add empty metadata when no name', () => {
13
+ let UserResolver = class UserResolver {
14
+ };
15
+ UserResolver = __decorate([
16
+ (0, resolver_decorator_1.Resolver)()
17
+ ], UserResolver);
18
+ const meta = (0, resolver_decorator_1.getResolverMetadata)(UserResolver);
19
+ expect(meta).toEqual({});
20
+ });
21
+ it('should add metadata with custom name', () => {
22
+ let UserResolver = class UserResolver {
23
+ };
24
+ UserResolver = __decorate([
25
+ (0, resolver_decorator_1.Resolver)('User')
26
+ ], UserResolver);
27
+ const meta = (0, resolver_decorator_1.getResolverMetadata)(UserResolver);
28
+ expect(meta).toEqual({ name: 'User' });
29
+ });
30
+ it('should return undefined for class without decorator', () => {
31
+ class Plain {
32
+ }
33
+ const meta = (0, resolver_decorator_1.getResolverMetadata)(Plain);
34
+ expect(meta).toBeUndefined();
35
+ });
36
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=graphql.module.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.module.test.d.ts","sourceRoot":"","sources":["../src/graphql.module.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,85 @@
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
+ require("reflect-metadata");
13
+ const core_1 = require("@hazeljs/core");
14
+ const core_2 = require("@hazeljs/core");
15
+ const graphql_module_1 = require("./graphql.module");
16
+ const graphql_server_1 = require("./graphql.server");
17
+ const query_mutation_decorator_1 = require("./decorators/query-mutation.decorator");
18
+ const resolver_decorator_1 = require("./decorators/resolver.decorator");
19
+ const core_3 = require("@hazeljs/core");
20
+ let TestResolver = class TestResolver {
21
+ hello() {
22
+ return 'world';
23
+ }
24
+ };
25
+ __decorate([
26
+ (0, query_mutation_decorator_1.Query)(),
27
+ __metadata("design:type", Function),
28
+ __metadata("design:paramtypes", []),
29
+ __metadata("design:returntype", void 0)
30
+ ], TestResolver.prototype, "hello", null);
31
+ TestResolver = __decorate([
32
+ (0, resolver_decorator_1.Resolver)()
33
+ ], TestResolver);
34
+ let TestModule = class TestModule {
35
+ };
36
+ TestModule = __decorate([
37
+ (0, core_3.HazelModule)({
38
+ imports: [
39
+ graphql_module_1.GraphQLModule.forRoot({
40
+ path: '/graphql',
41
+ resolvers: [TestResolver],
42
+ }),
43
+ ],
44
+ })
45
+ ], TestModule);
46
+ describe('GraphQLModule', () => {
47
+ let container;
48
+ const originalGetInstance = core_1.Container.getInstance;
49
+ beforeEach(() => {
50
+ container = core_1.Container.createTestInstance();
51
+ core_1.Container.getInstance = jest.fn(() => container);
52
+ });
53
+ afterEach(() => {
54
+ core_1.Container.getInstance = originalGetInstance;
55
+ });
56
+ describe('forRoot', () => {
57
+ it('should return module config with providers and exports', () => {
58
+ expect(TestModule).toBeDefined();
59
+ const config = graphql_module_1.GraphQLModule.forRoot({
60
+ path: '/graphql',
61
+ resolvers: [TestResolver],
62
+ });
63
+ expect(config.module).toBe(graphql_module_1.GraphQLModule);
64
+ expect(config.providers).toHaveLength(2);
65
+ expect(config.providers[0]).toMatchObject({ provide: graphql_server_1.GraphQLServer });
66
+ expect(config.providers[0].useFactory).toBeDefined();
67
+ expect(config.exports).toContain(graphql_server_1.GraphQLServer);
68
+ expect(config.global).toBe(true);
69
+ });
70
+ it('should create GraphQLServer via factory', () => {
71
+ const mockApp = { addEarlyHandler: jest.fn() };
72
+ container.register(core_2.HazelApp, mockApp);
73
+ container.register(TestResolver, new TestResolver());
74
+ const config = graphql_module_1.GraphQLModule.forRoot({
75
+ path: '/api/gql',
76
+ resolvers: [TestResolver],
77
+ });
78
+ const factory = config.providers[0].useFactory;
79
+ const server = factory();
80
+ expect(server).toBeInstanceOf(graphql_server_1.GraphQLServer);
81
+ expect(server.getPath()).toBe('/api/gql');
82
+ expect(mockApp.addEarlyHandler).toHaveBeenCalledWith('/api/gql', expect.any(Function));
83
+ });
84
+ });
85
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=graphql.server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.server.test.d.ts","sourceRoot":"","sources":["../src/graphql.server.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,79 @@
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
+ require("reflect-metadata");
13
+ const core_1 = require("@hazeljs/core");
14
+ const core_2 = require("@hazeljs/core");
15
+ const graphql_server_1 = require("./graphql.server");
16
+ const query_mutation_decorator_1 = require("./decorators/query-mutation.decorator");
17
+ const resolver_decorator_1 = require("./decorators/resolver.decorator");
18
+ jest.mock('graphql-http/lib/use/http', () => ({
19
+ createHandler: jest.fn().mockReturnValue(jest.fn()),
20
+ }));
21
+ let TestResolver = class TestResolver {
22
+ hello() {
23
+ return 'world';
24
+ }
25
+ };
26
+ __decorate([
27
+ (0, query_mutation_decorator_1.Query)(),
28
+ __metadata("design:type", Function),
29
+ __metadata("design:paramtypes", []),
30
+ __metadata("design:returntype", void 0)
31
+ ], TestResolver.prototype, "hello", null);
32
+ TestResolver = __decorate([
33
+ (0, core_2.Injectable)(),
34
+ (0, resolver_decorator_1.Resolver)()
35
+ ], TestResolver);
36
+ describe('GraphQLServer', () => {
37
+ let container;
38
+ beforeEach(() => {
39
+ container = core_1.Container.createTestInstance();
40
+ container.register(TestResolver, new TestResolver());
41
+ });
42
+ describe('configure', () => {
43
+ it('should set default path to /graphql', () => {
44
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
45
+ expect(server.getPath()).toBe('/graphql');
46
+ });
47
+ it('should set custom path', () => {
48
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
49
+ server.configure({ path: '/api/gql' });
50
+ expect(server.getPath()).toBe('/api/gql');
51
+ });
52
+ });
53
+ describe('getHandler', () => {
54
+ it('should build and return handler on first call', () => {
55
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
56
+ const handler = server.getHandler();
57
+ expect(handler).toBeDefined();
58
+ expect(typeof handler).toBe('function');
59
+ });
60
+ it('should return same handler on subsequent calls', () => {
61
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
62
+ const h1 = server.getHandler();
63
+ const h2 = server.getHandler();
64
+ expect(h1).toBe(h2);
65
+ });
66
+ });
67
+ describe('getSchema', () => {
68
+ it('should return null before build', () => {
69
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
70
+ expect(server.getSchema()).toBeNull();
71
+ });
72
+ it('should return schema after getHandler', () => {
73
+ const server = new graphql_server_1.GraphQLServer([TestResolver], container);
74
+ server.getHandler();
75
+ expect(server.getSchema()).toBeDefined();
76
+ expect(server.getSchema()?.getQueryType()).toBeDefined();
77
+ });
78
+ });
79
+ });
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=schema-builder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-builder.test.d.ts","sourceRoot":"","sources":["../src/schema-builder.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ 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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ require("reflect-metadata");
49
+ const core_1 = require("@hazeljs/core");
50
+ const core_2 = require("@hazeljs/core");
51
+ const schema_builder_1 = require("./schema-builder");
52
+ const resolver_decorator_1 = require("./decorators/resolver.decorator");
53
+ const query_mutation_decorator_1 = require("./decorators/query-mutation.decorator");
54
+ let TestResolver = class TestResolver {
55
+ hello() {
56
+ return 'world';
57
+ }
58
+ user(id) {
59
+ return JSON.stringify({ id, name: `User ${id}` });
60
+ }
61
+ createUser(name) {
62
+ return JSON.stringify({ id: '1', name });
63
+ }
64
+ };
65
+ __decorate([
66
+ (0, query_mutation_decorator_1.Query)(),
67
+ __metadata("design:type", Function),
68
+ __metadata("design:paramtypes", []),
69
+ __metadata("design:returntype", void 0)
70
+ ], TestResolver.prototype, "hello", null);
71
+ __decorate([
72
+ (0, query_mutation_decorator_1.Query)(),
73
+ __param(0, (0, query_mutation_decorator_1.Arg)('id')),
74
+ __metadata("design:type", Function),
75
+ __metadata("design:paramtypes", [String]),
76
+ __metadata("design:returntype", void 0)
77
+ ], TestResolver.prototype, "user", null);
78
+ __decorate([
79
+ (0, query_mutation_decorator_1.Mutation)(),
80
+ __param(0, (0, query_mutation_decorator_1.Arg)('name')),
81
+ __metadata("design:type", Function),
82
+ __metadata("design:paramtypes", [String]),
83
+ __metadata("design:returntype", void 0)
84
+ ], TestResolver.prototype, "createUser", null);
85
+ TestResolver = __decorate([
86
+ (0, core_2.Injectable)(),
87
+ (0, resolver_decorator_1.Resolver)()
88
+ ], TestResolver);
89
+ describe('SchemaBuilder', () => {
90
+ let container;
91
+ beforeEach(() => {
92
+ container = core_1.Container.createTestInstance();
93
+ container.register(TestResolver, new TestResolver());
94
+ });
95
+ it('should build schema with queries', () => {
96
+ const builder = new schema_builder_1.SchemaBuilder();
97
+ const schema = builder.buildSchema([TestResolver], container);
98
+ expect(schema.getQueryType()).toBeDefined();
99
+ expect(schema.getQueryType()?.getFields().hello).toBeDefined();
100
+ expect(schema.getQueryType()?.getFields().user).toBeDefined();
101
+ });
102
+ it('should build schema with mutations', () => {
103
+ const builder = new schema_builder_1.SchemaBuilder();
104
+ const schema = builder.buildSchema([TestResolver], container);
105
+ expect(schema.getMutationType()).toBeDefined();
106
+ expect(schema.getMutationType()?.getFields().createUser).toBeDefined();
107
+ });
108
+ it('should execute query resolvers', async () => {
109
+ const builder = new schema_builder_1.SchemaBuilder();
110
+ const schema = builder.buildSchema([TestResolver], container);
111
+ const { graphql } = await Promise.resolve().then(() => __importStar(require('graphql')));
112
+ const result = await graphql({ schema, source: '{ hello }' });
113
+ expect(result.data).toEqual({ hello: 'world' });
114
+ });
115
+ it('should execute query with args', async () => {
116
+ const builder = new schema_builder_1.SchemaBuilder();
117
+ const schema = builder.buildSchema([TestResolver], container);
118
+ const { graphql } = await Promise.resolve().then(() => __importStar(require('graphql')));
119
+ const result = await graphql({ schema, source: '{ user(id: "42") }' });
120
+ expect(result.errors).toBeUndefined();
121
+ expect(result.data?.user).toBeDefined();
122
+ expect(JSON.parse(result.data.user)).toMatchObject({ id: '42', name: 'User 42' });
123
+ });
124
+ it('should execute mutation', async () => {
125
+ const builder = new schema_builder_1.SchemaBuilder();
126
+ const schema = builder.buildSchema([TestResolver], container);
127
+ const { graphql } = await Promise.resolve().then(() => __importStar(require('graphql')));
128
+ const result = await graphql({
129
+ schema,
130
+ source: 'mutation { createUser(name: "Alice") }',
131
+ });
132
+ expect(result.errors).toBeUndefined();
133
+ expect(result.data?.createUser).toBeDefined();
134
+ expect(JSON.parse(result.data.createUser)).toMatchObject({ id: '1', name: 'Alice' });
135
+ });
136
+ it('should handle resolver with missing method', async () => {
137
+ let IncompleteResolver = class IncompleteResolver {
138
+ hello() {
139
+ return 'ok';
140
+ }
141
+ };
142
+ __decorate([
143
+ (0, query_mutation_decorator_1.Query)(),
144
+ __metadata("design:type", Function),
145
+ __metadata("design:paramtypes", []),
146
+ __metadata("design:returntype", void 0)
147
+ ], IncompleteResolver.prototype, "hello", null);
148
+ IncompleteResolver = __decorate([
149
+ (0, core_2.Injectable)(),
150
+ (0, resolver_decorator_1.Resolver)()
151
+ ], IncompleteResolver);
152
+ const instance = new (class {
153
+ })();
154
+ container.register(IncompleteResolver, instance);
155
+ const builder = new schema_builder_1.SchemaBuilder();
156
+ const schema = builder.buildSchema([IncompleteResolver], container);
157
+ const { graphql } = await Promise.resolve().then(() => __importStar(require('graphql')));
158
+ const result = await graphql({ schema, source: '{ hello }' });
159
+ expect(result.data?.hello).toBeNull();
160
+ });
161
+ it('should build mutation type only when mutations exist', () => {
162
+ let QueryOnlyResolver = class QueryOnlyResolver {
163
+ only() {
164
+ return 'ok';
165
+ }
166
+ };
167
+ __decorate([
168
+ (0, query_mutation_decorator_1.Query)(),
169
+ __metadata("design:type", Function),
170
+ __metadata("design:paramtypes", []),
171
+ __metadata("design:returntype", void 0)
172
+ ], QueryOnlyResolver.prototype, "only", null);
173
+ QueryOnlyResolver = __decorate([
174
+ (0, core_2.Injectable)(),
175
+ (0, resolver_decorator_1.Resolver)()
176
+ ], QueryOnlyResolver);
177
+ container.register(QueryOnlyResolver, new QueryOnlyResolver());
178
+ const builder = new schema_builder_1.SchemaBuilder();
179
+ const schema = builder.buildSchema([QueryOnlyResolver], container);
180
+ expect(schema.getMutationType()).toBeUndefined();
181
+ });
182
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/graphql",
3
- "version": "0.2.0-beta.54",
3
+ "version": "0.2.0-beta.56",
4
4
  "description": "GraphQL server and client for HazelJS - decorator-based schema and typed client",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -52,5 +52,5 @@
52
52
  "url": "https://github.com/hazeljs/hazel-js/issues"
53
53
  },
54
54
  "homepage": "https://hazeljs.com",
55
- "gitHead": "c593ce33447cdc62d7bd2386cc2db47840292fcb"
55
+ "gitHead": "c2737e90974458a8438eee623726f0a453b66b8b"
56
56
  }