UNPKG

vulcain-corejs

Version:
122 lines 6.37 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 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; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); const annotations_1 = require("../di/annotations"); const messageBus_1 = require("../bus/messageBus"); const annotations_2 = require("../di/annotations"); const typeBuilder_1 = require("./typeBuilder"); const applicationRequestError_1 = require("../pipeline/errors/applicationRequestError"); const conventions_1 = require("../utils/conventions"); const graphql = require('graphql'); const graphQlQuerySymbol = Symbol("[[graphqlquery]]"); let GraphQLAdapter = class GraphQLAdapter { constructor(container) { this.container = container; this._subscriptions = new Map(); } async processGraphQLQuery(context, g) { context.requestData[graphQlQuerySymbol] = g.query || g; if ((g.query || g).indexOf("subscription") >= 0) throw new applicationRequestError_1.ApplicationError("Invalid subscription. Use Server Side Event on " + conventions_1.Conventions.instance.defaultGraphQLSubscriptionPath); let result = await graphql.graphql(this.getGraphQuerySchema(context), g.query || g, null, context, g.variables); return result; } enableSubscription(context, handler, entity) { if (entity) return entity; // Subscription step let g = context.requestData[graphQlQuerySymbol]; let item = { scope: handler.definition.scope, subscriptions: {} }; item.subscriptions[handler.name] = g.query || g; this._subscriptions.set(context.requestData.correlationId, item); } getGraphQuerySchema(context) { if (!this._schema) { const builder = new typeBuilder_1.GraphQLTypeBuilder(); this._schema = builder.build(context, this); } return this._schema; } getSubscriptionHandler() { return async (ctx) => { let response = ctx.request.nativeResponse; let request = ctx.request.nativeRequest; let query = request.url.substr(request.url.indexOf('?') + 1); let parts = query && query.split('='); if (!parts || parts.length !== 2 || parts[0] !== "query") { response.statusCode = 400; response.end("query is required"); return; } let g = decodeURIComponent(parts[1]); ctx.requestData[graphQlQuerySymbol] = g; let result; try { result = await graphql.graphql(this.getGraphQuerySchema(ctx), g, null, ctx); } catch (e) { result = { errors: e.message || e }; } if (result.errors) { response.statusCode = 400; response.setHeader("ContentType", "application/json"); response.end(JSON.stringify(result.errors)); return; } response.setHeader('Content-Type', 'text/event-stream'); response.setHeader('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate'); response.setHeader('Pragma', 'no-cache'); response.setHeader('Access-Control-Allow-Origin', '*'); response.flushHeaders(); let self = this; let id = ctx.requestData.correlationId; let subscription = messageBus_1.MessageBus.localEvents.subscribe(async function onNext(evt) { let eventHandlerName = evt[messageBus_1.MessageBus.LocalEventSymbol]; let item = self._subscriptions.get(id); if (!item) return; let g = item.subscriptions[eventHandlerName]; if (!g) return; // Verify authorization if (item.scope && !ctx.user.hasScope(item.scope)) { ctx.logError(new Error(`Unauthorized for handler ${conventions_1.Conventions.instance.defaultGraphQLSubscriptionPath} with scope=${item.scope}`), () => `Current user is user=${ctx.user.name}, scopes=${ctx.user.scopes}`); throw new applicationRequestError_1.UnauthorizedRequestError(); } let result = await graphql.graphql(self.getGraphQuerySchema(ctx), g, evt.value, ctx); let payload = { [eventHandlerName]: result && result.data && result.data[eventHandlerName], action: evt.action, schema: evt.schema, error: evt.error }; //response.write("event: " + eventHandlerName + '\n'); response.write("id: " + evt.correlationId + '\n'); response.write("data: " + JSON.stringify(payload) + '\n\n'); }); request.on("close", () => { self._subscriptions.delete(id); if (subscription) subscription.unsubscribe(); }); }; } }; GraphQLAdapter = __decorate([ annotations_1.Injectable(annotations_1.LifeTime.Singleton, annotations_1.DefaultServiceNames.GraphQLAdapter), __param(0, annotations_2.Inject(annotations_1.DefaultServiceNames.Container)), __metadata("design:paramtypes", [Object]) ], GraphQLAdapter); exports.GraphQLAdapter = GraphQLAdapter; //# sourceMappingURL=graphQLAdapter.js.map