@orion-js/graphql 3.4.11 → 3.5.0

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.
@@ -5,10 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const crypto_1 = __importDefault(require("crypto"));
7
7
  const helpers_1 = require("@orion-js/helpers");
8
+ const graphql_1 = require("graphql");
8
9
  function errorHandler(error, data) {
9
10
  const message = `Error in resolver "${data.name}" ${data.model ? `of model "${data.model.name}"` : ''}`;
10
11
  if (error && error.isOrionError) {
11
12
  console.warn(message, error);
13
+ throw new graphql_1.GraphQLError(error.message, {
14
+ originalError: error,
15
+ extensions: {
16
+ isOrionError: !!error.isOrionError,
17
+ isValidationError: !!error.isValidationError,
18
+ code: error.code,
19
+ info: error.getInfo()
20
+ }
21
+ });
12
22
  }
13
23
  else {
14
24
  const hash = crypto_1.default
package/lib/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import subscription from './subscription';
2
2
  import startGraphQL from './startGraphQL';
3
3
  import startGraphiQL from './startGraphiQL';
4
4
  import resolversSchemas from './resolversSchemas';
5
- import ResolverParams from './resolversSchemas/ResolverParams';
5
+ import ResolverParams from './resolversSchemas/ResolverParamsInfo';
6
6
  import serializeSchema from './resolversSchemas/serializeSchema';
7
7
  import getBasicResultQuery from './resolversSchemas/getBasicResultQuery';
8
8
  import * as GraphQL from 'graphql';
package/lib/index.js CHANGED
@@ -38,8 +38,8 @@ const startGraphiQL_1 = __importDefault(require("./startGraphiQL"));
38
38
  exports.startGraphiQL = startGraphiQL_1.default;
39
39
  const resolversSchemas_1 = __importDefault(require("./resolversSchemas"));
40
40
  exports.resolversSchemas = resolversSchemas_1.default;
41
- const ResolverParams_1 = __importDefault(require("./resolversSchemas/ResolverParams"));
42
- exports.ResolverParams = ResolverParams_1.default;
41
+ const ResolverParamsInfo_1 = __importDefault(require("./resolversSchemas/ResolverParamsInfo"));
42
+ exports.ResolverParams = ResolverParamsInfo_1.default;
43
43
  const serializeSchema_1 = __importDefault(require("./resolversSchemas/serializeSchema"));
44
44
  exports.serializeSchema = serializeSchema_1.default;
45
45
  const getBasicResultQuery_1 = __importDefault(require("./resolversSchemas/getBasicResultQuery"));
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const resolvers_1 = require("@orion-js/resolvers");
7
7
  const helpers_1 = require("@orion-js/helpers");
8
- const ResolverParams_1 = __importDefault(require("./ResolverParams"));
8
+ const ResolverParamsInfo_1 = __importDefault(require("./ResolverParamsInfo"));
9
9
  const resolversStore_1 = require("../buildSchema/getResolvers/resolversStore");
10
10
  exports.default = (0, resolvers_1.resolver)({
11
11
  params: {
@@ -16,7 +16,7 @@ exports.default = (0, resolvers_1.resolver)({
16
16
  type: Boolean
17
17
  }
18
18
  },
19
- returns: ResolverParams_1.default,
19
+ returns: ResolverParamsInfo_1.default,
20
20
  mutation: false,
21
21
  resolve: async function ({ mutation, name }, viewer) {
22
22
  const resolver = resolversStore_1.resolversStore[name];
@@ -3,8 +3,8 @@ export declare function Resolvers(): ClassDecorator;
3
3
  export interface GlobalResolverPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {
4
4
  value?: GlobalResolverResolve;
5
5
  }
6
- export declare function Query(options: Omit<ResolverOptions<any>, 'resolve' | 'mutation'>): (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor) => void;
7
- export declare function Mutation(options: Omit<ResolverOptions<any>, 'resolve' | 'mutation'>): (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor) => void;
6
+ export declare function Query(options?: Omit<ResolverOptions<any>, 'resolve' | 'mutation'>): (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor) => void;
7
+ export declare function Mutation(options?: Omit<ResolverOptions<any>, 'resolve' | 'mutation'>): (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor) => void;
8
8
  export declare function getServiceResolvers(target: any): {
9
9
  [key: string]: Resolver<GlobalResolverResolve>;
10
10
  };
@@ -4,6 +4,7 @@ exports.getServiceResolvers = exports.Mutation = exports.Query = exports.Resolve
4
4
  const services_1 = require("@orion-js/services");
5
5
  const resolvers_1 = require("@orion-js/resolvers");
6
6
  const helpers_1 = require("@orion-js/helpers");
7
+ const otherParams_1 = require("./otherParams");
7
8
  function Resolvers() {
8
9
  return function (target) {
9
10
  (0, services_1.Service)()(target);
@@ -17,6 +18,9 @@ function Query(options) {
17
18
  throw new Error(`You must pass resolver function to ${propertyKey}`);
18
19
  target.resolvers = target.resolvers || {};
19
20
  target.resolvers[propertyKey] = (0, resolvers_1.resolver)({
21
+ params: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'params'),
22
+ returns: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'returns'),
23
+ middlewares: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'middlewares'),
20
24
  ...options,
21
25
  resolve: async (params, viewer) => {
22
26
  const instance = (0, services_1.getInstance)(target.service);
@@ -32,6 +36,9 @@ function Mutation(options) {
32
36
  throw new Error(`You must pass resolver function to ${propertyKey}`);
33
37
  target.resolvers = target.resolvers || {};
34
38
  target.resolvers[propertyKey] = (0, resolvers_1.resolver)({
39
+ params: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'params'),
40
+ returns: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'returns'),
41
+ middlewares: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'middlewares'),
35
42
  ...options,
36
43
  mutation: true,
37
44
  resolve: async (params, viewer) => {
@@ -1,3 +1,4 @@
1
1
  export * from './global';
2
2
  export * from './model';
3
3
  export * from './subscription';
4
+ export * from './otherParams';
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./global"), exports);
18
18
  __exportStar(require("./model"), exports);
19
19
  __exportStar(require("./subscription"), exports);
20
+ __exportStar(require("./otherParams"), exports);
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
@@ -0,0 +1,99 @@
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 services_1 = require("@orion-js/services");
14
+ const index_1 = require("./index");
15
+ const otherParams_1 = require("./otherParams");
16
+ const resolvers_1 = require("@orion-js/resolvers");
17
+ const typed_model_1 = require("@orion-js/typed-model");
18
+ describe('Resolvers with service injection and middlewares', () => {
19
+ it('should allow to pass resolver middlewares with decorators', async () => {
20
+ expect.assertions(3);
21
+ let ExampleRepo = class ExampleRepo {
22
+ getLastName() {
23
+ return 'Lopez';
24
+ }
25
+ };
26
+ ExampleRepo = __decorate([
27
+ (0, services_1.Service)()
28
+ ], ExampleRepo);
29
+ const exampleMiddleware = (0, resolvers_1.createResolverMiddleware)(async (executeOptions, next) => {
30
+ const result = await next();
31
+ expect(result).toBe('intercepted2');
32
+ return 'intercepted';
33
+ });
34
+ const CheckRoles = (rolesToCheck) => {
35
+ return (0, otherParams_1.UseMiddleware)(async (executeOptions, next) => {
36
+ // check roles here
37
+ await next();
38
+ return 'intercepted2';
39
+ });
40
+ };
41
+ let ExampleResolverService = class ExampleResolverService {
42
+ async sayHi(params) {
43
+ return 'text';
44
+ }
45
+ };
46
+ __decorate([
47
+ (0, index_1.Query)(),
48
+ (0, otherParams_1.ResolverParams)({ name: { type: 'string' } }),
49
+ (0, otherParams_1.ResolverReturns)(String),
50
+ (0, otherParams_1.UseMiddleware)(exampleMiddleware),
51
+ CheckRoles(['admin']),
52
+ __metadata("design:type", Function),
53
+ __metadata("design:paramtypes", [Object]),
54
+ __metadata("design:returntype", Promise)
55
+ ], ExampleResolverService.prototype, "sayHi", null);
56
+ ExampleResolverService = __decorate([
57
+ (0, index_1.Resolvers)()
58
+ ], ExampleResolverService);
59
+ const resolvers = (0, index_1.getServiceResolvers)(ExampleResolverService);
60
+ expect(resolvers.sayHi).toBeDefined();
61
+ const result = await resolvers.sayHi.execute({ params: { name: 'Orion' } });
62
+ expect(result).toBe(`intercepted`);
63
+ });
64
+ it('show also work with model resolvers', async () => {
65
+ let Person = class Person {
66
+ };
67
+ __decorate([
68
+ (0, typed_model_1.Prop)(),
69
+ __metadata("design:type", String)
70
+ ], Person.prototype, "name", void 0);
71
+ Person = __decorate([
72
+ (0, typed_model_1.TypedSchema)()
73
+ ], Person);
74
+ const NiceToMeetYou = (0, otherParams_1.UseMiddleware)(async (executeOptions, next) => {
75
+ const result = await next();
76
+ return `${result}, nice to meet you`;
77
+ });
78
+ let PersonResolvers = class PersonResolvers {
79
+ async getAge(person) {
80
+ return `hello ${person.name}`;
81
+ }
82
+ };
83
+ __decorate([
84
+ (0, index_1.ModelResolver)(),
85
+ (0, otherParams_1.ResolverReturns)(String),
86
+ NiceToMeetYou,
87
+ __metadata("design:type", Function),
88
+ __metadata("design:paramtypes", [Person]),
89
+ __metadata("design:returntype", Promise)
90
+ ], PersonResolvers.prototype, "getAge", null);
91
+ PersonResolvers = __decorate([
92
+ (0, index_1.ModelResolvers)(Person)
93
+ ], PersonResolvers);
94
+ const data = (0, index_1.getServiceModelResolvers)(PersonResolvers);
95
+ const item = { name: 'Orion' };
96
+ const result = await data.Person.getAge.execute({ parent: item });
97
+ expect(result).toBe(`hello Orion, nice to meet you`);
98
+ });
99
+ });
@@ -2,7 +2,7 @@ import { GlobalResolverResolve, ResolverOptions, ModelResolverResolve, ModelReso
2
2
  export interface ModelResolverPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {
3
3
  value?: ModelResolverResolve;
4
4
  }
5
- export declare function ModelResolver(options: Omit<ResolverOptions<any>, 'resolve'>): (target: any, propertyKey: string, descriptor: ModelResolverPropertyDescriptor) => void;
5
+ export declare function ModelResolver(options?: Omit<ResolverOptions<any>, 'resolve' | 'middlewares'>): (target: any, propertyKey: string, descriptor: ModelResolverPropertyDescriptor) => void;
6
6
  export interface ModelResolversOptions {
7
7
  modelName?: string;
8
8
  }
@@ -4,12 +4,16 @@ exports.getServiceModelResolvers = exports.ModelResolvers = exports.ModelResolve
4
4
  const services_1 = require("@orion-js/services");
5
5
  const resolvers_1 = require("@orion-js/resolvers");
6
6
  const helpers_1 = require("@orion-js/helpers");
7
+ const otherParams_1 = require("./otherParams");
7
8
  function ModelResolver(options) {
8
9
  return function (target, propertyKey, descriptor) {
9
10
  if (!descriptor.value)
10
11
  throw new Error(`You must pass resolver function to ${propertyKey}`);
11
12
  target.resolvers = target.resolvers || {};
12
13
  target.resolvers[propertyKey] = (0, resolvers_1.modelResolver)({
14
+ params: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'params'),
15
+ returns: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'returns'),
16
+ middlewares: (0, otherParams_1.getTargetMetadata)(target, propertyKey, 'middlewares'),
13
17
  ...options,
14
18
  resolve: async (item, params, viewer) => {
15
19
  const instance = (0, services_1.getInstance)(target.service);
@@ -0,0 +1,7 @@
1
+ import { ResolverMiddleware } from '@orion-js/resolvers';
2
+ import { GlobalResolverPropertyDescriptor } from './global';
3
+ import { ModelResolverPropertyDescriptor } from './model';
4
+ export declare function getTargetMetadata(target: any, propertyKey: string, metadataKey: string): any;
5
+ export declare const UseMiddleware: (metadata: ResolverMiddleware) => (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor | ModelResolverPropertyDescriptor) => void;
6
+ export declare const ResolverParams: (metadata: any) => (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor | ModelResolverPropertyDescriptor) => void;
7
+ export declare const ResolverReturns: (metadata: any) => (target: any, propertyKey: string, descriptor: GlobalResolverPropertyDescriptor | ModelResolverPropertyDescriptor) => void;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResolverReturns = exports.ResolverParams = exports.UseMiddleware = exports.getTargetMetadata = void 0;
4
+ function createRegisterResolverMetadata(metadataKey, isArray = false) {
5
+ return (metadata) => {
6
+ return function (target, propertyKey, descriptor) {
7
+ if (!descriptor.value)
8
+ throw new Error(`You must pass resolver function to ${propertyKey}`);
9
+ target[metadataKey] = target[metadataKey] || {};
10
+ if (isArray) {
11
+ target[metadataKey][propertyKey] = target[metadataKey][propertyKey] || [];
12
+ // push at the start of the array
13
+ target[metadataKey][propertyKey].unshift(metadata);
14
+ }
15
+ else {
16
+ target[metadataKey][propertyKey] = metadata;
17
+ }
18
+ };
19
+ };
20
+ }
21
+ function getTargetMetadata(target, propertyKey, metadataKey) {
22
+ const items = target[metadataKey] || {};
23
+ return items[propertyKey] || [];
24
+ }
25
+ exports.getTargetMetadata = getTargetMetadata;
26
+ exports.UseMiddleware = createRegisterResolverMetadata('middlewares', true);
27
+ exports.ResolverParams = createRegisterResolverMetadata('params');
28
+ exports.ResolverReturns = createRegisterResolverMetadata('returns');
@@ -19,6 +19,7 @@ const supertest_1 = __importDefault(require("supertest"));
19
19
  const typed_model_1 = require("@orion-js/typed-model");
20
20
  const cleanResolvers_1 = require("./cleanResolvers");
21
21
  const models_1 = require("@orion-js/models");
22
+ const helpers_1 = require("@orion-js/helpers");
22
23
  describe('Test GraphQL Server', () => {
23
24
  beforeEach(() => {
24
25
  (0, cleanResolvers_1.cleanResolvers)();
@@ -108,6 +109,129 @@ describe('Test GraphQL Server', () => {
108
109
  expect(response.statusCode).toBe(400);
109
110
  expect(response.body.errors[0].message).toEqual('Cannot query field "helloWorld_doesntExists" on type "Query".');
110
111
  });
112
+ it('should return validation errors correctly', async () => {
113
+ const resolvers = {
114
+ helloWorld: (0, resolvers_1.resolver)({
115
+ params: {
116
+ name: {
117
+ type: 'string',
118
+ validate: () => {
119
+ return 'notUnique';
120
+ }
121
+ }
122
+ },
123
+ returns: 'string',
124
+ async resolve({ name }) {
125
+ return `Hello ${name}`;
126
+ }
127
+ })
128
+ };
129
+ const app = (0, http_1.express)();
130
+ await (0, _1.startGraphQL)({
131
+ resolvers,
132
+ app
133
+ });
134
+ const response = await (0, supertest_1.default)(app)
135
+ .post('/graphql')
136
+ .send({
137
+ operationName: 'testOperation',
138
+ variables: {
139
+ name: 'Nico'
140
+ },
141
+ query: `query testOperation($name: String) {
142
+ helloWorld(name: $name)
143
+ }`
144
+ });
145
+ expect(response.statusCode).toBe(200);
146
+ expect(response.body).toEqual({
147
+ errors: [
148
+ {
149
+ message: 'Validation Error: {name: notUnique}',
150
+ locations: [
151
+ {
152
+ line: 2,
153
+ column: 11
154
+ }
155
+ ],
156
+ path: ['helloWorld'],
157
+ extensions: {
158
+ isOrionError: true,
159
+ isValidationError: true,
160
+ code: 'validationError',
161
+ info: {
162
+ error: 'validationError',
163
+ message: 'Validation Error',
164
+ validationErrors: {
165
+ name: 'notUnique'
166
+ }
167
+ }
168
+ }
169
+ }
170
+ ],
171
+ data: {
172
+ helloWorld: null
173
+ }
174
+ });
175
+ });
176
+ it('should return user errors correctly', async () => {
177
+ const resolvers = {
178
+ helloWorld: (0, resolvers_1.resolver)({
179
+ params: {
180
+ name: {
181
+ type: 'string'
182
+ }
183
+ },
184
+ returns: 'string',
185
+ async resolve({ name }) {
186
+ throw new helpers_1.UserError('code', 'message');
187
+ return `Hello ${name}`;
188
+ }
189
+ })
190
+ };
191
+ const app = (0, http_1.express)();
192
+ await (0, _1.startGraphQL)({
193
+ resolvers,
194
+ app
195
+ });
196
+ const response = await (0, supertest_1.default)(app)
197
+ .post('/graphql')
198
+ .send({
199
+ operationName: 'testOperation',
200
+ variables: {
201
+ name: 'Nico'
202
+ },
203
+ query: `query testOperation($name: String) {
204
+ helloWorld(name: $name)
205
+ }`
206
+ });
207
+ expect(response.statusCode).toBe(200);
208
+ expect(response.body).toEqual({
209
+ errors: [
210
+ {
211
+ message: 'message',
212
+ locations: [
213
+ {
214
+ line: 2,
215
+ column: 11
216
+ }
217
+ ],
218
+ path: ['helloWorld'],
219
+ extensions: {
220
+ isOrionError: true,
221
+ isValidationError: false,
222
+ code: 'code',
223
+ info: {
224
+ error: 'code',
225
+ message: 'message'
226
+ }
227
+ }
228
+ }
229
+ ],
230
+ data: {
231
+ helloWorld: null
232
+ }
233
+ });
234
+ });
111
235
  it('Should make requests to schemas with typed models', async () => {
112
236
  let Params = class Params {
113
237
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-js/graphql",
3
- "version": "3.4.11",
3
+ "version": "3.5.0",
4
4
  "main": "lib/index.js",
5
5
  "author": "nicolaslopezj",
6
6
  "license": "MIT",
@@ -15,14 +15,14 @@
15
15
  "dependencies": {
16
16
  "@apollo/server": "^4.3.0",
17
17
  "@graphql-tools/schema": "^9.0.12",
18
- "@orion-js/env": "^3.4.1",
19
- "@orion-js/helpers": "^3.4.1",
20
- "@orion-js/http": "^3.4.9",
21
- "@orion-js/models": "^3.4.9",
22
- "@orion-js/resolvers": "^3.4.9",
23
- "@orion-js/schema": "^3.4.9",
24
- "@orion-js/services": "^3.4.1",
25
- "@orion-js/typed-model": "^3.4.9",
18
+ "@orion-js/env": "^3.5.0",
19
+ "@orion-js/helpers": "^3.5.0",
20
+ "@orion-js/http": "^3.5.0",
21
+ "@orion-js/models": "^3.5.0",
22
+ "@orion-js/resolvers": "^3.5.0",
23
+ "@orion-js/schema": "^3.5.0",
24
+ "@orion-js/services": "^3.5.0",
25
+ "@orion-js/typed-model": "^3.5.0",
26
26
  "graphql-iso-date": "^3.6.1",
27
27
  "graphql-subscriptions": "2.0.0",
28
28
  "graphql-ws": "^5.11.2",
@@ -51,5 +51,5 @@
51
51
  "publishConfig": {
52
52
  "access": "public"
53
53
  },
54
- "gitHead": "99aec486f0d9343d9bc2c3bacf430217b0bc7dba"
54
+ "gitHead": "6fc8b0e40fad04d7ff84cf0849cbf260a66b6641"
55
55
  }