@fluojs/graphql 1.0.3 → 1.1.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.
- package/README.ko.md +95 -7
- package/README.md +95 -7
- package/dist/decorators.d.ts +39 -0
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +102 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/metadata.d.ts +21 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +68 -7
- package/dist/node/graphql-websocket-transport.d.ts +36 -0
- package/dist/node/graphql-websocket-transport.d.ts.map +1 -0
- package/dist/node/graphql-websocket-transport.js +156 -0
- package/dist/schema/object-field-resolvers.d.ts +17 -0
- package/dist/schema/object-field-resolvers.d.ts.map +1 -0
- package/dist/schema/object-field-resolvers.js +78 -0
- package/dist/schema/schema.d.ts +5 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +75 -39
- package/dist/service.d.ts +3 -7
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +56 -156
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/transport/transport.js +8 -3
- package/dist/types.d.ts +16 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -1
- package/package.json +7 -7
package/dist/service.js
CHANGED
|
@@ -4,14 +4,9 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
4
4
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
5
|
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
6
|
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
8
|
-
import { createRequire } from 'node:module';
|
|
9
|
-
import { Controller, Get, Post } from '@fluojs/http';
|
|
10
7
|
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { Controller, Get, Post } from '@fluojs/http';
|
|
11
9
|
import { APPLICATION_LOGGER, COMPILED_MODULES, HTTP_APPLICATION_ADAPTER, RUNTIME_CONTAINER } from '@fluojs/runtime/internal';
|
|
12
|
-
import { handleProtocols } from 'graphql-ws';
|
|
13
|
-
import { useServer } from 'graphql-ws/lib/use/ws';
|
|
14
|
-
import { WebSocketServer } from 'ws';
|
|
15
10
|
import { discoverResolverDescriptors } from './discovery.js';
|
|
16
11
|
import { createGraphqlValidationPlugin, resolveGraphqlRequestLimits } from './guardrails.js';
|
|
17
12
|
import { GRAPHQL_INTERNAL_MODULE_OPTIONS_TOKEN } from './internal-tokens.js';
|
|
@@ -24,13 +19,6 @@ const DEFAULT_GRAPHQL_WEBSOCKET_LIMITS = {
|
|
|
24
19
|
maxOperationsPerConnection: 25,
|
|
25
20
|
maxPayloadBytes: 64 * 1024
|
|
26
21
|
};
|
|
27
|
-
function hasNodeUpgradeServer(value) {
|
|
28
|
-
if (typeof value !== 'object' || value === null) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
const server = value;
|
|
32
|
-
return typeof server.on === 'function' && typeof server.off === 'function';
|
|
33
|
-
}
|
|
34
22
|
function buildFrameworkRequestFromFetchRequest(request) {
|
|
35
23
|
const requestUrl = new URL(request.url);
|
|
36
24
|
return {
|
|
@@ -45,39 +33,6 @@ function buildFrameworkRequestFromFetchRequest(request) {
|
|
|
45
33
|
url: requestUrl.pathname + requestUrl.search
|
|
46
34
|
};
|
|
47
35
|
}
|
|
48
|
-
function buildFrameworkRequestFromIncomingMessage(request) {
|
|
49
|
-
const requestUrl = new URL(request.url ?? '/graphql', 'http://localhost');
|
|
50
|
-
return {
|
|
51
|
-
cookies: {},
|
|
52
|
-
headers: request.headers,
|
|
53
|
-
method: request.method ?? 'GET',
|
|
54
|
-
params: {},
|
|
55
|
-
path: requestUrl.pathname,
|
|
56
|
-
query: Object.fromEntries(requestUrl.searchParams.entries()),
|
|
57
|
-
raw: request,
|
|
58
|
-
url: requestUrl.pathname + requestUrl.search
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function isConnectionParamsRecord(value) {
|
|
62
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
63
|
-
}
|
|
64
|
-
function closeWebSocketServer(server) {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
server.close(error => {
|
|
67
|
-
if (error?.message === 'The server is not running') {
|
|
68
|
-
resolve();
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (error) {
|
|
72
|
-
reject(error);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
resolve();
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
const graphqlRequestContextStorage = new AsyncLocalStorage();
|
|
80
|
-
const runtimeRequire = createRequire(import.meta.url);
|
|
81
36
|
let graphqlInstanceOfPatchRefCount = 0;
|
|
82
37
|
let restoreGraphqlInstanceOfPatch;
|
|
83
38
|
const allowedCrossRealmGraphqlObjects = new WeakSet();
|
|
@@ -108,16 +63,17 @@ class GraphqlEndpointController {
|
|
|
108
63
|
}
|
|
109
64
|
export { _GraphqlEndpointContr as GraphqlEndpointController };
|
|
110
65
|
function getCrossRealmGraphqlTag(value, constructor) {
|
|
111
|
-
const
|
|
66
|
+
const prototypeTag = constructor.prototype?.[Symbol.toStringTag];
|
|
67
|
+
const className = typeof prototypeTag === 'string' ? prototypeTag : constructor.name;
|
|
112
68
|
if (typeof className !== 'string' || !className.startsWith('GraphQL')) {
|
|
113
69
|
return undefined;
|
|
114
70
|
}
|
|
115
71
|
if (typeof value !== 'object' || value === null) {
|
|
116
72
|
return undefined;
|
|
117
73
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
74
|
+
const valueTag = value[Symbol.toStringTag];
|
|
75
|
+
if (typeof valueTag === 'string') {
|
|
76
|
+
return valueTag === className ? className : undefined;
|
|
121
77
|
}
|
|
122
78
|
const valueClassName = value.constructor?.name;
|
|
123
79
|
return valueClassName === className ? className : undefined;
|
|
@@ -131,7 +87,8 @@ function markAllowedCrossRealmGraphqlObjects(value, visited = new WeakSet()) {
|
|
|
131
87
|
}
|
|
132
88
|
visited.add(value);
|
|
133
89
|
const tag = value[Symbol.toStringTag];
|
|
134
|
-
|
|
90
|
+
const constructorName = value.constructor?.name;
|
|
91
|
+
if (typeof tag === 'string' && tag.startsWith('GraphQL') || typeof constructorName === 'string' && constructorName.startsWith('GraphQL')) {
|
|
135
92
|
allowedCrossRealmGraphqlObjects.add(value);
|
|
136
93
|
}
|
|
137
94
|
if (Array.isArray(value)) {
|
|
@@ -150,8 +107,7 @@ function isAllowedCrossRealmGraphqlObject(value, constructor) {
|
|
|
150
107
|
}
|
|
151
108
|
return allowedCrossRealmGraphqlObjects.has(value) && getCrossRealmGraphqlTag(value, constructor) !== undefined;
|
|
152
109
|
}
|
|
153
|
-
function installGraphqlInstanceOfPatch() {
|
|
154
|
-
const instanceOfModule = runtimeRequire('graphql/jsutils/instanceOf.js');
|
|
110
|
+
function installGraphqlInstanceOfPatch(instanceOfModule) {
|
|
155
111
|
if (restoreGraphqlInstanceOfPatch) {
|
|
156
112
|
graphqlInstanceOfPatchRefCount += 1;
|
|
157
113
|
return releaseGraphqlInstanceOfPatch;
|
|
@@ -192,8 +148,10 @@ function releaseGraphqlInstanceOfPatch() {
|
|
|
192
148
|
restoreGraphqlInstanceOfPatch = undefined;
|
|
193
149
|
}
|
|
194
150
|
async function loadGraphqlDeps() {
|
|
195
|
-
const
|
|
196
|
-
const
|
|
151
|
+
const graphqlSpecifier = 'graphql';
|
|
152
|
+
const yogaSpecifier = 'graphql-yoga';
|
|
153
|
+
const instanceOfSpecifier = 'graphql/jsutils/instanceOf.js';
|
|
154
|
+
const [graphqlMod, yogaMod, instanceOfModule] = await Promise.all([import(/* @vite-ignore */graphqlSpecifier), import(/* @vite-ignore */yogaSpecifier), import(/* @vite-ignore */instanceOfSpecifier)]);
|
|
197
155
|
return {
|
|
198
156
|
GraphQLError: graphqlMod.GraphQLError,
|
|
199
157
|
GraphQLBoolean: graphqlMod.GraphQLBoolean,
|
|
@@ -201,13 +159,16 @@ async function loadGraphqlDeps() {
|
|
|
201
159
|
GraphQLID: graphqlMod.GraphQLID,
|
|
202
160
|
GraphQLInt: graphqlMod.GraphQLInt,
|
|
203
161
|
GraphQLList: graphqlMod.GraphQLList,
|
|
162
|
+
GraphQLNonNull: graphqlMod.GraphQLNonNull,
|
|
204
163
|
GraphQLObjectType: graphqlMod.GraphQLObjectType,
|
|
205
164
|
GraphQLSchema: graphqlMod.GraphQLSchema,
|
|
206
165
|
GraphQLString: graphqlMod.GraphQLString,
|
|
207
166
|
GraphQLUnionType: graphqlMod.GraphQLUnionType,
|
|
208
167
|
buildSchema: graphqlMod.buildSchema,
|
|
168
|
+
createGraphQLError: yogaMod.createGraphQLError,
|
|
209
169
|
createYoga: yogaMod.createYoga,
|
|
210
170
|
execute: graphqlMod.execute,
|
|
171
|
+
instanceOfModule,
|
|
211
172
|
subscribe: graphqlMod.subscribe
|
|
212
173
|
};
|
|
213
174
|
}
|
|
@@ -223,11 +184,9 @@ class GraphqlLifecycleService {
|
|
|
223
184
|
graphQLErrorConstructor;
|
|
224
185
|
middlewareRegistered = false;
|
|
225
186
|
operationContainers = new WeakMap();
|
|
187
|
+
requestContexts = new WeakMap();
|
|
226
188
|
websocketOperationContainers = new Map();
|
|
227
|
-
|
|
228
|
-
websocketServer;
|
|
229
|
-
websocketUpgradeListener;
|
|
230
|
-
websocketUpgradeServer;
|
|
189
|
+
websocketTransport;
|
|
231
190
|
executeGraphqlOperation;
|
|
232
191
|
releaseGraphqlInstanceOfPatch;
|
|
233
192
|
subscribeGraphqlOperation;
|
|
@@ -251,13 +210,15 @@ class GraphqlLifecycleService {
|
|
|
251
210
|
}
|
|
252
211
|
try {
|
|
253
212
|
const fetchRequest = toFetchRequest(context.request);
|
|
213
|
+
this.requestContexts.set(fetchRequest, {
|
|
214
|
+
principal: context.requestContext.principal,
|
|
215
|
+
request: context.request
|
|
216
|
+
});
|
|
254
217
|
try {
|
|
255
|
-
const fetchResponse = await
|
|
256
|
-
principal: context.requestContext.principal,
|
|
257
|
-
request: context.request
|
|
258
|
-
}, () => yoga.fetch(fetchRequest));
|
|
218
|
+
const fetchResponse = await yoga.fetch(fetchRequest);
|
|
259
219
|
await writeFetchResponse(fetchResponse, context.response);
|
|
260
220
|
} finally {
|
|
221
|
+
this.requestContexts.delete(fetchRequest);
|
|
261
222
|
await this.disposeOperationContainer(fetchRequest);
|
|
262
223
|
}
|
|
263
224
|
} catch (error) {
|
|
@@ -304,7 +265,7 @@ class GraphqlLifecycleService {
|
|
|
304
265
|
} : {}),
|
|
305
266
|
schema
|
|
306
267
|
});
|
|
307
|
-
this.registerWebSocketTransport();
|
|
268
|
+
await this.registerWebSocketTransport();
|
|
308
269
|
this.registerMiddleware();
|
|
309
270
|
this.middlewareRegistered = true;
|
|
310
271
|
} catch (error) {
|
|
@@ -348,7 +309,7 @@ class GraphqlLifecycleService {
|
|
|
348
309
|
};
|
|
349
310
|
}
|
|
350
311
|
resolveSchema(deps) {
|
|
351
|
-
this.releaseGraphqlInstanceOfPatch ??= installGraphqlInstanceOfPatch();
|
|
312
|
+
this.releaseGraphqlInstanceOfPatch ??= installGraphqlInstanceOfPatch(deps.instanceOfModule);
|
|
352
313
|
return resolveSchema(deps, this.options.schema, () => this.createCodeFirstSchema(deps), markAllowedCrossRealmGraphqlObjects);
|
|
353
314
|
}
|
|
354
315
|
createCodeFirstSchema(deps) {
|
|
@@ -386,7 +347,7 @@ class GraphqlLifecycleService {
|
|
|
386
347
|
}
|
|
387
348
|
}
|
|
388
349
|
buildGraphqlContext(request, requestContextOverride, operationContainerOverride) {
|
|
389
|
-
const storedContext =
|
|
350
|
+
const storedContext = this.requestContexts.get(request);
|
|
390
351
|
const requestContext = {
|
|
391
352
|
connectionParams: requestContextOverride?.connectionParams,
|
|
392
353
|
principal: requestContextOverride?.principal ?? storedContext?.principal,
|
|
@@ -404,85 +365,44 @@ class GraphqlLifecycleService {
|
|
|
404
365
|
[GRAPHQL_OPERATION_CONTAINER]: operationContainer
|
|
405
366
|
};
|
|
406
367
|
}
|
|
407
|
-
registerWebSocketTransport() {
|
|
408
|
-
if (!this.isWebSocketTransportEnabled() || this.yoga === undefined || this.
|
|
368
|
+
async registerWebSocketTransport() {
|
|
369
|
+
if (!this.isWebSocketTransportEnabled() || this.yoga === undefined || this.websocketTransport !== undefined) {
|
|
409
370
|
return;
|
|
410
371
|
}
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
});
|
|
418
|
-
const upgradeListener = (request, socket, head) => {
|
|
419
|
-
const targetPath = new URL(request.url ?? '/', 'http://localhost').pathname;
|
|
420
|
-
if (!isGraphqlPath(targetPath)) {
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (websocketLimits && websocketServer.clients.size >= websocketLimits.maxConnections) {
|
|
424
|
-
this.rejectWebSocketUpgrade(socket, 503, 'GraphQL websocket connection count exceeds the configured limit.');
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
websocketServer.handleUpgrade(request, socket, head, websocket => {
|
|
428
|
-
websocketServer.emit('connection', websocket, request);
|
|
429
|
-
});
|
|
430
|
-
};
|
|
431
|
-
const websocketDisposable = useServer({
|
|
432
|
-
connectionInitWaitTimeout: this.options.subscriptions?.websocket?.connectionInitWaitTimeoutMs,
|
|
372
|
+
const {
|
|
373
|
+
createNodeGraphqlWebSocketTransport
|
|
374
|
+
} = await import('./node/graphql-websocket-transport.js');
|
|
375
|
+
this.websocketTransport = await createNodeGraphqlWebSocketTransport({
|
|
376
|
+
adapter: this.adapter,
|
|
377
|
+
connectionInitWaitTimeoutMs: this.options.subscriptions?.websocket?.connectionInitWaitTimeoutMs,
|
|
433
378
|
execute: args => {
|
|
434
379
|
if (!this.executeGraphqlOperation) {
|
|
435
380
|
throw new Error('GraphQL execute function not initialized.');
|
|
436
381
|
}
|
|
437
382
|
return this.executeGraphqlOperation(args);
|
|
438
383
|
},
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
onDisconnect:
|
|
443
|
-
|
|
444
|
-
},
|
|
445
|
-
onSubscribe: async (context, message) => this.handleWebSocketSubscribe(context, message.id, message.payload),
|
|
384
|
+
keepAliveMs: this.options.subscriptions?.websocket?.keepAliveMs,
|
|
385
|
+
limits: this.resolveWebSocketLimits(),
|
|
386
|
+
onComplete: (socketKey, operationId) => this.disposeWebSocketOperationContainer(socketKey, operationId),
|
|
387
|
+
onDisconnect: socketKey => this.disposeAllWebSocketOperationContainers(socketKey),
|
|
388
|
+
onSubscribe: request => this.handleWebSocketSubscribe(request),
|
|
446
389
|
subscribe: args => {
|
|
447
390
|
if (!this.subscribeGraphqlOperation) {
|
|
448
391
|
throw new Error('GraphQL subscribe function not initialized.');
|
|
449
392
|
}
|
|
450
393
|
return this.subscribeGraphqlOperation(args);
|
|
451
394
|
}
|
|
452
|
-
}
|
|
453
|
-
upgradeServer.on('upgrade', upgradeListener);
|
|
454
|
-
this.websocketDisposable = websocketDisposable;
|
|
455
|
-
this.websocketServer = websocketServer;
|
|
456
|
-
this.websocketUpgradeListener = upgradeListener;
|
|
457
|
-
this.websocketUpgradeServer = upgradeServer;
|
|
395
|
+
});
|
|
458
396
|
}
|
|
459
397
|
async unregisterWebSocketTransport() {
|
|
460
|
-
if (this.
|
|
461
|
-
this.websocketUpgradeServer.off('upgrade', this.websocketUpgradeListener);
|
|
462
|
-
}
|
|
463
|
-
this.websocketUpgradeListener = undefined;
|
|
464
|
-
this.websocketUpgradeServer = undefined;
|
|
465
|
-
if (this.websocketServer) {
|
|
466
|
-
for (const client of this.websocketServer.clients) {
|
|
467
|
-
client.terminate();
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
if (this.websocketDisposable) {
|
|
398
|
+
if (this.websocketTransport) {
|
|
471
399
|
try {
|
|
472
|
-
await this.
|
|
400
|
+
await this.websocketTransport.dispose();
|
|
473
401
|
} catch (error) {
|
|
474
402
|
this.logger.error('Failed to dispose GraphQL websocket transport.', error, 'GraphqlLifecycleService');
|
|
475
403
|
}
|
|
476
404
|
}
|
|
477
|
-
this.
|
|
478
|
-
if (this.websocketServer) {
|
|
479
|
-
try {
|
|
480
|
-
await closeWebSocketServer(this.websocketServer);
|
|
481
|
-
} catch (error) {
|
|
482
|
-
this.logger.error('Failed to close GraphQL websocket server.', error, 'GraphqlLifecycleService');
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
this.websocketServer = undefined;
|
|
405
|
+
this.websocketTransport = undefined;
|
|
486
406
|
for (const socketKey of this.websocketOperationContainers.keys()) {
|
|
487
407
|
await this.disposeAllWebSocketOperationContainers(socketKey);
|
|
488
408
|
}
|
|
@@ -490,32 +410,21 @@ class GraphqlLifecycleService {
|
|
|
490
410
|
isWebSocketTransportEnabled() {
|
|
491
411
|
return this.options.subscriptions?.websocket?.enabled === true;
|
|
492
412
|
}
|
|
493
|
-
|
|
494
|
-
if (typeof this.adapter.getServer !== 'function') {
|
|
495
|
-
throw new Error('GraphQL websocket subscriptions require an HTTP adapter with getServer(). Use the Node HTTP adapter or provide a compatible adapter implementation.');
|
|
496
|
-
}
|
|
497
|
-
const server = this.adapter.getServer();
|
|
498
|
-
if (!hasNodeUpgradeServer(server)) {
|
|
499
|
-
throw new Error('GraphQL websocket subscriptions require adapter.getServer() to return a Node HTTP/S server that supports upgrade listeners.');
|
|
500
|
-
}
|
|
501
|
-
return server;
|
|
502
|
-
}
|
|
503
|
-
async handleWebSocketSubscribe(context, operationId, payload) {
|
|
413
|
+
async handleWebSocketSubscribe(request) {
|
|
504
414
|
const yoga = this.yoga;
|
|
505
415
|
if (!yoga) {
|
|
506
416
|
throw new Error('GraphQL server not initialized.');
|
|
507
417
|
}
|
|
508
|
-
const websocketLimitError = this.createWebSocketOperationLimitError(
|
|
418
|
+
const websocketLimitError = this.createWebSocketOperationLimitError(request.socket, request.operationId);
|
|
509
419
|
if (websocketLimitError) {
|
|
510
420
|
return [websocketLimitError];
|
|
511
421
|
}
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
const operationContainer = this.getOrCreateWebSocketOperationContainer(context.extra.socket, operationId);
|
|
422
|
+
const fetchRequest = toFetchRequest(request.request);
|
|
423
|
+
const operationContainer = this.getOrCreateWebSocketOperationContainer(request.socket, request.operationId);
|
|
515
424
|
const graphqlContext = this.buildGraphqlContext(fetchRequest, {
|
|
516
|
-
connectionParams:
|
|
517
|
-
request:
|
|
518
|
-
socket:
|
|
425
|
+
connectionParams: request.connectionParams,
|
|
426
|
+
request: request.request,
|
|
427
|
+
socket: request.socket
|
|
519
428
|
}, operationContainer);
|
|
520
429
|
try {
|
|
521
430
|
const {
|
|
@@ -527,21 +436,21 @@ class GraphqlLifecycleService {
|
|
|
527
436
|
request: fetchRequest,
|
|
528
437
|
[GRAPHQL_CONTEXT_OVERRIDE]: graphqlContext
|
|
529
438
|
});
|
|
530
|
-
const document = parse(payload.query);
|
|
439
|
+
const document = parse(request.payload.query);
|
|
531
440
|
const validationErrors = validate(schema, document);
|
|
532
441
|
if (validationErrors.length > 0) {
|
|
533
|
-
await this.disposeWebSocketOperationContainer(
|
|
442
|
+
await this.disposeWebSocketOperationContainer(request.socket, request.operationId);
|
|
534
443
|
return validationErrors;
|
|
535
444
|
}
|
|
536
445
|
return {
|
|
537
446
|
contextValue: await contextFactory(),
|
|
538
447
|
document,
|
|
539
|
-
operationName: payload.operationName ?? undefined,
|
|
448
|
+
operationName: request.payload.operationName ?? undefined,
|
|
540
449
|
schema,
|
|
541
|
-
variableValues: payload.variables
|
|
450
|
+
variableValues: request.payload.variables
|
|
542
451
|
};
|
|
543
452
|
} catch (error) {
|
|
544
|
-
await this.disposeWebSocketOperationContainer(
|
|
453
|
+
await this.disposeWebSocketOperationContainer(request.socket, request.operationId);
|
|
545
454
|
throw error;
|
|
546
455
|
}
|
|
547
456
|
}
|
|
@@ -560,15 +469,6 @@ class GraphqlLifecycleService {
|
|
|
560
469
|
}
|
|
561
470
|
return new GraphQLError(`GraphQL websocket active operation count exceeds the configured limit of ${String(limits.maxOperationsPerConnection)}.`);
|
|
562
471
|
}
|
|
563
|
-
rejectWebSocketUpgrade(socket, statusCode, message) {
|
|
564
|
-
if (!socket.writable) {
|
|
565
|
-
socket.destroy();
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
const body = `${message}\n`;
|
|
569
|
-
socket.write([`HTTP/1.1 ${String(statusCode)} ${statusCode === 503 ? 'Service Unavailable' : 'Bad Request'}`, 'Connection: close', 'Content-Type: text/plain; charset=utf-8', `Content-Length: ${String(Buffer.byteLength(body))}`, '', body].join('\r\n'));
|
|
570
|
-
socket.destroy();
|
|
571
|
-
}
|
|
572
472
|
getOrCreateWebSocketOperationContainer(socketKey, operationId) {
|
|
573
473
|
const existingSocketContainers = this.websocketOperationContainers.get(socketKey);
|
|
574
474
|
if (existingSocketContainers?.has(operationId)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAA2B,MAAM,cAAc,CAAC;AAEjG;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAA2B,MAAM,cAAc,CAAC;AAEjG;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AA6ED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAUjE;AAgGD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BrH"}
|
|
@@ -34,13 +34,18 @@ function createFetchHeaders(request) {
|
|
|
34
34
|
}
|
|
35
35
|
return headers;
|
|
36
36
|
}
|
|
37
|
+
function copyBytesToArrayBuffer(bytes) {
|
|
38
|
+
const body = new ArrayBuffer(bytes.byteLength);
|
|
39
|
+
new Uint8Array(body).set(bytes);
|
|
40
|
+
return body;
|
|
41
|
+
}
|
|
37
42
|
function createFetchBody(request, headers) {
|
|
38
43
|
const method = request.method.toUpperCase();
|
|
39
44
|
if (method === 'GET' || method === 'HEAD') {
|
|
40
45
|
return undefined;
|
|
41
46
|
}
|
|
42
47
|
if (request.rawBody) {
|
|
43
|
-
return
|
|
48
|
+
return copyBytesToArrayBuffer(request.rawBody);
|
|
44
49
|
}
|
|
45
50
|
if (request.body === undefined) {
|
|
46
51
|
return undefined;
|
|
@@ -49,10 +54,10 @@ function createFetchBody(request, headers) {
|
|
|
49
54
|
return request.body;
|
|
50
55
|
}
|
|
51
56
|
if (request.body instanceof Uint8Array) {
|
|
52
|
-
return
|
|
57
|
+
return copyBytesToArrayBuffer(request.body);
|
|
53
58
|
}
|
|
54
59
|
if (request.body instanceof ArrayBuffer) {
|
|
55
|
-
return
|
|
60
|
+
return request.body;
|
|
56
61
|
}
|
|
57
62
|
if (!headers.has('content-type')) {
|
|
58
63
|
headers.set('content-type', 'application/json; charset=utf-8');
|
package/dist/types.d.ts
CHANGED
|
@@ -99,9 +99,20 @@ export interface ResolverMetadata {
|
|
|
99
99
|
typeName: string;
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
-
* Supported GraphQL operation handler categories.
|
|
102
|
+
* Supported GraphQL root-operation and object-field handler categories.
|
|
103
103
|
*/
|
|
104
|
-
export type ResolverHandlerType = 'query' | 'mutation' | 'subscription';
|
|
104
|
+
export type ResolverHandlerType = 'query' | 'mutation' | 'subscription' | 'field';
|
|
105
|
+
/**
|
|
106
|
+
* Explicit source kinds that can be bound to object field-resolver parameters.
|
|
107
|
+
*/
|
|
108
|
+
export type FieldResolverParameterKind = 'parent' | 'context';
|
|
109
|
+
/**
|
|
110
|
+
* Describes one positional parameter binding for an object field resolver.
|
|
111
|
+
*/
|
|
112
|
+
export interface FieldResolverParameterBindingMetadata {
|
|
113
|
+
index: number;
|
|
114
|
+
kind: FieldResolverParameterKind;
|
|
115
|
+
}
|
|
105
116
|
/**
|
|
106
117
|
* Scalar names supported by the code-first schema helpers.
|
|
107
118
|
*/
|
|
@@ -157,6 +168,7 @@ export interface ResolverHandlerMetadata {
|
|
|
157
168
|
inputClass?: Function;
|
|
158
169
|
argTypes?: Record<string, GraphqlArgType>;
|
|
159
170
|
outputType?: GraphqlRootOutputType;
|
|
171
|
+
nullable?: boolean;
|
|
160
172
|
}
|
|
161
173
|
/**
|
|
162
174
|
* Describes how one method parameter maps to a named GraphQL argument.
|
|
@@ -177,6 +189,8 @@ export interface ResolverHandlerDescriptor {
|
|
|
177
189
|
argFields: ArgFieldMetadata[];
|
|
178
190
|
argTypes?: Record<string, GraphqlArgType>;
|
|
179
191
|
outputType?: GraphqlRootOutputType;
|
|
192
|
+
nullable?: boolean;
|
|
193
|
+
parameterBindings: FieldResolverParameterBindingMetadata[];
|
|
180
194
|
}
|
|
181
195
|
/**
|
|
182
196
|
* Fully discovered resolver descriptor used by the GraphQL runtime.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAElF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,eAAiD,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,eAAyD,CAAC;AAE1G;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,CAAC,2BAA2B,CAAC,CAAC,EAAE,SAAS,CAAC;IAC1C,CAAC,mCAAmC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,oCAAoC;IACnD,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,6BAA6B,GAAG,KAAK,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,oCAAoC,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -48,7 +48,15 @@ export const GRAPHQL_REQUEST_SCOPED_LOADER_CACHE = Symbol.for('fluo.graphql.requ
|
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* Supported GraphQL operation handler categories.
|
|
51
|
+
* Supported GraphQL root-operation and object-field handler categories.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Explicit source kinds that can be bound to object field-resolver parameters.
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Describes one positional parameter binding for an object field resolver.
|
|
52
60
|
*/
|
|
53
61
|
|
|
54
62
|
/**
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"yoga",
|
|
10
10
|
"api"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.0
|
|
12
|
+
"version": "1.1.0",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"directory": "packages/graphql"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=20.
|
|
21
|
+
"node": ">=20.16.0"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"graphql-ws": "^5.16.2",
|
|
42
42
|
"graphql-yoga": "^5.18.1",
|
|
43
43
|
"ws": "^8.18.3",
|
|
44
|
-
"@fluojs/core": "^1.0
|
|
45
|
-
"@fluojs/di": "^
|
|
46
|
-
"@fluojs/http": "^
|
|
47
|
-
"@fluojs/runtime": "^
|
|
48
|
-
"@fluojs/validation": "^1.0.
|
|
44
|
+
"@fluojs/core": "^1.1.0",
|
|
45
|
+
"@fluojs/di": "^2.0.0",
|
|
46
|
+
"@fluojs/http": "^2.0.1",
|
|
47
|
+
"@fluojs/runtime": "^2.0.1",
|
|
48
|
+
"@fluojs/validation": "^1.0.6"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/ws": "^8.18.1",
|