Skip to content

Commit

Permalink
merge k6 and bruno plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
mvantellingen committed Nov 26, 2024
1 parent cce9843 commit f07193f
Show file tree
Hide file tree
Showing 25 changed files with 2,986 additions and 23 deletions.
54 changes: 54 additions & 0 deletions packages/bruno/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## GraphQL Codegen Bruno Plugin
This plugin generates a directory with
[Bruno](https://github.com/usebruno/bruno) files with all GraphQL queries in
your codebase

# Installation
```sh
pnpm add -d @labdigital/graphql-codegen-bruno
```

# Usage
Create a `codegen.ts` file in the root of your project with the following content:

```ts
import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
schema:
"schema.graphql",
documents: [
"src/**/*.{ts,tsx}"
],
generates: {
// Generate Bruno files in the api-collection directory
"api-collection/generated.json": {
plugins: ["@labdigital/graphql-codegen-bruno"],
config: {

// Clean the output directory before generating the files
clean: true

// Set default values for the generated Bruno variables
defaults: {
locale: "nl-NL",
currency: "EUR"
}
},
},
};

export default config;
```
Then run the following command:
```sh
pnpx graphql-codegen --config codegen.ts
```
# Notes
The `api-collection/generated.json` seems to be needed for GraphQL codegen
to work (we need to generate a file, not a directory). If you know a way to
generate a directory instead of a file, please us know
48 changes: 48 additions & 0 deletions packages/bruno/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@labdigital/graphql-codegen-bruno",
"version": "1.1.0",
"type": "commonjs",
"main": "dist/index.js",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/labd/graphql-codegen-plugins.git",
"directory": "packages/bruno"
},
"scripts": {
"build": "tsup",
"lint": "biome ci && tsc --noEmit",
"clean": "rm -rf dist",
"publish:ci": "pnpm build && pnpm changeset publish",
"test": "vitest run",
"test:ci": "vitest run --coverage"
},
"dependencies": {
"@biomejs/biome": "^1.8.3",
"@graphql-codegen/plugin-helpers": "^5.0.4",
"fs-extra": "^11.2.0",
"prettier": "^3.3.3",
"vitest": "^2.0.5"
},
"devDependencies": {
"@changesets/cli": "^2.27.7",
"@graphql-tools/graphql-file-loader": "^8.0.1",
"@graphql-tools/load": "^8.0.2",
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.5.2",
"@vitest/coverage-v8": "^2.0.5",
"tsup": "^8.2.4",
"typescript": "^5.5.4"
},
"peerDependencies": {
"graphql": "^16.9.0"
},
"pnpm": {
"overrides": {
"graphql": "16.9.0"
}
},
"packageManager": "pnpm@9.9.0"
}
20 changes: 20 additions & 0 deletions packages/bruno/src/__mocks__/query.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# query.graphql

query GetCustomer($info: CustomerInfo!) {
customer(info: $info) {
...CustomerDetails
}
}

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

fragment AddressDetails on Address {
id
city
}
41 changes: 41 additions & 0 deletions packages/bruno/src/__mocks__/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
type Query {
customer(info: CustomerInfo!): Customer
product(id: ID!): Product
}

input CustomerInfo {
credentials: Credentials!
authMethod: AuthMethod!
}

enum AuthMethod {
EMAIL
PHONE
}

input Credentials {
email: String!
password: String!
}

type Customer {
id: ID!
firstName: String!
email: String!
addresses: [Address!]!
}

type Product {
id: ID!
name: String!
price: Float!
}

type Address {
id: ID!
email: String
firstName: String
lastName: String
city: String
}

57 changes: 57 additions & 0 deletions packages/bruno/src/__output__/queries/GetCustomer.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

meta {
name: GetCustomer
type: graphql
}

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

body:graphql {
query GetCustomer($info: CustomerInfo!) {
customer(info: $info) {
...CustomerDetails
}
}

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

fragment AddressDetails on Address {
id
city
}
fragment CustomerDetails on Customer {
firstName
email
addresses {
...AddressDetails
}
}
fragment AddressDetails on Address {
id
city
}

}

body:graphql:vars {
{
"info": {
"credentials": {
"email": "example",
"password": "example"
},
"authMethod": "EMAIL"
}
}
}

57 changes: 57 additions & 0 deletions packages/bruno/src/__snapshots__/queries/GetCustomer.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

meta {
name: GetCustomer
type: graphql
}

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

body:graphql {
query GetCustomer($info: CustomerInfo!) {
customer(info: $info) {
...CustomerDetails
}
}

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

fragment AddressDetails on Address {
id
city
}
fragment CustomerDetails on Customer {
firstName
email
addresses {
...AddressDetails
}
}
fragment AddressDetails on Address {
id
city
}

}

body:graphql:vars {
{
"info": {
"credentials": {
"email": "example",
"password": "example"
},
"authMethod": "EMAIL"
}
}
}

53 changes: 53 additions & 0 deletions packages/bruno/src/bruno.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import prettier from "prettier";
import type { FileContent } from "./operations";

export const asBruno = async (
operation: FileContent,
defaults: Record<string, unknown>,
) => {
const formattedContent = await prettier.format(operation.content, {
parser: "graphql",
});

const vars = mergeDefaults(operation.vars, defaults);

return `
meta {
name: ${operation.name}
type: graphql
}
post {
url: {{graphql-gateway}}/graphql
body: graphql
auth: none
}
body:graphql {
${formattedContent.split("\n").join("\n ")}
}
body:graphql:vars {
${JSON.stringify(vars, null, 2).split("\n").join("\n ")}
}
`;
};

const mergeDefaults = (
vars: Record<string, unknown>,
defaults: Record<string, unknown>,
) => {
const mergedVars: Record<string, unknown> = {};

for (const key in vars) {
mergedVars[key] = vars[key];
}

for (const key in defaults) {
if (key in vars) {
mergedVars[key] = defaults[key];
}
}

return mergedVars;
};
52 changes: 52 additions & 0 deletions packages/bruno/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import path from "node:path";
import { afterEach } from "node:test";
import type { Types } from "@graphql-codegen/plugin-helpers";
import { GraphQLFileLoader } from "@graphql-tools/graphql-file-loader";
import { loadDocumentsSync, loadSchemaSync } from "@graphql-tools/load";
import fs from "fs-extra";
import { describe, expect, it } from "vitest";
import { type BrunoPluginConfig, plugin } from "./index";

const mockOutputDir = path.join(__dirname, "__output__");
const snapshotDir = path.join(__dirname, "__snapshots__");
const mockSchemaPath = path.join(__dirname, "__mocks__", "schema.graphqls");
const mockDocumentsPath = path.join(__dirname, "__mocks__", "query.graphql");

afterEach(() => {
fs.removeSync(mockOutputDir);
});

describe("Bruno Plugin", () => {
it("should generate the expected output", async () => {
// Load the mock schema
const schema = loadSchemaSync(mockSchemaPath, {
loaders: [new GraphQLFileLoader()],
});

// Load the mock documents
const documents = loadDocumentsSync(mockDocumentsPath, {
loaders: [new GraphQLFileLoader()],
}) as Types.DocumentFile[];

// Clear the output directory before running the test
fs.ensureDirSync(mockOutputDir);

// Run the plugin
const outputFile = path.join(mockOutputDir, "output.json");
const pluginConfig: BrunoPluginConfig = {
defaults: {},
clean: false,
};
const data = await plugin(schema, documents, pluginConfig, { outputFile });

expect(data).toBeDefined();

const result = fs.readFileSync(
path.join(mockOutputDir, "queries", "GetCustomer.bru"),
"utf-8",
);
await expect(result).toMatchFileSnapshot(
path.join(snapshotDir, "queries", "GetCustomer.bru"),
);
});
});
Loading

0 comments on commit f07193f

Please sign in to comment.