Skip to content

Commit

Permalink
feat(typegraphql): update code to use typegraphql 2.0.0
Browse files Browse the repository at this point in the history
BREAKING CHANGE: @tsed/typegraphql use new @tsed/apollo package and support Apollo v4
  • Loading branch information
Romakita committed Sep 14, 2024
1 parent ed3a9f2 commit 7afc1a2
Show file tree
Hide file tree
Showing 12 changed files with 627 additions and 410 deletions.
53 changes: 41 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,42 @@ jobs:
test-integration:
runs-on: ${{ matrix.os }}

strategy:
matrix:
node-version: [20.12.2]

steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: yarn install --immutable --network-timeout 500000
- name: Run build
run: yarn tsc --build
env:
FORCE_COLOR: true
- name: Run test
run: yarn test:integration
env:
FORCE_COLOR: true
- name: Upload vitest config files
uses: actions/upload-artifact@v4
with:
name: vitest-config-integration-${{ matrix.os }}-${{ matrix.version }}
overwrite: true
path: |
team.json
packages/platform/platform-express/vitest.config.mts
packages/platform/platform-koa/vitest.config.mts
continue-on-error: true

test-envs:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
Expand Down Expand Up @@ -67,16 +103,7 @@ jobs:
run: yarn test:integration
env:
FORCE_COLOR: true
- name: Upload vitest config files
uses: actions/upload-artifact@v4
with:
name: vitest-config-integration-${{ matrix.os }}-${{ matrix.version }}
overwrite: true
path: |
team.json
packages/platform/platform-express/vitest.config.mts
packages/platform/platform-koa/vitest.config.mts
continue-on-error: true

test-core:
runs-on: ubuntu-latest

Expand Down Expand Up @@ -283,7 +310,8 @@ jobs:
test-download-artifacts:
runs-on: ubuntu-latest
needs: [lint, test-core, test-specs, test-platform, test-integration, test-orm, test-security, test-graphql, test-third-parties]
needs:
[lint, test-core, test-specs, test-platform, test-integration, test-envs, test-orm, test-security, test-graphql, test-third-parties]
if: github.event_name == 'pull_request'
strategy:
matrix:
Expand All @@ -307,7 +335,8 @@ jobs:

deploy-packages:
runs-on: ubuntu-latest
needs: [lint, test-core, test-specs, test-platform, test-integration, test-orm, test-security, test-graphql, test-third-parties]
needs:
[lint, test-core, test-specs, test-platform, test-integration, test-envs, test-orm, test-security, test-graphql, test-third-parties]
if: github.event_name != 'pull_request' && contains('
refs/heads/production
refs/heads/alpha
Expand Down
33 changes: 17 additions & 16 deletions docs/tutorials/graphql-typegraphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ To begin, install the `@tsed/typegraphql` package:
<Tab label="Express.js">

```bash
npm install --save @tsed/apollo graphql type-graphql @apollo/server @apollo/datasource-rest
npm install --save @tsed/apollo graphql type-graphql @apollo/server @apollo/datasource-rest graphql-scalars
npm install --save-dev apollo-server-testing
```

</Tab>
<Tab label="Koa.js">

```bash
npm install --save @tsed/apollo graphql type-graphql @apollo/server @as-integration/koa @apollo/datasource-rest
npm install --save @tsed/apollo graphql type-graphql @apollo/server @as-integration/koa @apollo/datasource-rest graphql-scalars
npm install --save-dev apollo-server-testing
```

Expand All @@ -37,8 +37,8 @@ npm install --save-dev apollo-server-testing

Now, we can configure the Ts.ED server by importing `@tsed/typegraphql` in your Server:

<Tabs class="-code">
<Tab label="Configuration" icon="bx-code-alt">
[//]: # '<Tabs class="-code">'
[//]: # ' <Tab label="Configuration" icon="bx-code-alt">'

```ts
import {Configuration} from "@tsed/di";
Expand Down Expand Up @@ -70,18 +70,19 @@ import "./resolvers/index"; // barrel file with all resolvers
export class Server {}
```

</Tab>
<Tab label="CodeSandbox" icon="bxl-codepen">

<iframe src="https://codesandbox.io/embed/tsed-graphql-pgvfz?fontsize=14&hidenavigation=1&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="TsED Graphql"
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi;
payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>

</Tab>
</Tabs>
[//]: #
[//]: # " </Tab>"
[//]: # ' <Tab label="CodeSandbox" icon="bxl-codepen">'
[//]: #
[//]: # '<iframe src="https://codesandbox.io/embed/tsed-graphql-pgvfz?fontsize=14&hidenavigation=1&theme=dark"'
[//]: # 'style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"'
[//]: # 'title="TsED Graphql"'
[//]: # 'allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi;'
[//]: # 'payment; usb; vr; xr-spatial-tracking"'
[//]: # 'sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>'
[//]: #
[//]: # " </Tab>"
[//]: # "</Tabs>"

## Types

Expand Down
36 changes: 33 additions & 3 deletions packages/di/src/node/utils/asyncHookContext.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {DITest} from "../services/DITest.js";
import {runInContext, setContext, getContext} from "./asyncHookContext.js";
import {getContext, runInContext, setContext, useContext} from "./asyncHookContext.js";

describe("asyncHookContext", () => {
beforeEach(() => DITest.create());
Expand All @@ -9,7 +9,7 @@ describe("asyncHookContext", () => {
const res = {type: "res"};

function next(res: any, req: any) {
return Promise.resolve(getContext());
return Promise.resolve(useContext());
}

function nextContext(res: any, req: any, next: any) {
Expand Down Expand Up @@ -45,7 +45,7 @@ describe("asyncHookContext", () => {
const res = {type: "res"};

function next(res: any, req: any) {
return Promise.resolve(getContext());
return Promise.resolve(useContext());
}

function nextContext(res: any, req: any, next: any) {
Expand Down Expand Up @@ -74,6 +74,36 @@ describe("asyncHookContext", () => {
}
});
});
it("should initiate the async hook context - promise (initialValue)", async () => {
const req = {type: "req"};
const res = {type: "res"};

function next(res: any, req: any) {
return Promise.resolve(useContext({id: "id2"} as never));
}

function nextContext(res: any, req: any, next: any) {
const $ctx: any = {
id: "id",
req,
res
};

setContext($ctx);

return next();
}

function app(req: any, res: any) {
return runInContext(undefined, () => nextContext(req, res, () => next(req, res)), DITest.injector);
}

const result = await app(req, res);

expect(result).toEqual({
id: "id2"
});
});
it("should initiate the async hook context - promise + setTimeout", async () => {
const req = {type: "req"};
const res = {type: "res"};
Expand Down
6 changes: 4 additions & 2 deletions packages/di/src/node/utils/asyncHookContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ export function useContextRef() {
return getAsyncStore().getStore();
}

export function getContext<Context = DIContext>(): Context | undefined {
return useContextRef()?.current as any;
export function useContext<Context = DIContext>(initialValue?: DIContext): Context | undefined {
return initialValue || (useContextRef()?.current as any);
}

export const getContext = useContext;

export async function runInContext<Result = unknown>(
ctx: DIContext | undefined,
cb: (...args: unknown[]) => Result,
Expand Down
7 changes: 4 additions & 3 deletions packages/graphql/apollo/src/services/ApolloService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {ApolloServerPluginLandingPageDisabled} from "@apollo/server/plugin/disab
import {ApolloServerPluginDrainHttpServer} from "@apollo/server/plugin/drainHttpServer";
import {ApolloServerPluginLandingPageLocalDefault} from "@apollo/server/plugin/landingPage/default";
import type {IExecutableSchemaDefinition} from "@graphql-tools/schema";
import {getContext, InjectorService, LocalsContainer, PlatformApplication, PlatformContext, Provider} from "@tsed/common";
import {useContext, InjectorService, LocalsContainer, PlatformApplication, PlatformContext, Provider} from "@tsed/common";
import {Constant, Inject, Service} from "@tsed/di";
import {Logger} from "@tsed/logger";
import type {GraphQLSchema} from "graphql";
Expand Down Expand Up @@ -176,15 +176,16 @@ export class ApolloService {
}, new Map<string, Provider>());

return async () => {
const $ctx = getContext() as PlatformContext;
const $ctx = useContext<PlatformContext>();
const context: ApolloContext = {
dataSources: {
...(settings.dataSources?.() || {})
}
};

const alteredContext = await this.injector.alterAsync("$alterApolloContext", context, $ctx);
$ctx.set(APOLLO_CONTEXT, alteredContext);

$ctx!.set(APOLLO_CONTEXT, alteredContext);

const locals = new LocalsContainer();
locals.set(APOLLO_CONTEXT, alteredContext);
Expand Down
1 change: 0 additions & 1 deletion packages/graphql/typegraphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"graphql": "16.8.2",
"graphql-passport": "^0.6.8",
"graphql-scalars": "1.23.0",
"jest": "^29.7.0",
"ts-node": "10.9.2",
"type-graphql": ">=2.0.0-rc.2",
"typescript": "4.9.5",
Expand Down
57 changes: 29 additions & 28 deletions packages/graphql/typegraphql/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,51 +40,52 @@ for the decorators.

To begin, install the TypeGraphQL module for TS.ED:

Express.js:

```bash
npm install --save @tsed/apollo graphql type-graphql @apollo/server @apollo/datasource-rest graphql-scalars
npm install --save-dev apollo-server-testing
```

Koa.js

```bash
npm install --save @tsed/typegraphql type-graphql graphql@15 @apollo/server @apollo/datasource-rest
npm install --save @tsed/apollo graphql type-graphql @apollo/server @as-integration/koa @apollo/datasource-rest graphql-scalars
npm install --save-dev apollo-server-testing
```

Now, we can configure the Ts.ED server by importing `@tsed/typegraphql` in your Server:

```typescript
import {Configuration} from "@tsed/common";
import {Configuration} from "@tsed/di";
import "@tsed/platform-express";
import "@tsed/typegraphql";
import "./resolvers/index"; // barrel file with all resolvers

@Configuration({
graphql: {
apollo: {
server1: {
resolvers: []
}
}
})
export class Server {}
```

## TypeGraphQlService

TypeGraphQlService let you retrieve an instance of ApolloServer.

```typescript
import {Service, AfterRoutesInit} from "@tsed/common";
import {TypeGraphQLService} from "@tsed/typegraphql";
import {ApolloServer} from "apollo-server-express";
// GraphQL server configuration
// See options descriptions on https://www.apollographql.com/docs/apollo-server/api/apollo-server.html
path: "/",
playground: true // enable playground GraphQL IDE. Set false to use Apollo Studio

@Service()
export class UsersService implements AfterRoutesInit {
private server: ApolloServer;
// resolvers?: (Function | string)[];
// dataSources?: Function;
// server?: (config: Config) => ApolloServer;

@Inject()
typeGraphQLService: TypeGraphQLService;
// plugins: []
// middlewareOptions?: ServerRegistration;

$afterRoutesInit() {
this.server = this.typeGraphQLService.get("server1");
// type-graphql
// See options descriptions on https://19majkel94.github.io/type-graphql/
// buildSchemaOptions?: Partial<BuildSchemaOptions>;
}
}
}
})
export class Server {}
```

For more information about ApolloServer look his documentation [here](https://www.apollographql.com/);

## Type-graphql

### Types
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {getContext, PlatformContext, runInContext} from "@tsed/common";
import {type DIContext, runInContext, useContext} from "@tsed/di";
import {MiddlewareFn} from "type-graphql";

export const ContextMiddleware: MiddlewareFn<{req: {$ctx: PlatformContext}}> = (_, next) => {
return runInContext(getContext(), next);
export const ContextMiddleware: MiddlewareFn<{req: {$ctx: DIContext}}> = (action, next) => {
const $ctx = useContext(action.context?.req?.$ctx);
return runInContext($ctx, next);
};
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,7 @@ describe("TypeGraphQL", () => {
errors: [
{
extensions: {
code: "INTERNAL_SERVER_ERROR",
exception: {
headers: {},
// message: "Wrong credentials",
name: "UNAUTHORIZED",
status: 401,
type: "HTTP_EXCEPTION"
}
code: "INTERNAL_SERVER_ERROR"
},
locations: [
{
Expand Down
2 changes: 0 additions & 2 deletions packages/orm/mongoose/test/helpers/models/User.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {Model, MongooseNextCB, ObjectID, PostHook, PreHook, Ref, Schema, Unique} from "@tsed/mongoose";
import {CollectionOf, Groups, Ignore, MinLength, Property, Required} from "@tsed/schema";
import next from "ajv/dist/vocabularies/next";
import {options} from "superagent";

export class BaseModel {
@ObjectID("id")
Expand Down
4 changes: 2 additions & 2 deletions packages/platform/platform-koa/vitest.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export default defineConfig(
...presets.test.coverage,
thresholds: {
statements: 99.15,
branches: 95.65,
branches: 95.6,
functions: 100,
lines: 99.15
}
}
}
}
);
);
Loading

0 comments on commit 7afc1a2

Please sign in to comment.