1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | return new (P || (P = Promise))(function (resolve, reject) {
|
4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
7 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8 | });
|
9 | };
|
10 | Object.defineProperty(exports, "__esModule", { value: true });
|
11 | const events_1 = require("events");
|
12 | const path_1 = require("path");
|
13 | const core_1 = require("@cortexql/core");
|
14 | const paths_1 = require("../paths");
|
15 | const expressRequestContextParams_1 = require("../hooks/expressRequestContextParams");
|
16 | const webSocketTransportContextParams_1 = require("../hooks/webSocketTransportContextParams");
|
17 | const context_1 = require("../hooks/context");
|
18 | const contextExecution_1 = require("../hooks/contextExecution");
|
19 | const __1 = require("..");
|
20 | const getSchema_1 = require("../api/getSchema");
|
21 | const contextId_1 = require("../hooks/contextId");
|
22 | const contextExecutionId_1 = require("../hooks/contextExecutionId");
|
23 | contextId_1.default.addFilter('default', () => {
|
24 | return `${(new Date()).getTime()}.${Math.floor(Math.random() * Math.pow(10, 5))}`;
|
25 | });
|
26 | const $$executionSeq = Symbol();
|
27 | const $$end = Symbol();
|
28 | contextExecutionId_1.default.addFilter('default', (value, { context }) => {
|
29 | if (typeof context[$$executionSeq] === 'undefined') {
|
30 | context[$$executionSeq] = -1;
|
31 | }
|
32 | context[$$executionSeq] = context[$$executionSeq] + 1;
|
33 | return `${context.id}.${context[$$executionSeq]}`;
|
34 | });
|
35 | function createContextId(context) {
|
36 | return contextId_1.default.filter(null, { context });
|
37 | }
|
38 | exports.createContextId = createContextId;
|
39 | function createExecutionContextId(context, info) {
|
40 | return contextExecutionId_1.default.filter(null, { context, info });
|
41 | }
|
42 | exports.createExecutionContextId = createExecutionContextId;
|
43 | function createContextNamespace(context, info, id) {
|
44 | let { operationName, operationType, } = context;
|
45 | let namespace;
|
46 | if (typeof info !== 'undefined') {
|
47 | if (typeof operationType === 'undefined') {
|
48 | operationType = info.operation.operation;
|
49 | }
|
50 | if (typeof operationName === 'undefined'
|
51 | && typeof info.operation.name !== 'undefined') {
|
52 | operationName = info.operation.name.value;
|
53 | }
|
54 | operationType = `${operationType}.${info.fieldName}`;
|
55 | if (info.path.key !== info.fieldName) {
|
56 | if (typeof operationName === 'undefined') {
|
57 | operationName = '';
|
58 | }
|
59 | operationName = `${operationName}.${info.path.key}`;
|
60 | }
|
61 | }
|
62 | if (typeof operationType !== 'undefined') {
|
63 | namespace = `${operationType}`;
|
64 | }
|
65 | else {
|
66 | namespace = '';
|
67 | }
|
68 | if (typeof operationName !== 'undefined') {
|
69 | namespace = `${namespace}@${operationName}`;
|
70 | }
|
71 | return `${namespace}::${typeof id !== 'undefined' ? id : context.id}`;
|
72 | }
|
73 | exports.createContextNamespace = createContextNamespace;
|
74 | class BaseContext {
|
75 | constructor(params, operationName, operationType, id) {
|
76 | this.params = params;
|
77 | this.operationName = operationName;
|
78 | this.operationType = operationType;
|
79 | this.id = id;
|
80 | this.context = undefined;
|
81 | this.debug = ((...args) => {
|
82 | Object.defineProperty(this, 'debug', {
|
83 | configurable: true,
|
84 | value: core_1.debug(createContextNamespace(this)),
|
85 | });
|
86 | return this.debug(...args);
|
87 | });
|
88 | this.event = new events_1.EventEmitter();
|
89 | this.schema = getSchema_1.getSchema();
|
90 | this[$$end] = [];
|
91 | this.execute = (document, variableValues, operationName) => __awaiter(this, void 0, void 0, function* () { return __1.execute(document, this.params, variableValues, operationName); });
|
92 | this.subscribe = (document, variableValues, operationName) => __awaiter(this, void 0, void 0, function* () { return __1.subscribe(document, this.params, variableValues, operationName); });
|
93 | Object.defineProperty(this, 'completed', { value: false, configurable: true });
|
94 | if (typeof this.id === 'undefined') {
|
95 | this.id = createContextId(this);
|
96 | }
|
97 | }
|
98 | destroy(handler) {
|
99 | return this.once('destroy', handler);
|
100 | }
|
101 | on(event, handler) {
|
102 | return this.event.on(event, handler);
|
103 | }
|
104 | once(event, handler) {
|
105 | return this.event.once(event, handler);
|
106 | }
|
107 | removeListener(event, handler) {
|
108 | return this.event.removeListener(event, handler);
|
109 | }
|
110 | removeAllListeners(event) {
|
111 | return this.event.removeAllListeners(event);
|
112 | }
|
113 | emit(event, ...args) {
|
114 | return this.event.emit(event, ...args);
|
115 | }
|
116 | execution(info) {
|
117 | return createExecutionContext(this, info);
|
118 | }
|
119 | end(value, reason) {
|
120 | if (typeof value === 'function') {
|
121 | if (this.completed) {
|
122 | process.nextTick(value);
|
123 | }
|
124 | else {
|
125 | this[$$end].push(value);
|
126 | }
|
127 | }
|
128 | else {
|
129 | let self = this;
|
130 | return (() => __awaiter(this, void 0, void 0, function* () {
|
131 | if (self.completed) {
|
132 | throw new Error('The execution has already ended');
|
133 | }
|
134 | Object.defineProperty(self, 'completed', { value: true });
|
135 | self.completionReason = reason;
|
136 | if (value instanceof Error) {
|
137 | self.completionError = value;
|
138 | }
|
139 | const handlers = self[$$end].splice(0, self[$$end].length);
|
140 | yield Promise.all(handlers.map((handler) => __awaiter(this, void 0, void 0, function* () { return handler(self.completionError, self.completionReason); })));
|
141 | self.event.emit('destroy', self.completionError, this.completionReason);
|
142 | }))().catch(error => {
|
143 | console.log(error.stack);
|
144 | });
|
145 | }
|
146 | }
|
147 | }
|
148 | exports.BaseContext = BaseContext;
|
149 | ;
|
150 | class BaseExecutionContext {
|
151 | constructor(context, info) {
|
152 | this.context = context;
|
153 | this.info = info;
|
154 | this.executionEvent = new events_1.EventEmitter();
|
155 | this.isExecution = true;
|
156 | this.id = createExecutionContextId(context, info);
|
157 | const namespace = createContextNamespace(context, info, this.id);
|
158 | this.debug = core_1.debug(namespace);
|
159 | this[$$end] = [];
|
160 | Object.defineProperty(this, 'completed', { value: false, configurable: true });
|
161 | }
|
162 | destroy(handler) {
|
163 | return this.once('destroy', handler);
|
164 | }
|
165 | on(event, handler) {
|
166 | return this.executionEvent.on(event, handler);
|
167 | }
|
168 | once(event, handler) {
|
169 | return this.executionEvent.once(event, handler);
|
170 | }
|
171 | removeListener(event, handler) {
|
172 | return this.executionEvent.removeListener(event, handler);
|
173 | }
|
174 | removeAllListeners(event) {
|
175 | return this.executionEvent.removeAllListeners(event);
|
176 | }
|
177 | emit(event, ...args) {
|
178 | return this.executionEvent.emit(event, ...args);
|
179 | }
|
180 | end(value, reason) {
|
181 | if (typeof value === 'function') {
|
182 | if (this.completed) {
|
183 | process.nextTick(value);
|
184 | }
|
185 | else {
|
186 | this[$$end].push(value);
|
187 | }
|
188 | }
|
189 | else {
|
190 | let self = this;
|
191 | return (() => __awaiter(this, void 0, void 0, function* () {
|
192 | if (self.completed) {
|
193 | throw new Error('The execution has already ended');
|
194 | }
|
195 | Object.defineProperty(self, 'completed', { value: true });
|
196 | self.completionReason = reason;
|
197 | if (value instanceof Error) {
|
198 | self.completionError = value;
|
199 | }
|
200 | const handlers = self[$$end].splice(0, self[$$end].length);
|
201 | yield Promise.all(handlers.map((handler) => __awaiter(this, void 0, void 0, function* () { return handler(self.completionError, self.completionReason); })));
|
202 | self.executionEvent.emit('destroy', self.completionError, this.completionReason);
|
203 | }))().catch(error => {
|
204 | console.log(error.stack);
|
205 | });
|
206 | }
|
207 | }
|
208 | }
|
209 | exports.BaseExecutionContext = BaseExecutionContext;
|
210 | function createContext(params, operationName, operationType, executionId) {
|
211 | return __awaiter(this, void 0, void 0, function* () {
|
212 | const { Context } = require(path_1.resolve(paths_1.getApiPath(), 'context'));
|
213 | let context = new Context(params, operationName, operationType, executionId);
|
214 | yield context_1.default.do({ context, params });
|
215 | return context;
|
216 | });
|
217 | }
|
218 | exports.createContext = createContext;
|
219 | function createExecutionContext(context, info) {
|
220 | return __awaiter(this, void 0, void 0, function* () {
|
221 | const execution = new BaseExecutionContext(context, info);
|
222 | yield contextExecution_1.default.do({ execution, context, info });
|
223 | return Object.assign(execution, Object.assign({}, context, execution));
|
224 | });
|
225 | }
|
226 | exports.createExecutionContext = createExecutionContext;
|
227 | function getOperationFromQuery(query) {
|
228 | const match = query.match(/^\s*([^\s]+)(?:\s+([^\s]+))?\s*{/);
|
229 | if (match != null) {
|
230 | return {
|
231 | operationName: match[2],
|
232 | operationType: match[1],
|
233 | };
|
234 | }
|
235 | return {
|
236 | operationName: undefined,
|
237 | operationType: undefined,
|
238 | };
|
239 | }
|
240 | exports.getOperationFromQuery = getOperationFromQuery;
|
241 | function createContextFromExpressRequest(req, params) {
|
242 | return __awaiter(this, void 0, void 0, function* () {
|
243 | let contextParams = Object.assign({}, params);
|
244 | contextParams = expressRequestContextParams_1.default.filter(contextParams, { req, params });
|
245 | const query = req.method === 'POST' ? req.body.query : req.query;
|
246 | const { operationName, operationType, } = getOperationFromQuery(query);
|
247 | return yield createContext(contextParams, operationName, operationType);
|
248 | });
|
249 | }
|
250 | exports.createContextFromExpressRequest = createContextFromExpressRequest;
|
251 | function createContextFromWebSocketTransport(webSocket, message, params) {
|
252 | return __awaiter(this, void 0, void 0, function* () {
|
253 | let contextParams = Object.assign({}, (typeof message !== 'undefined' && typeof message.payload !== 'undefined' ? message.payload.context : null));
|
254 | contextParams = webSocketTransportContextParams_1.default.filter(contextParams, { webSocket, message, params });
|
255 | let operationName;
|
256 | let operationType;
|
257 | if (typeof params.query === 'string') {
|
258 | ({
|
259 | operationName,
|
260 | operationType,
|
261 | } = getOperationFromQuery(params.query));
|
262 | }
|
263 | return yield createContext(contextParams, operationName, operationType);
|
264 | });
|
265 | }
|
266 | exports.createContextFromWebSocketTransport = createContextFromWebSocketTransport;
|
267 |
|
\ | No newline at end of file |