Skip to content

Commit 3266d69

Browse files
committed
Go
1 parent bf661cb commit 3266d69

File tree

11 files changed

+310
-57
lines changed

11 files changed

+310
-57
lines changed

babel.config.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module.exports = {
77
'@babel/preset-typescript',
88
],
99
plugins: [
10+
['@babel/plugin-transform-class-static-block', { version: '2023-11' }],
11+
['@babel/plugin-proposal-decorators', { version: '2023-11' }],
1012
'@babel/plugin-transform-class-properties',
1113
'@babel/plugin-proposal-explicit-resource-management',
1214
],

e2e/nestjs/nestjs.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { expect, it } from 'vitest';
66
const { service } = createTenv(__dirname);
77
const { supergraph, query, result } = createExampleSetup(__dirname);
88

9-
it('executes the query', async () => {
9+
it.todo('executes the query', async () => {
1010
const supergraphPath = await supergraph();
1111
const { port } = await service('nestjs', {
1212
args: [`--supergraph=${supergraphPath}`],

e2e/nestjs/services/nestjs.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { HiveGatewayDriver, HiveGatewayDriverConfig } from "@graphql-hive/nestjs";
2+
import { Opts } from "@internal/testing";
3+
import { Module } from "@nestjs/common";
4+
import { GraphQLModule } from "@nestjs/graphql";
5+
6+
const opts = Opts(process.argv);
7+
const supergraph = opts.get('supergraph', true);
8+
9+
@Module({
10+
imports: [
11+
GraphQLModule.forRoot<HiveGatewayDriverConfig>({
12+
driver: HiveGatewayDriver,
13+
supergraph,
14+
}),
15+
],
16+
})
17+
export class AppModule { }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NestFactory } from "@nestjs/core";
2+
import { AppModule } from "./app.module";
3+
import { Opts } from "@internal/testing";
4+
5+
const opts = Opts(process.argv);
6+
const port = opts.getServicePort('nestjs', true);
7+
8+
async function main() {
9+
const app = await NestFactory.create(AppModule);
10+
await app.listen(port);
11+
}
12+
13+
main().catch((err) => {
14+
console.error(err);
15+
process.exit(1);
16+
});

jest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const rootDir = __dirname;
99
const tsconfigPath = resolve(rootDir, 'tsconfig.json');
1010
const tsconfigContents = readFileSync(tsconfigPath, 'utf8');
1111
const tsconfig = JSON5.parse(tsconfigContents);
12-
const ESM_PACKAGES = ['graphql-federation-gateway-audit'];
12+
const ESM_PACKAGES = ['graphql-federation-gateway-audit', 'parse-duration'];
1313

1414
export default {
1515
testEnvironment: 'node',

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
},
2828
"devDependencies": {
2929
"@babel/core": "7.26.9",
30+
"@babel/plugin-proposal-decorators": "7.25.9",
3031
"@babel/plugin-proposal-explicit-resource-management": "7.25.9",
3132
"@babel/plugin-transform-class-properties": "7.25.9",
33+
"@babel/plugin-transform-class-static-block": "7.26.0",
3234
"@babel/preset-env": "7.26.9",
3335
"@babel/preset-typescript": "7.26.0",
3436
"@changesets/changelog-github": "^0.5.0",

packages/nestjs/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"prepack": "yarn build"
4141
},
4242
"peerDependencies": {
43-
"@nestjs/common": "^11.0.10",
44-
"@nestjs/graphql": "^13.0.3",
43+
"@nestjs/common": "^10 || ^11",
44+
"@nestjs/graphql": "^12 || ^13",
4545
"graphql": "^15.9.0 || ^16.9.0"
4646
},
4747
"dependencies": {
@@ -55,11 +55,14 @@
5555
"@nestjs/common": "11.0.10",
5656
"@nestjs/core": "11.0.10",
5757
"@nestjs/graphql": "13.0.3",
58+
"@nestjs/testing": "11.0.11",
59+
"@types/supertest": "6.0.2",
5860
"fastify": "5.2.1",
5961
"graphql": "^16.9.0",
6062
"pkgroll": "2.10.0",
6163
"reflect-metadata": "0.2.2",
62-
"rxjs": "7.8.1"
64+
"rxjs": "7.8.1",
65+
"supertest": "7.0.0"
6366
},
6467
"sideEffects": false
6568
}

packages/nestjs/src/index.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ export type HiveGatewayDriverConfig<
4949
export class HiveGatewayDriver<
5050
TContext extends Record<string, any>,
5151
> extends AbstractGraphQLDriver<HiveGatewayDriverConfig<TContext>> {
52-
#gatewayRuntime: GatewayRuntime<TContext> | undefined;
53-
#subscriptionService?: GqlSubscriptionService;
52+
private _gatewayRuntime: GatewayRuntime<TContext> | undefined;
53+
private _subscriptionService?: GqlSubscriptionService;
5454

5555
public async start({
5656
schema,
@@ -87,7 +87,7 @@ export class HiveGatewayDriver<
8787
...configCtx,
8888
cache,
8989
});
90-
this.#gatewayRuntime = createGatewayRuntime({
90+
this._gatewayRuntime = createGatewayRuntime({
9191
logging: configCtx.logger,
9292
cache,
9393
graphqlEndpoint: options.path,
@@ -133,7 +133,7 @@ export class HiveGatewayDriver<
133133
options.subscriptions || { 'graphql-ws': {} };
134134
if (subscriptionsOptions['graphql-ws']) {
135135
const gwOptions = getGraphQLWSOptions<TContext, any>(
136-
this.#gatewayRuntime,
136+
this._gatewayRuntime,
137137
(ctx) => ({
138138
req: ctx.extra?.request,
139139
socket: ctx.extra?.socket,
@@ -161,7 +161,7 @@ export class HiveGatewayDriver<
161161
},
162162
ws: WebSocket,
163163
) => {
164-
if (!this.#gatewayRuntime) {
164+
if (!this._gatewayRuntime) {
165165
throw new Error('Hive Gateway is not initialized');
166166
}
167167
const {
@@ -171,7 +171,7 @@ export class HiveGatewayDriver<
171171
contextFactory,
172172
parse,
173173
validate,
174-
} = this.#gatewayRuntime.getEnveloped({
174+
} = this._gatewayRuntime.getEnveloped({
175175
...params.context,
176176
req:
177177
// @ts-expect-error upgradeReq does exist but is untyped
@@ -197,9 +197,9 @@ export class HiveGatewayDriver<
197197
return args;
198198
};
199199
}
200-
this.#subscriptionService = new GqlSubscriptionService(
200+
this._subscriptionService = new GqlSubscriptionService(
201201
{
202-
schema: await this.#gatewayRuntime.getSchema(),
202+
schema: await this._gatewayRuntime.getSchema(),
203203
path: options.path,
204204
// @ts-expect-error - We know that execute and subscribe are defined
205205
execute: (args) => args.rootValue.execute(args),
@@ -213,23 +213,23 @@ export class HiveGatewayDriver<
213213
}
214214

215215
public async stop(): Promise<void> {
216-
await this.#subscriptionService?.stop();
217-
await this.#gatewayRuntime?.dispose();
216+
await this._subscriptionService?.stop();
217+
await this._gatewayRuntime?.dispose();
218218
}
219219

220220
private registerExpress() {
221-
this.httpAdapterHost.httpAdapter.use(this.#gatewayRuntime);
221+
this.httpAdapterHost.httpAdapter.use(this._gatewayRuntime);
222222
}
223223
private registerFastify() {
224224
this.httpAdapterHost.httpAdapter
225225
.getInstance()
226226
.all('*', async (req: FastifyRequest, reply: FastifyReply) => {
227-
if (!this.#gatewayRuntime) {
227+
if (!this._gatewayRuntime) {
228228
throw new Error('Hive Gateway is not initialized');
229229
}
230230
// Second parameter adds Fastify's `req` and `reply` to the GraphQL Context
231231
const response =
232-
await this.#gatewayRuntime.handleNodeRequestAndResponse(req, reply, {
232+
await this._gatewayRuntime.handleNodeRequestAndResponse(req, reply, {
233233
req,
234234
reply,
235235
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { buildSubgraphSchema } from '@apollo/subgraph';
2+
import { AsyncDisposableStack } from '@whatwg-node/disposablestack';
3+
import {
4+
HiveGatewayDriver,
5+
HiveGatewayDriverConfig,
6+
} from '../src';
7+
import {
8+
composeLocalSchemasWithApollo,
9+
createDisposableServer,
10+
} from '@internal/testing';
11+
import { INestApplication } from '@nestjs/common';
12+
import { GraphQLModule } from '@nestjs/graphql';
13+
import { Test } from '@nestjs/testing';
14+
import { parse } from 'graphql';
15+
import { createYoga } from 'graphql-yoga';
16+
import supertest from 'supertest';
17+
import { afterAll, beforeAll, describe, it } from 'vitest';
18+
19+
describe.skipIf(process.env['LEAK_TEST'])('NestJS', () => {
20+
let app: INestApplication;
21+
const disposableStack = new AsyncDisposableStack();
22+
beforeAll(async () => {
23+
const upstreamSchema = buildSubgraphSchema({
24+
typeDefs: parse(/* GraphQL */ `
25+
type Query {
26+
hello: String!
27+
}
28+
`),
29+
resolvers: {
30+
Query: {
31+
hello: () => 'world',
32+
},
33+
},
34+
});
35+
const upstreamYoga = createYoga({
36+
schema: upstreamSchema,
37+
});
38+
disposableStack.use(upstreamYoga);
39+
const upstreamServer = await createDisposableServer(upstreamYoga);
40+
disposableStack.use(upstreamServer);
41+
const supergraph = await composeLocalSchemasWithApollo([
42+
{
43+
name: 'upstream',
44+
schema: upstreamSchema,
45+
url: `${upstreamServer.url}/graphql`,
46+
},
47+
]);
48+
const moduleRef = await Test.createTestingModule({
49+
imports: [
50+
GraphQLModule.forRoot<HiveGatewayDriverConfig>({
51+
driver: HiveGatewayDriver,
52+
supergraph,
53+
}),
54+
],
55+
}).compile();
56+
app = moduleRef.createNestApplication();
57+
disposableStack.defer(() => app.close());
58+
return app.init();
59+
});
60+
afterAll(() => disposableStack.disposeAsync());
61+
it('works', () => {
62+
return supertest(app.getHttpServer())
63+
.post('/graphql')
64+
.send({
65+
query: /* GraphQL */ `
66+
query {
67+
hello
68+
}
69+
`,
70+
})
71+
.expect(200, {
72+
data: {
73+
hello: 'world',
74+
},
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)