Skip to content

Commit

Permalink
feat: add start executor (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
domjtalbot authored Jul 15, 2022
1 parent 78e4d9c commit c7c4a60
Show file tree
Hide file tree
Showing 17 changed files with 273 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/dirty-drinks-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'nx-plugin-graphql-mesh': major
---

Add `start` executor
3 changes: 3 additions & 0 deletions .lintstagedrc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export default {
'nx affected --target=test',
'nx affected --target=e2e',
],
'apps/api-gateway/**/*.*': () => [
'nx affected --target=e2e --configuration start',
],
};
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ This is the equivalent of using `graphql-mesh build`, but with extra steps for c
| **`fileType`** | `json`, `ts` or `js` | `false` | `ts` | The filetype. |
| **`require`** | `string[]` | `false` | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |

### `build`
### `build-swc`

Builds artifacts for a GraphQL Mesh library.

This is the equivalent of using `graphql-mesh dev`, but with extra steps for packaging the library.
This is the equivalent of using `graphql-mesh build`, but with extra steps for packaging the library with SWC.

```json
"targets": {
Expand Down Expand Up @@ -154,6 +154,32 @@ This is the equifilent of using `graphql-mesh dev`.
| **`port`** | `number` | `false` | `4000` | The port number to run on. |
| **`require`** | `string[]` | `false` | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |

### `start`

Serves a GraphQL server with GraphQL interface based on your generated artifacts.

This is the equifilent of using `graphql-mesh start`.

```json
"targets": {
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
"dir": "path/to/app/or/lib",
},
},
}
```

#### Options

| Name | Type | Required | Default | Description |
| ------------- | ---------- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| **`debug`** | `boolean` | `false` | `false` | Display debugging info by applying the `DEBUG` env variable. |
| **`dir`** | `string` | `true` | - | The path of the directory containing the GraphQL Mesh config. |
| **`port`** | `number` | `false` | `4000` | The port number to run on. |
| **`require`** | `string[]` | `false` | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |

<br/>

## Examples
Expand Down
12 changes: 10 additions & 2 deletions apps/api-gateway/stackexchange-e2e/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/api-gateway/stackexchange-e2e/cypress.json",
"devServerTarget": "api-gateway-stackexchange:dev:e2e"
"cypressConfig": "apps/api-gateway/stackexchange-e2e/cypress.json"
},
"defaultConfiguration": "dev",
"configurations": {
"dev": {
"devServerTarget": "api-gateway-stackexchange:dev:e2e"
},
"start": {
"devServerTarget": "api-gateway-stackexchange:start:e2e"
}
}
},
"lint": {
Expand Down
19 changes: 19 additions & 0 deletions apps/api-gateway/stackexchange/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
"dir": "dist/apps/api-gateway/stackexchange",
"port": 5200
},
"configurations": {
"e2e": {
"debug": false,
"port": 5201
}
},
"dependsOn": [
{
"projects": "self",
"target": "build"
}
]
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
Expand Down
12 changes: 10 additions & 2 deletions apps/api-gateway/trippin-e2e/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/api-gateway/trippin-e2e/cypress.json",
"devServerTarget": "api-gateway-trippin:dev:e2e"
"cypressConfig": "apps/api-gateway/trippin-e2e/cypress.json"
},
"defaultConfiguration": "dev",
"configurations": {
"dev": {
"devServerTarget": "api-gateway-trippin:dev:e2e"
},
"start": {
"devServerTarget": "api-gateway-trippin:start:e2e"
}
}
},
"lint": {
Expand Down
19 changes: 19 additions & 0 deletions apps/api-gateway/trippin/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
"dir": "dist/apps/api-gateway/trippin",
"port": 5100
},
"configurations": {
"e2e": {
"debug": false,
"port": 5101
}
},
"dependsOn": [
{
"projects": "self",
"target": "build"
}
]
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
Expand Down
12 changes: 10 additions & 2 deletions apps/api-gateway/weatherbit-e2e/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/api-gateway/weatherbit-e2e/cypress.json",
"devServerTarget": "api-gateway-weatherbit:dev:e2e"
"cypressConfig": "apps/api-gateway/weatherbit-e2e/cypress.json"
},
"defaultConfiguration": "dev",
"configurations": {
"dev": {
"devServerTarget": "api-gateway-weatherbit:dev:e2e"
},
"start": {
"devServerTarget": "api-gateway-weatherbit:start:e2e"
}
}
},
"lint": {
Expand Down
7 changes: 0 additions & 7 deletions apps/api-gateway/weatherbit/.meshrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,5 @@ sources:
serve:
browser: false

plugins:
- responseCache:
ttlPerCoordinate:
# Forecast data might change, so we can cache it for 1 hour only
- coordinate: Query.forecast_daily_by_lat_by_lon
ttl: 3600

documents:
- ./*.graphql
19 changes: 19 additions & 0 deletions apps/api-gateway/weatherbit/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
"dir": "dist/apps/api-gateway/weatherbit",
"port": 5300
},
"configurations": {
"e2e": {
"debug": false,
"port": 5301
}
},
"dependsOn": [
{
"projects": "self",
"target": "build"
}
]
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
Expand Down
6 changes: 6 additions & 0 deletions libs/nx-plugin-graphql-mesh/executors.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"schema": "./src/executors/build-swc/schema.json",
"description": "Builds artifacts using SWC.",
"hasher": "./src/executors/build-swc/hasher"
},
"start": {
"implementation": "./src/executors/start/start.impl",
"schema": "./src/executors/start/schema.json",
"description": "Serves a GraphQL server with GraphQL interface based on your generated artifacts",
"hasher": "./src/executors/start/hasher"
}
}
}
27 changes: 27 additions & 0 deletions libs/nx-plugin-graphql-mesh/src/executors/start/hasher.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Hasher, HasherContext } from '@nrwl/devkit';

import { startHasher } from './hasher';

describe('startHasher', () => {
it('should generate hash', async () => {
const mockHasher: Hasher = {
hashTaskWithDepsAndContext: jest
.fn()
.mockReturnValue({ value: 'hashed-task' }),
} as unknown as Hasher;
const hash = await startHasher(
{
id: 'my-task-id',
target: {
project: 'proj',
target: 'target',
},
overrides: {},
},
{
hasher: mockHasher,
} as unknown as HasherContext
);
expect(hash).toEqual({ value: 'hashed-task' });
});
});
12 changes: 12 additions & 0 deletions libs/nx-plugin-graphql-mesh/src/executors/start/hasher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { CustomHasher } from '@nrwl/devkit';

/**
* This is a boilerplate custom hasher that matches
* the default Nx hasher. If you need to extend the behavior,
* you can consume workspace details from the context.
*/
export const startHasher: CustomHasher = async (task, context) => {
return context.hasher.hashTaskWithDepsAndContext(task);
};

export default startHasher;
32 changes: 32 additions & 0 deletions libs/nx-plugin-graphql-mesh/src/executors/start/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"title": "Start executor",
"description": "Serves a GraphQL server with GraphQL interface based on your generated artifacts",
"type": "object",
"properties": {
"debug": {
"type": "boolean",
"description": "Display debugging info.",
"default": false
},
"dir": {
"description": "The directory containing built GraphQL Mesh assets (.mesh).",
"type": "string"
},
"port": {
"type": "integer",
"description": "The port number to run on.",
"default": 4000
},
"require": {
"type": "array",
"description": "Loads specific require.extensions before running the codegen and reading the configuration.",
"items": {
"type": "string"
},
"default": []
}
},
"required": ["dir"]
}
6 changes: 6 additions & 0 deletions libs/nx-plugin-graphql-mesh/src/executors/start/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Options } from '../../utils';

type MeshStartSchema = Options<'start'>;

export type StartExecutorSchema = MeshStartSchema['args'] &
MeshStartSchema['env'];
66 changes: 66 additions & 0 deletions libs/nx-plugin-graphql-mesh/src/executors/start/start.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { ExecutorContext } from '@nrwl/devkit';

import { logger } from '@nrwl/devkit';
import { resolve } from 'path';

import { childProcess, runMeshCli } from '../../utils/mesh-cli';

import { StartExecutorSchema } from './schema';

const readyWhenMsg = 'Serving GraphQL Mesh:';

export default async function* startExecutor(
options: StartExecutorSchema,
context: ExecutorContext
) {
if (options.dir === undefined) {
throw new Error("Please define the 'dir' value");
}

const baseUrl = `http://0.0.0.0:${options.port}`;

logger.info('Starting GraphQL Mesh start server...');

runMeshCli(
'start',
{
args: {
dir: resolve(context.root, options.dir),
port: options.port,
require: options.require,
},
env: {
debug: options.debug,
},
},
context,
{
stdio: 'pipe',
}
);

childProcess?.stdout?.on('data', (chunk) => {
process.stdout.write(chunk);
});

childProcess?.stderr?.on('data', (chunk) => {
process.stderr.write(chunk);
});

await new Promise<void>((resolve) => {
childProcess?.stdout?.on('data', (chunk) => {
if (chunk.toString().indexOf(readyWhenMsg) > -1) {
resolve();
}
});
});

yield {
baseUrl,
success: true,
};

await new Promise<{ success: boolean }>(() => {
// This Promise intentionally never resolves, leaving the process running.
});
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"build": "nx run-many --target=build --all",
"ci": "pnpm lint:fix && pnpm build && pnpm test && pnpm e2e",
"e2e": "nx run-many --target=e2e --all && nx",
"e2e": "nx run-many --target=e2e --all && nx run-many --target=e2e --all --configuration start",
"lint:fix": "nx format:write && nx run-many --target=lint --all --fix",
"lint": "nx workspace-lint && nx format && nx run-many --target=lint --all",
"test": "nx run-many --target=test --all",
Expand Down

0 comments on commit c7c4a60

Please sign in to comment.