Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/bruno-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@labdigital/graphql-codegen-bruno": minor
---

Add the `url` and `auth` options for the request URL and auth mode; they default to the previously hardcoded `{{graphql-gateway}}/graphql` and `none`.

This release changes the generated output:

- A request now contains only its operation followed by the fragments it (transitively) uses, each once. Previously it contained the complete source document (including other operations in the same document) and fragments could be included twice. The GraphQL is printed with `graphql`'s `print`, so comments of the source document are no longer included.
- Subscriptions are written to `subscriptions/` instead of `mutations/`. Run once with `clean: true` (or remove them manually) to remove the subscriptions from `mutations/`.
- `clean: true` now only removes the previously generated requests (the `.bru` files, except `folder.bru`, in the `queries/`, `mutations/` and `subscriptions/` folders of the output directory) instead of everything in the output directory, so it no longer deletes `bruno.json`, environments or other files.
- prettier is no longer bundled (the package was 5 MB); formatting is done by `graphql`'s `print`.
7 changes: 7 additions & 0 deletions .changeset/k6-fix-document-modes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@labdigital/graphql-codegen-k6": patch
---

Fix the generated code for `documentMode` `graphQLTag` (the default) and `external`: the `Requester` type referred to `DocumentNode` without importing it, so the output did not type check. `DocumentNode` is now imported from `documentNodeImport` (default `graphql`), respecting `useTypeImports`.

Fix `documentMode: "string"`: the output referred to a `TypedDocumentString` class that was never defined. The class is now generated (the same class as `typed-document-node` and the client preset use), the operation documents are typed with their result and variables, and the requester receives the `TypedDocumentString` (which serializes to the query string).
7 changes: 7 additions & 0 deletions .changeset/typedefs-extend-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@labdigital/graphql-codegen-typedefs": minor
---

Only print the schema definition as `extend schema { ... }`. Previously the whole printed schema was prefixed with `extend`, which produced invalid output for schemas without root types (`extend type ...`, `extend directive ...`) and for schemas with a description. The description of the schema is dropped from the extension, as extensions cannot have one.

Add the `extendSchema` option (default `true`, the previous behaviour); set it to `false` to print a plain `schema { ... }` definition instead.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dist/*
test-reports/*

.turbo/
.typecheck/
49 changes: 27 additions & 22 deletions packages/bruno/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ const config: CodegenConfig = {
"api-collection/generated/index.json": {
plugins: ["@labdigital/graphql-codegen-bruno"],
config: {
// Empty the output directory before generating
// Remove previously generated requests before generating
clean: true,
// URL of the requests (default: "{{graphql-gateway}}/graphql")
url: "{{baseUrl}}/graphql",
// Use the auth of the collection (default: "none")
auth: "inherit",
// Headers added to every request
headers: {
Authorization: "Bearer {{token}}",
Expand Down Expand Up @@ -68,20 +72,24 @@ api-collection/
├── index.json
├── mutations/
│ └── AddToCart.bru
└── queries/
├── GetProduct.bru
└── ListProducts.bru
├── queries/
│ ├── GetProduct.bru
│ └── ListProducts.bru
└── subscriptions/
└── CartUpdated.bru
```

The requests are sent to `{{graphql-gateway}}/graphql`, so define a
By default the requests are sent to `{{graphql-gateway}}/graphql`, so define a
`graphql-gateway` variable (for example `http://localhost:4000`) in your Bruno
environment.
environment, or set `url` to match your environment variables.

## Configuration

| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| `clean` | `boolean` | `false` | Remove everything in the output directory (the directory of the output file) before generating. |
| `clean` | `boolean` | `false` | Remove the previously generated requests before generating: the `.bru` files in the `queries/`, `mutations/` and `subscriptions/` folders of the output directory (except `folder.bru`), and those folders when they are empty afterwards. Other files, such as `bruno.json`, `collection.bru` or environments, are never removed. |
| `url` | `string` | `"{{graphql-gateway}}/graphql"` | URL of every request. May use Bruno variables. |
| `auth` | `string` | `"none"` | Auth mode of every request. Use `inherit` to use the auth configured on the collection or folder. |
| `headers` | `Record<string, string>` | `{}` | Headers added to the `headers` block of every request. Values may use Bruno variables, such as `{{token}}`. |
| `defaults` | `Record<string, unknown>` | `{}` | Values for operation variables, by variable name. A default replaces the generated example value of a top-level variable with the same name; variables that the operation does not declare are ignored. |

Expand Down Expand Up @@ -119,9 +127,9 @@ meta {
}

post {
url: {{graphql-gateway}}/graphql
url: {{baseUrl}}/graphql
body: graphql
auth: none
auth: inherit
}

headers {
Expand All @@ -134,12 +142,12 @@ body:graphql {
...ProductFields
}
}

fragment ProductFields on Product {
id
name
price
}

}

body:graphql:vars {
Expand Down Expand Up @@ -189,18 +197,15 @@ Variables get an example value based on their type:

- Codegen requires a file as output, so the plugin needs an output *file* even
though it generates a directory. The file is used for the JSON index.
- `clean: true` removes **everything** in the directory of the output file.
Point the output to a dedicated directory inside your collection, not to the
collection root, or it removes your `bruno.json` and environments as well.
- Queries are written to `queries/`; mutations (and subscriptions) to
`mutations/`. Files are named after the operation, so operation names must be
unique.
- Queries are written to `queries/`, mutations to `mutations/` and
subscriptions to `subscriptions/`. Files are named after the operation, so
operation names must be unique.
- Unnamed operations are skipped.
- The request body contains the complete source document of the operation
(one `.graphql` file, or one `gql` template literal in TypeScript), followed
by the fragments the operation uses. Put one operation per document;
otherwise every request contains all operations of that document, and
fragments defined in the same document are included twice.
- The URL (`{{graphql-gateway}}/graphql`) and `auth: none` are fixed.
- The request body contains the operation, followed by the fragments it uses
(also fragments used by those fragments, and fragments defined in other
documents), each fragment once. The GraphQL is printed with `graphql`'s
`print`, so comments in the source documents are not included.
- Without `clean`, requests of operations that were removed or renamed stay in
the output directory.
- `defaults` only applies to top-level variables; it replaces the whole value,
it does not merge into input objects.
1 change: 0 additions & 1 deletion packages/bruno/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"@types/node": "^26.6.5",
"@vitest/coverage-v8": "5.0.3",
"graphql": "^17.0.2",
"prettier": "^3.9.10",
"publint": "^0.3.25",
"tsdown": "^0.23.1",
"typescript": "^7.0.2",
Expand Down
42 changes: 42 additions & 0 deletions packages/bruno/src/__mocks__/operations.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Several operations in one document

query GetProduct($id: ID!) {
product(id: $id) {
...ProductFields
}
}

mutation UpdateCustomer($id: ID!, $firstName: String) {
updateCustomer(id: $id, firstName: $firstName) {
id
...CustomerDetails
}
}

subscription CustomerUpdated($id: ID!) {
customerUpdated(id: $id) {
id
... on Customer {
...CustomerDetails
}
}
}

# Unnamed operations are skipped
# biome-ignore lint/correctness/useLoneAnonymousOperation: tests unnamed operations
# biome-ignore lint/correctness/useGraphqlNamedOperations: tests unnamed operations
query {
product(id: "1") {
id
}
}

fragment ProductFields on Product {
id
name
price
}

fragment UnusedFields on Product {
id
}
8 changes: 8 additions & 0 deletions packages/bruno/src/__mocks__/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ type Query {
product(id: ID!): Product
}

type Mutation {
updateCustomer(id: ID!, firstName: String): Customer
}

type Subscription {
customerUpdated(id: ID!): Customer
}

input CustomerInfo {
credentials: Credentials!
authMethod: AuthMethod!
Expand Down
55 changes: 0 additions & 55 deletions packages/bruno/src/__output__/queries/GetCustomer.bru

This file was deleted.

39 changes: 39 additions & 0 deletions packages/bruno/src/__snapshots__/mutations/UpdateCustomer.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
meta {
name: UpdateCustomer
type: graphql
}

post {
url: {{graphql-gateway}}/graphql
body: graphql
auth: none
}

body:graphql {
mutation UpdateCustomer($id: ID!, $firstName: String) {
updateCustomer(id: $id, firstName: $firstName) {
id
...CustomerDetails
}
}

fragment CustomerDetails on Customer {
firstName
email
addresses {
...AddressDetails
}
}

fragment AddressDetails on Address {
id
city
}
}

body:graphql:vars {
{
"id": "example-id",
"firstName": "example"
}
}
12 changes: 0 additions & 12 deletions packages/bruno/src/__snapshots__/queries/GetCustomer.bru
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,6 @@ body:graphql {
id
city
}
fragment CustomerDetails on Customer {
firstName
email
addresses {
...AddressDetails
}
}
fragment AddressDetails on Address {
id
city
}

}

body:graphql:vars {
Expand Down
30 changes: 30 additions & 0 deletions packages/bruno/src/__snapshots__/queries/GetProduct.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
meta {
name: GetProduct
type: graphql
}

post {
url: {{graphql-gateway}}/graphql
body: graphql
auth: none
}

body:graphql {
query GetProduct($id: ID!) {
product(id: $id) {
...ProductFields
}
}

fragment ProductFields on Product {
id
name
price
}
}

body:graphql:vars {
{
"id": "example-id"
}
}
40 changes: 40 additions & 0 deletions packages/bruno/src/__snapshots__/subscriptions/CustomerUpdated.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
meta {
name: CustomerUpdated
type: graphql
}

post {
url: {{graphql-gateway}}/graphql
body: graphql
auth: none
}

body:graphql {
subscription CustomerUpdated($id: ID!) {
customerUpdated(id: $id) {
id
... on Customer {
...CustomerDetails
}
}
}

fragment CustomerDetails on Customer {
firstName
email
addresses {
...AddressDetails
}
}

fragment AddressDetails on Address {
id
city
}
}

body:graphql:vars {
{
"id": "example-id"
}
}
Loading
Loading