Skip to content

Commit f984723

Browse files
authored
Merge pull request #3479 from SeedCompany/gql-tada
2 parents c7dc7c8 + ba375d1 commit f984723

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3811
-3861
lines changed

.eslintrc.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ const restrictedImports = [
9393
kind: 'value',
9494
message: 'Be sure to specify the `type` modifier',
9595
},
96+
{
97+
importNames: ['ResultOf', 'VariablesOf'],
98+
path: '@graphql-typed-document-node/core',
99+
replacement: { path: '~/graphql' },
100+
},
101+
{
102+
importNames: ['FragmentOf', 'ResultOf', 'VariablesOf'],
103+
path: 'gql.tada',
104+
replacement: { path: '~/graphql' },
105+
},
96106
];
97107

98108
const namingConvention = [

.github/workflows/lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ jobs:
2121
- name: Check for no duplicate dependencies
2222
run: yarn dedupe --check
2323

24+
- name: Generate GQL Schema
25+
run: yarn start -- --gen-schema && yarn gql-tada generate output
26+
2427
- name: Check TypeScript
2528
run: yarn type-check
2629

27-
- name: Generate GQL Schema
28-
run: yarn start -- --gen-schema
2930
- name: Upload GQL Schema
3031
uses: actions/upload-artifact@v4
3132
with:

.github/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jobs:
1818
- name: Gel Setup
1919
uses: ./.github/actions/gel-setup
2020

21+
- name: Generate GQL Schema
22+
run: yarn start -- --gen-schema && yarn gql-tada generate output
23+
2124
- name: Tests
2225
run: yarn test --reporters=github-actions
2326

@@ -59,6 +62,9 @@ jobs:
5962
- name: Gel Setup
6063
uses: ./.github/actions/gel-setup
6164

65+
- name: Generate GQL Schema
66+
run: yarn start -- --gen-schema && yarn gql-tada generate output
67+
6268
- name: E2E Tests
6369
run: yarn test:e2e --shard=${{ matrix.shard }}/6 --reporters=github-actions
6470
env:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
src/core/gel/generated-client
88
src/core/gel/schema.ts
99
src/**/*.edgeql.ts
10+
*.generated.*
1011

1112
# Yarn / NPM
1213
.yarn/cache

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"gel": "^2.1.0-canary.20250319T143140",
7575
"glob": "^11.0.2",
7676
"got": "^14.3.0",
77+
"gql.tada": "^1.8.10",
7778
"graphql": "^16.9.0",
7879
"graphql-parse-resolve-info": "^4.14.0",
7980
"graphql-scalars": "^1.22.4",

src/graphql.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* eslint-disable @seedcompany/no-restricted-imports */
2+
import { initGraphQLTada, type VariablesOf } from 'gql.tada';
3+
import { type ID } from '~/common';
4+
import type { introspection } from './graphql-env.generated';
5+
6+
export const graphql = initGraphQLTada<{
7+
introspection: introspection;
8+
scalars: {
9+
ID: ID;
10+
Date: string;
11+
DateTime: string;
12+
InlineMarkdown: string;
13+
Markdown: string;
14+
RichText: object;
15+
URL: string;
16+
};
17+
disableMasking: true;
18+
}>();
19+
20+
export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';
21+
export { readFragment } from 'gql.tada';
22+
23+
export type InputOf<T> = VariablesOf<T> extends { input?: infer Input }
24+
? Input
25+
: never;

test/authentication.e2e-spec.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ import { jest } from '@jest/globals';
33
import { EmailService } from '@seedcompany/nestjs-email';
44
import { Connection } from 'cypher-query-builder';
55
import { isValidId } from '~/common';
6+
import { graphql } from '~/graphql';
67
import {
78
createSession,
89
createTestApp,
910
fragments,
1011
generateRegisterInput,
11-
gql,
1212
login,
1313
logout,
1414
registerUser,
1515
type TestApp,
1616
} from './utility';
17-
import { type RawUser } from './utility/fragments';
1817

1918
describe('Authentication e2e', () => {
2019
let app: TestApp;
@@ -38,13 +37,13 @@ describe('Authentication e2e', () => {
3837
// create user first
3938
await registerUser(app, fakeUser);
4039
await app.graphql.mutate(
41-
gql`
40+
graphql(`
4241
mutation forgotPassword($email: String!) {
4342
forgotPassword(email: $email) {
4443
__typename
4544
}
4645
}
47-
`,
46+
`),
4847
{
4948
email: email,
5049
},
@@ -59,13 +58,13 @@ describe('Authentication e2e', () => {
5958
const token = tokenRes ? tokenRes.token : '';
6059
const newPassword = faker.internet.password();
6160
await app.graphql.mutate(
62-
gql`
61+
graphql(`
6362
mutation resetPassword($input: ResetPasswordInput!) {
6463
resetPassword(input: $input) {
6564
__typename
6665
}
6766
}
68-
`,
67+
`),
6968
{
7069
input: {
7170
token: token,
@@ -90,20 +89,22 @@ describe('Authentication e2e', () => {
9089

9190
await login(app, { email: fakeUser.email, password: fakeUser.password });
9291
const result = await app.graphql.query(
93-
gql`
94-
query user($id: ID!) {
95-
user(id: $id) {
96-
...user
92+
graphql(
93+
`
94+
query user($id: ID!) {
95+
user(id: $id) {
96+
...user
97+
}
9798
}
98-
}
99-
${fragments.user}
100-
`,
99+
`,
100+
[fragments.user],
101+
),
101102
{
102103
id: user.id,
103104
},
104105
);
105106

106-
const actual: RawUser = result.user;
107+
const actual = result.user;
107108
expect(actual).toBeTruthy();
108109
expect(isValidId(actual.id)).toBe(true);
109110
expect(actual.email.value).toBe(fakeUser.email.toLowerCase());
@@ -125,13 +126,13 @@ describe('Authentication e2e', () => {
125126

126127
const newPassword = faker.internet.password();
127128
await app.graphql.mutate(
128-
gql`
129+
graphql(`
129130
mutation changePassword($oldPassword: String!, $newPassword: String!) {
130131
changePassword(oldPassword: $oldPassword, newPassword: $newPassword) {
131132
__typename
132133
}
133134
}
134-
`,
135+
`),
135136
{
136137
oldPassword: fakeUser.password,
137138
newPassword: newPassword,

test/education.e2e-spec.ts

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import { faker } from '@faker-js/faker';
22
import { times } from 'lodash';
33
import { isValidId, Role } from '~/common';
4-
import { type User } from '../src/components/user/dto';
5-
import { type Education } from '../src/components/user/education/dto';
4+
import { graphql } from '~/graphql';
65
import {
76
createEducation,
87
createSession,
98
createTestApp,
10-
gql,
9+
fragments,
1110
registerUser,
1211
type TestApp,
1312
} from './utility';
14-
import { fragments } from './utility/fragments';
1513

1614
describe('Education e2e', () => {
1715
let app: TestApp;
18-
let user: User;
16+
let user: fragments.user;
1917

2018
beforeAll(async () => {
2119
app = await createTestApp();
@@ -36,14 +34,16 @@ describe('Education e2e', () => {
3634
const education = await createEducation(app, { userId: user.id });
3735

3836
const { education: actual } = await app.graphql.query(
39-
gql`
40-
query education($id: ID!) {
41-
education(id: $id) {
42-
...education
37+
graphql(
38+
`
39+
query education($id: ID!) {
40+
education(id: $id) {
41+
...education
42+
}
4343
}
44-
}
45-
${fragments.education}
46-
`,
44+
`,
45+
[fragments.education],
46+
),
4747
{
4848
id: education.id,
4949
},
@@ -60,16 +60,18 @@ describe('Education e2e', () => {
6060
const newInstitution = faker.company.name();
6161

6262
const result = await app.graphql.mutate(
63-
gql`
64-
mutation updateEducation($input: UpdateEducationInput!) {
65-
updateEducation(input: $input) {
66-
education {
67-
...education
63+
graphql(
64+
`
65+
mutation updateEducation($input: UpdateEducationInput!) {
66+
updateEducation(input: $input) {
67+
education {
68+
...education
69+
}
6870
}
6971
}
70-
}
71-
${fragments.education}
72-
`,
72+
`,
73+
[fragments.education],
74+
),
7375
{
7476
input: {
7577
education: {
@@ -90,18 +92,18 @@ describe('Education e2e', () => {
9092
const education = await createEducation(app, { userId: user.id });
9193

9294
const result = await app.graphql.mutate(
93-
gql`
95+
graphql(`
9496
mutation deleteEducation($id: ID!) {
9597
deleteEducation(id: $id) {
9698
__typename
9799
}
98100
}
99-
`,
101+
`),
100102
{
101103
id: education.id,
102104
},
103105
);
104-
const actual: Education | undefined = result.deleteEducation;
106+
const actual = result.deleteEducation;
105107
expect(actual).toBeTruthy();
106108
});
107109

@@ -114,20 +116,22 @@ describe('Education e2e', () => {
114116
);
115117

116118
const result = await app.graphql.query(
117-
gql`
118-
query UserEducation($id: ID!) {
119-
user(id: $id) {
120-
education {
121-
items {
122-
...education
119+
graphql(
120+
`
121+
query UserEducation($id: ID!) {
122+
user(id: $id) {
123+
education {
124+
items {
125+
...education
126+
}
127+
hasMore
128+
total
123129
}
124-
hasMore
125-
total
126130
}
127131
}
128-
}
129-
${fragments.education}
130-
`,
132+
`,
133+
[fragments.education],
134+
),
131135
{
132136
id: user.id,
133137
},

0 commit comments

Comments
 (0)