diff --git a/.changeset/beige-planets-perform.md b/.changeset/beige-planets-perform.md
new file mode 100644
index 00000000..674e0a79
--- /dev/null
+++ b/.changeset/beige-planets-perform.md
@@ -0,0 +1,5 @@
+---
+'nx-plugin-graphql-mesh': minor
+---
+
+Add automatic port selection for `dev`, `start` & `serve` executors
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index 5ff6c35a..91763870 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -63,12 +63,13 @@ jobs:
env:
NX_CLOUD_ENV_NAME: node-${{ matrix.node }}
outputs:
- affected: ${{ steps.affected.affected }}
- affectedLength: ${{ steps.affected.affectedLength }}
- affectedApps: ${{ steps.affected.affectedApps }}
- affectedAppsLength: ${{ steps.affected.affectedAppsLength }}
- affectedLibs: ${{ steps.affected.affectedLibs }}
- affectedLibsLength: ${{ steps.affected.affectedLibsLength }}
+ affected: ${{ steps.affected.outputs.affected }}
+ affectedLength: ${{ steps.affected.outputs.affectedLength }}
+ affectedApps: ${{ steps.affected.outputs.affectedApps }}
+ affectedAppsLength: ${{ steps.affected.outputs.affectedAppsLength }}
+ affectedLibs: ${{ steps.affected.outputs.affectedLibs }}
+ affectedLibsLength: ${{ steps.affected.outputs.affectedLibsLength }}
+ hasAffected: ${{ steps.affected.outputs.hasAffected }}
steps:
- name: Check out repository
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
@@ -82,7 +83,6 @@ jobs:
- name: Affected
id: affected
- if: matrix.node == 'lts'
uses: ./.github/actions/nx-affected
- name: Workspace Lint
diff --git a/README.md b/README.md
index 7ab042e9..e67eada9 100644
--- a/README.md
+++ b/README.md
@@ -298,12 +298,19 @@ This is the equifilent of using `graphql-mesh dev`.
#### Options
-| Name | Type | Required | Default | Description |
-| ------------- | ---------- | :------: | ------- | ------------------------------------------------------------------------------------------- |
-| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
-| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
-| **`port`** | `number` | - | `4000` | The port number to run on. |
-| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
+| Name | Type | Required | Default | Description |
+| --------------------- | -------------- | :------: | --------- | -------------------------------------------------------------------------------------------------- |
+| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
+| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
+| **`port`** | `object` | - | - | Port selection settings |
+| **`port.auto`** | `boolean` | - | `true` | Use the first available port |
+| **`port.number`** | `number` | - | `4200` | Define the preferred port to use when `auto` is set to `false` |
+| **`port.range`** | `object` | - | - | The range of ports to select from. |
+| **`port.range.from`** | `boolean` | - | - | The first port of the range. Must be in the range `1024`...`65535` |
+| **`port.range.to`** | `boolean` | - | - | The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`. |
+| **`port.fallback`** | `auto`, `none` | - | `auto` | The fallback strategy to use when the preferred port is unavailable. |
+| **`port.host`** | `string` | - | `0.0.0.0` | The host to listern on (only used for port number lookup). |
+| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
@@ -326,12 +333,19 @@ This is the equifilent of using `graphql-mesh start`.
#### Options
-| Name | Type | Required | Default | Description |
-| ------------- | ---------- | :------: | ------- | ------------------------------------------------------------------------------------------- |
-| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
-| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
-| **`port`** | `number` | - | `4000` | The port number to run on. |
-| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
+| Name | Type | Required | Default | Description |
+| --------------------- | -------------- | :------: | --------- | -------------------------------------------------------------------------------------------------- |
+| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
+| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
+| **`port`** | `object` | - | - | Port selection settings |
+| **`port.auto`** | `boolean` | - | `true` | Use the first available port |
+| **`port.number`** | `number` | - | `4200` | Define the preferred port to use when `auto` is set to `false` |
+| **`port.range`** | `object` | - | - | The range of ports to select from. |
+| **`port.range.from`** | `boolean` | - | - | The first port of the range. Must be in the range `1024`...`65535` |
+| **`port.range.to`** | `boolean` | - | - | The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`. |
+| **`port.fallback`** | `auto`, `none` | - | `auto` | The fallback strategy to use when the preferred port is unavailable. |
+| **`port.host`** | `string` | - | `0.0.0.0` | The host to listern on (only used for port number lookup). |
+| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
@@ -360,13 +374,20 @@ This combines `dev` & `start` via a `dev` option toggle.
#### Options
-| Name | Type | Required | Default | Description |
-| ------------- | ---------- | :------: | ------- | ------------------------------------------------------------------------------------------- |
-| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
-| **`dev`** | `string` | - | `false` | Run the server in dev or production mode. |
-| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
-| **`port`** | `number` | - | `4000` | The port number to run on. |
-| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
+| Name | Type | Required | Default | Description |
+| --------------------- | -------------- | :------: | --------- | -------------------------------------------------------------------------------------------------- |
+| **`debug`** | `boolean` | - | `false` | Display debugging info by applying the `DEBUG` env variable. |
+| **`dev`** | `string` | - | `false` | Run the server in dev or production mode. |
+| **`dir`** | `string` | ✅ | - | The path of the directory containing the GraphQL Mesh config. |
+| **`port`** | `object` | - | - | Port selection settings |
+| **`port.auto`** | `boolean` | - | `true` | Use the first available port |
+| **`port.number`** | `number` | - | `4200` | Define the preferred port to use when `auto` is set to `false` |
+| **`port.range`** | `object` | - | - | The range of ports to select from. |
+| **`port.range.from`** | `boolean` | - | - | The first port of the range. Must be in the range `1024`...`65535` |
+| **`port.range.to`** | `boolean` | - | - | The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`. |
+| **`port.fallback`** | `auto`, `none` | - | `auto` | The fallback strategy to use when the preferred port is unavailable. |
+| **`port.host`** | `string` | - | `0.0.0.0` | The host to listern on (only used for port number lookup). |
+| **`require`** | `string[]` | - | `[]` | Loads specific require.extensions before running the codegen and reading the configuration. |
diff --git a/apps/api-gateway/javascript-wiki/cjs-config/project.json b/apps/api-gateway/javascript-wiki/cjs-config/project.json
index c6a6d804..a4035209 100644
--- a/apps/api-gateway/javascript-wiki/cjs-config/project.json
+++ b/apps/api-gateway/javascript-wiki/cjs-config/project.json
@@ -18,8 +18,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "apps/api-gateway/javascript-wiki/cjs-config",
- "port": 4800
+ "dir": "apps/api-gateway/javascript-wiki/cjs-config"
},
"configurations": {
"production": {
diff --git a/apps/api-gateway/javascript-wiki/js-config/project.json b/apps/api-gateway/javascript-wiki/js-config/project.json
index 34a2b007..6a18133e 100644
--- a/apps/api-gateway/javascript-wiki/js-config/project.json
+++ b/apps/api-gateway/javascript-wiki/js-config/project.json
@@ -18,8 +18,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "apps/api-gateway/javascript-wiki/js-config",
- "port": 4801
+ "dir": "apps/api-gateway/javascript-wiki/js-config"
},
"configurations": {
"production": {
diff --git a/apps/api-gateway/javascript-wiki/json-config/project.json b/apps/api-gateway/javascript-wiki/json-config/project.json
index da2df0e1..9f2bef8e 100644
--- a/apps/api-gateway/javascript-wiki/json-config/project.json
+++ b/apps/api-gateway/javascript-wiki/json-config/project.json
@@ -18,8 +18,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "apps/api-gateway/javascript-wiki/json-config",
- "port": 4802
+ "dir": "apps/api-gateway/javascript-wiki/json-config"
},
"configurations": {
"production": {
diff --git a/apps/api-gateway/javascript-wiki/yml-config/project.json b/apps/api-gateway/javascript-wiki/yml-config/project.json
index a65db822..6c01f8ad 100644
--- a/apps/api-gateway/javascript-wiki/yml-config/project.json
+++ b/apps/api-gateway/javascript-wiki/yml-config/project.json
@@ -18,8 +18,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "apps/api-gateway/javascript-wiki/yml-config",
- "port": 4803
+ "dir": "apps/api-gateway/javascript-wiki/yml-config"
},
"configurations": {
"production": {
diff --git a/apps/api-gateway/stackexchange/project.json b/apps/api-gateway/stackexchange/project.json
index 24d76368..c89b8531 100644
--- a/apps/api-gateway/stackexchange/project.json
+++ b/apps/api-gateway/stackexchange/project.json
@@ -23,40 +23,34 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "apps/api-gateway/stackexchange",
- "port": 4700,
"dev": true
},
"configurations": {
"production": {
"dir": "dist/apps/api-gateway/stackexchange",
- "dev": false,
- "port": 5200
+ "dev": false
}
}
},
"dev": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:dev",
"options": {
- "dir": "apps/api-gateway/stackexchange",
- "port": 4500
+ "dir": "apps/api-gateway/stackexchange"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 4700
+ "debug": false
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
- "dir": "dist/apps/api-gateway/stackexchange",
- "port": 5200
+ "dir": "dist/apps/api-gateway/stackexchange"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 5201
+ "debug": false
}
},
"dependsOn": [
diff --git a/apps/api-gateway/trippin/project.json b/apps/api-gateway/trippin/project.json
index b56e11b8..9b10c9e4 100644
--- a/apps/api-gateway/trippin/project.json
+++ b/apps/api-gateway/trippin/project.json
@@ -20,40 +20,37 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "apps/api-gateway/trippin",
- "port": 5001,
- "dev": true
+ "dev": true,
+ "port": {
+ "host": "localhost"
+ }
},
"configurations": {
"production": {
"dir": "dist/apps/api-gateway/trippin",
- "dev": false,
- "port": 5100
+ "dev": false
}
}
},
"dev": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:dev",
"options": {
- "dir": "apps/api-gateway/trippin",
- "port": 4500
+ "dir": "apps/api-gateway/trippin"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 5001
+ "debug": false
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
- "dir": "dist/apps/api-gateway/trippin",
- "port": 5100
+ "dir": "dist/apps/api-gateway/trippin"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 5101
+ "debug": false
}
},
"dependsOn": [
diff --git a/apps/api-gateway/weatherbit/project.json b/apps/api-gateway/weatherbit/project.json
index 5d139f24..30070d20 100644
--- a/apps/api-gateway/weatherbit/project.json
+++ b/apps/api-gateway/weatherbit/project.json
@@ -20,40 +20,34 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "apps/api-gateway/weatherbit",
- "port": 4600,
"dev": true
},
"configurations": {
"production": {
"dir": "dist/apps/api-gateway/weatherbit",
- "dev": false,
- "port": 5300
+ "dev": false
}
}
},
"dev": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:dev",
"options": {
- "dir": "apps/api-gateway/weatherbit",
- "port": 4500
+ "dir": "apps/api-gateway/weatherbit"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 4600
+ "debug": false
}
}
},
"start": {
"executor": "@domjtalbot/nx-plugin-graphql-mesh:start",
"options": {
- "dir": "dist/apps/api-gateway/weatherbit",
- "port": 5300
+ "dir": "dist/apps/api-gateway/weatherbit"
},
"configurations": {
"e2e": {
- "debug": false,
- "port": 5301
+ "debug": false
}
},
"dependsOn": [
diff --git a/apps/nextjs/javascript-wiki-swc/project.json b/apps/nextjs/javascript-wiki-swc/project.json
index 0098df20..bab504ed 100644
--- a/apps/nextjs/javascript-wiki-swc/project.json
+++ b/apps/nextjs/javascript-wiki-swc/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-javascript-wiki-swc:build",
- "dev": true
+ "dev": true,
+ "port": 4800
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-javascript-wiki-swc:build:production",
- "dev": false,
- "port": 4900
+ "dev": false
},
"production": {
"buildTarget": "nextjs-javascript-wiki-swc:build:production",
diff --git a/apps/nextjs/javascript-wiki/project.json b/apps/nextjs/javascript-wiki/project.json
index 36c6c86c..e388589b 100644
--- a/apps/nextjs/javascript-wiki/project.json
+++ b/apps/nextjs/javascript-wiki/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-javascript-wiki:build",
- "dev": true
+ "dev": true,
+ "port": 5000
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-javascript-wiki:build:production",
- "dev": false,
- "port": 4900
+ "dev": false
},
"production": {
"buildTarget": "nextjs-javascript-wiki:build:production",
diff --git a/apps/nextjs/stackexchange/project.json b/apps/nextjs/stackexchange/project.json
index 22b8dcce..9b0048f9 100644
--- a/apps/nextjs/stackexchange/project.json
+++ b/apps/nextjs/stackexchange/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-stackexchange:build",
- "dev": true
+ "dev": true,
+ "port": 4700
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-stackexchange:build:production",
- "dev": false,
- "port": 5002
+ "dev": false
},
"production": {
"buildTarget": "nextjs-stackexchange:build:production",
diff --git a/apps/nextjs/trippin-swc/project.json b/apps/nextjs/trippin-swc/project.json
index ad44dd46..2915653b 100644
--- a/apps/nextjs/trippin-swc/project.json
+++ b/apps/nextjs/trippin-swc/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-trippin-swc:build",
- "dev": true
+ "dev": true,
+ "port": 4500
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-trippin:build:production",
- "dev": false,
- "port": 4300
+ "dev": false
},
"production": {
"buildTarget": "nextjs-trippin-swc:build:production",
diff --git a/apps/nextjs/trippin/project.json b/apps/nextjs/trippin/project.json
index 5ce8ac35..b02458b8 100644
--- a/apps/nextjs/trippin/project.json
+++ b/apps/nextjs/trippin/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-trippin:build",
- "dev": true
+ "dev": true,
+ "port": 4600
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-trippin:build:production",
- "dev": false,
- "port": 4900
+ "dev": false
},
"production": {
"buildTarget": "nextjs-trippin:build:production",
diff --git a/apps/nextjs/weatherbit/project.json b/apps/nextjs/weatherbit/project.json
index 9ec9e167..84d9a4a2 100644
--- a/apps/nextjs/weatherbit/project.json
+++ b/apps/nextjs/weatherbit/project.json
@@ -21,7 +21,8 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "nextjs-weatherbit:build",
- "dev": true
+ "dev": true,
+ "port": 4400
},
"configurations": {
"development": {
@@ -30,8 +31,7 @@
},
"e2e": {
"buildTarget": "nextjs-weatherbit:build:production",
- "dev": false,
- "port": 5003
+ "dev": false
},
"production": {
"buildTarget": "nextjs-weatherbit:build:production",
diff --git a/libs/nx-plugin-graphql-mesh/package.json b/libs/nx-plugin-graphql-mesh/package.json
index b800abbd..8624b456 100644
--- a/libs/nx-plugin-graphql-mesh/package.json
+++ b/libs/nx-plugin-graphql-mesh/package.json
@@ -14,6 +14,7 @@
"@nrwl/workspace": "14.1.9",
"@types/fs-extra": "9.0.13",
"fs-extra": "10.1.0",
+ "get-port": "5.1.1",
"type-fest": "2.18.0"
}
}
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/dev/executor.ts b/libs/nx-plugin-graphql-mesh/src/executors/dev/executor.ts
index 1458f414..df7147ec 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/dev/executor.ts
+++ b/libs/nx-plugin-graphql-mesh/src/executors/dev/executor.ts
@@ -4,7 +4,7 @@ import { logger } from '@nrwl/devkit';
import { resolve } from 'path';
import { childProcess, runMeshCli } from '../../utils/mesh-cli';
-
+import getServeLocation from './lib/get-serve-location';
import { DevExecutorSchema } from './schema';
const readyWhenMsg = 'Serving GraphQL Mesh:';
@@ -13,7 +13,7 @@ export async function* devExecutor(
options: DevExecutorSchema,
context: ExecutorContext
) {
- const baseUrl = `http://0.0.0.0:${options.port}`;
+ const { baseUrl, port } = await getServeLocation(options);
logger.info('Starting GraphQL Mesh dev server...');
@@ -22,7 +22,7 @@ export async function* devExecutor(
{
args: {
dir: resolve(context.root, options.dir),
- port: options.port,
+ port,
require: options.require,
},
env: {
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/dev/lib/get-serve-location.ts b/libs/nx-plugin-graphql-mesh/src/executors/dev/lib/get-serve-location.ts
new file mode 100644
index 00000000..b6d52046
--- /dev/null
+++ b/libs/nx-plugin-graphql-mesh/src/executors/dev/lib/get-serve-location.ts
@@ -0,0 +1,33 @@
+import type { DevExecutorSchema } from '../schema';
+
+import getPort = require('get-port');
+
+export async function getServeLocation(options: DevExecutorSchema) {
+ let port = options.port.number ?? 4200;
+ const isRange = options.port.range !== undefined;
+ const range = getPort.makeRange(
+ options.port.range?.from ?? 1024,
+ options.port.range?.to ?? 65535
+ );
+
+ if (options.port.auto) {
+ port = await getPort({
+ port: isRange ? range : undefined,
+ });
+ } else {
+ if (options.port.fallback === 'auto') {
+ port = await getPort({
+ port: isRange ? range : options.port.number,
+ host: options.port.host,
+ });
+ }
+ }
+
+ return {
+ baseUrl: `http://${options.port.host}:${port}`,
+ host: options.port.host,
+ port,
+ };
+}
+
+export default getServeLocation;
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.d.ts b/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.d.ts
index 28caef4b..6d9715ef 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.d.ts
+++ b/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.d.ts
@@ -10,9 +10,47 @@ export interface DevExecutorSchema {
dir: string;
/**
- * The port number to run on.
+ * The port number settings
*/
- port: number;
+ port: {
+ /**
+ * Use the first available port
+ */
+ auto: boolean;
+
+ /**
+ * The range of ports to select from.
+ */
+ range?: {
+ /**
+ * The first port of the range.
+ * Must be in the range `1024`...`65535`.
+ */
+ from?: number;
+
+ /**
+ * The last port of the range.
+ * Must be in the range `1024`...`65535` and must be greater
+ * than `from`.
+ */
+ to?: number;
+ };
+
+ /**
+ * Fallback action to take if the define port is unavailable.
+ */
+ fallback: 'auto' | 'none';
+
+ /**
+ * The port number to run on.
+ */
+ number: number;
+
+ /**
+ * The host to listern on.
+ */
+ host: string;
+ };
/**
* Loads specific require.extensions before running the codegen
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.json b/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.json
index b3ef7b93..c4399cc8 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.json
+++ b/libs/nx-plugin-graphql-mesh/src/executors/dev/schema.json
@@ -15,9 +15,44 @@
"type": "string"
},
"port": {
- "type": "integer",
- "description": "The port number to run on.",
- "default": 4000
+ "type": "object",
+ "properties": {
+ "auto": {
+ "type": "boolean",
+ "description": "Use the first available port.",
+ "default": true
+ },
+ "range": {
+ "type": "object",
+ "description": "The range of ports to select from. (Takes priority over `number`)",
+ "properties": {
+ "from": {
+ "type": "number",
+ "description": "The first port of the range. Must be in the range `1024`...`65535`."
+ },
+ "to": {
+ "type": "number",
+ "description": "The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`."
+ }
+ }
+ },
+ "number": {
+ "type": "integer",
+ "description": "The port number to run on.",
+ "default": 4200
+ },
+ "fallback": {
+ "type": "string",
+ "enum": ["auto", "none"],
+ "description": "Fallback action to take if the define port is unavailable.",
+ "default": "auto"
+ },
+ "host": {
+ "type": "string",
+ "description": "The host to listern on.",
+ "default": "0.0.0.0"
+ }
+ }
},
"require": {
"type": "array",
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/serve/schema.json b/libs/nx-plugin-graphql-mesh/src/executors/serve/schema.json
index f09d0ae1..2215fffc 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/serve/schema.json
+++ b/libs/nx-plugin-graphql-mesh/src/executors/serve/schema.json
@@ -20,9 +20,44 @@
"type": "string"
},
"port": {
- "type": "integer",
- "description": "The port number to run on.",
- "default": 4000
+ "type": "object",
+ "properties": {
+ "auto": {
+ "type": "boolean",
+ "description": "Use the first available port.",
+ "default": true
+ },
+ "range": {
+ "type": "object",
+ "description": "The range of ports to select from.",
+ "properties": {
+ "from": {
+ "type": "number",
+ "description": "The first port of the range. Must be in the range `1024`...`65535`."
+ },
+ "to": {
+ "type": "number",
+ "description": "The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`."
+ }
+ }
+ },
+ "number": {
+ "type": "integer",
+ "description": "The port number to run on.",
+ "default": 4200
+ },
+ "fallback": {
+ "type": "string",
+ "enum": ["auto", "none"],
+ "description": "Fallback action to take if the define port is unavailable.",
+ "default": "auto"
+ },
+ "host": {
+ "type": "string",
+ "description": "The host to listern on.",
+ "default": "0.0.0.0"
+ }
+ }
},
"require": {
"type": "array",
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/start/lib/get-serve-location.ts b/libs/nx-plugin-graphql-mesh/src/executors/start/lib/get-serve-location.ts
new file mode 100644
index 00000000..09cb531d
--- /dev/null
+++ b/libs/nx-plugin-graphql-mesh/src/executors/start/lib/get-serve-location.ts
@@ -0,0 +1,33 @@
+import type { StartExecutorSchema } from '../schema';
+
+import getPort = require('get-port');
+
+export async function getServeLocation(options: StartExecutorSchema) {
+ let port = options.port.number ?? 4200;
+ const isRange = options.port.range !== undefined;
+ const range = getPort.makeRange(
+ options.port.range?.from ?? 1024,
+ options.port.range?.to ?? 65535
+ );
+
+ if (options.port.auto) {
+ port = await getPort({
+ port: isRange ? range : undefined,
+ });
+ } else {
+ if (options.port.fallback === 'auto') {
+ port = await getPort({
+ port: isRange ? range : options.port.number,
+ host: options.port.host,
+ });
+ }
+ }
+
+ return {
+ baseUrl: `http://${options.port.host}:${port}`,
+ host: options.port.host,
+ port,
+ };
+}
+
+export default getServeLocation;
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/start/schema.json b/libs/nx-plugin-graphql-mesh/src/executors/start/schema.json
index 95f4808e..ee5a1db7 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/start/schema.json
+++ b/libs/nx-plugin-graphql-mesh/src/executors/start/schema.json
@@ -15,9 +15,44 @@
"type": "string"
},
"port": {
- "type": "integer",
- "description": "The port number to run on.",
- "default": 4000
+ "type": "object",
+ "properties": {
+ "auto": {
+ "type": "boolean",
+ "description": "Use the first available port.",
+ "default": true
+ },
+ "range": {
+ "type": "object",
+ "description": "The range of ports to select from.",
+ "properties": {
+ "from": {
+ "type": "number",
+ "description": "The first port of the range. Must be in the range `1024`...`65535`."
+ },
+ "to": {
+ "type": "number",
+ "description": "The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`."
+ }
+ }
+ },
+ "number": {
+ "type": "integer",
+ "description": "The port number to run on.",
+ "default": 4200
+ },
+ "fallback": {
+ "type": "string",
+ "enum": ["auto", "none"],
+ "description": "Fallback action to take if the define port is unavailable.",
+ "default": "auto"
+ },
+ "host": {
+ "type": "string",
+ "description": "The host to listern on.",
+ "default": "0.0.0.0"
+ }
+ }
},
"require": {
"type": "array",
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/start/schema.ts b/libs/nx-plugin-graphql-mesh/src/executors/start/schema.ts
index 0d61976c..f8747c37 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/start/schema.ts
+++ b/libs/nx-plugin-graphql-mesh/src/executors/start/schema.ts
@@ -2,5 +2,48 @@ import type { Options } from '../../utils';
type MeshStartSchema = Options<'start'>;
-export type StartExecutorSchema = MeshStartSchema['args'] &
- MeshStartSchema['env'];
+export type StartExecutorSchema = Omit &
+ MeshStartSchema['env'] & {
+ /**
+ * The port number settings
+ */
+ port: {
+ /**
+ * Use the first available port
+ */
+ auto: boolean;
+
+ /**
+ * The range of ports to select from.
+ */
+ range?: {
+ /**
+ * The first port of the range.
+ * Must be in the range `1024`...`65535`.
+ */
+ from?: number;
+
+ /**
+ * The last port of the range.
+ * Must be in the range `1024`...`65535` and must be greater
+ * than `from`.
+ */
+ to?: number;
+ };
+
+ /**
+ * Fallback action to take if the define port is unavailable.
+ */
+ fallback: 'auto' | 'none';
+
+ /**
+ * The port number to run on.
+ */
+ number: number;
+
+ /**
+ * The host to listern on.
+ */
+ host: string;
+ };
+ };
diff --git a/libs/nx-plugin-graphql-mesh/src/executors/start/start.impl.ts b/libs/nx-plugin-graphql-mesh/src/executors/start/start.impl.ts
index c2f4fd20..f0346f6a 100644
--- a/libs/nx-plugin-graphql-mesh/src/executors/start/start.impl.ts
+++ b/libs/nx-plugin-graphql-mesh/src/executors/start/start.impl.ts
@@ -4,7 +4,7 @@ import { logger } from '@nrwl/devkit';
import { resolve } from 'path';
import { childProcess, runMeshCli } from '../../utils/mesh-cli';
-
+import getServeLocation from './lib/get-serve-location';
import { StartExecutorSchema } from './schema';
const readyWhenMsg = 'Serving GraphQL Mesh:';
@@ -17,7 +17,7 @@ export async function* startExecutor(
throw new Error("Please define the 'dir' value");
}
- const baseUrl = `http://0.0.0.0:${options.port}`;
+ const { baseUrl, port } = await getServeLocation(options);
logger.info('Starting GraphQL Mesh start server...');
@@ -26,7 +26,7 @@ export async function* startExecutor(
{
args: {
dir: resolve(context.root, options.dir),
- port: options.port,
+ port,
require: options.require,
},
env: {
diff --git a/libs/nx-plugin-graphql-mesh/src/generators/application/application.spec.ts b/libs/nx-plugin-graphql-mesh/src/generators/application/application.spec.ts
index 245befcd..0760f3c4 100644
--- a/libs/nx-plugin-graphql-mesh/src/generators/application/application.spec.ts
+++ b/libs/nx-plugin-graphql-mesh/src/generators/application/application.spec.ts
@@ -54,7 +54,6 @@ describe('app', () => {
options: {
dev: true,
dir: 'apps/my-mesh-app',
- port: 4200,
},
configurations: {
production: {
diff --git a/libs/nx-plugin-graphql-mesh/src/generators/application/lib/add-project.ts b/libs/nx-plugin-graphql-mesh/src/generators/application/lib/add-project.ts
index 07d748af..d7969370 100644
--- a/libs/nx-plugin-graphql-mesh/src/generators/application/lib/add-project.ts
+++ b/libs/nx-plugin-graphql-mesh/src/generators/application/lib/add-project.ts
@@ -30,7 +30,6 @@ export function addProject(tree: Tree, options: AppGeneratorSchema) {
options: {
dev: true,
dir: appProjectRoot,
- port: 4200,
},
configurations: {
production: {
diff --git a/libs/nx-plugin-graphql-mesh/src/generators/sdk/lib/add-project.ts b/libs/nx-plugin-graphql-mesh/src/generators/sdk/lib/add-project.ts
index d09efbb0..e589f89a 100644
--- a/libs/nx-plugin-graphql-mesh/src/generators/sdk/lib/add-project.ts
+++ b/libs/nx-plugin-graphql-mesh/src/generators/sdk/lib/add-project.ts
@@ -41,7 +41,6 @@ export function addProject(tree: Tree, options: NormalizedSchema) {
options: {
dev: true,
dir: libProjectRoot,
- port: 4200,
},
};
diff --git a/libs/nx-plugin-graphql-mesh/src/generators/sdk/sdk.spec.ts b/libs/nx-plugin-graphql-mesh/src/generators/sdk/sdk.spec.ts
index fb7c4b93..956f7145 100644
--- a/libs/nx-plugin-graphql-mesh/src/generators/sdk/sdk.spec.ts
+++ b/libs/nx-plugin-graphql-mesh/src/generators/sdk/sdk.spec.ts
@@ -56,7 +56,6 @@ describe('sdk', () => {
options: {
dev: true,
dir: 'libs/my-mesh-sdk',
- port: 4200,
},
},
})
diff --git a/libs/nx-plugin-graphql-mesh/tsconfig.json b/libs/nx-plugin-graphql-mesh/tsconfig.json
index 5fd697b3..1e75c1e4 100644
--- a/libs/nx-plugin-graphql-mesh/tsconfig.json
+++ b/libs/nx-plugin-graphql-mesh/tsconfig.json
@@ -1,14 +1,17 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
- "module": "commonjs",
+ "allowJs": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
- "strict": true,
+ "module": "commonjs",
+ "noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
- "noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true,
- "allowSyntheticDefaultImports": true
+ "noPropertyAccessFromIndexSignature": true,
+ "strict": true,
+ "isolatedModules": true
},
"files": [],
"include": [],
diff --git a/libs/sdk/javascript-wiki-cjs/project.json b/libs/sdk/javascript-wiki-cjs/project.json
index 4d3110a6..916c0140 100644
--- a/libs/sdk/javascript-wiki-cjs/project.json
+++ b/libs/sdk/javascript-wiki-cjs/project.json
@@ -32,8 +32,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-cjs",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-cjs"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-js/project.json b/libs/sdk/javascript-wiki-js/project.json
index c7d95778..1da2f73f 100644
--- a/libs/sdk/javascript-wiki-js/project.json
+++ b/libs/sdk/javascript-wiki-js/project.json
@@ -32,8 +32,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-js",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-js"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-json/project.json b/libs/sdk/javascript-wiki-json/project.json
index a6c5b569..1f99af72 100644
--- a/libs/sdk/javascript-wiki-json/project.json
+++ b/libs/sdk/javascript-wiki-json/project.json
@@ -35,8 +35,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-json",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-json"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-swc-cjs/project.json b/libs/sdk/javascript-wiki-swc-cjs/project.json
index a1525591..bbd2190b 100644
--- a/libs/sdk/javascript-wiki-swc-cjs/project.json
+++ b/libs/sdk/javascript-wiki-swc-cjs/project.json
@@ -35,8 +35,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-swc-cjs",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-swc-cjs"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-swc-js/project.json b/libs/sdk/javascript-wiki-swc-js/project.json
index af48af89..c8e9cc02 100644
--- a/libs/sdk/javascript-wiki-swc-js/project.json
+++ b/libs/sdk/javascript-wiki-swc-js/project.json
@@ -35,8 +35,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-swc-js",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-swc-js"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-swc-json/project.json b/libs/sdk/javascript-wiki-swc-json/project.json
index a333583d..5f0c0945 100644
--- a/libs/sdk/javascript-wiki-swc-json/project.json
+++ b/libs/sdk/javascript-wiki-swc-json/project.json
@@ -35,8 +35,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-swc-json",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-swc-json"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki-swc/project.json b/libs/sdk/javascript-wiki-swc/project.json
index 3b5d3611..f7c7d6f4 100644
--- a/libs/sdk/javascript-wiki-swc/project.json
+++ b/libs/sdk/javascript-wiki-swc/project.json
@@ -32,8 +32,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki-swc",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki-swc"
}
},
"validate": {
diff --git a/libs/sdk/javascript-wiki/project.json b/libs/sdk/javascript-wiki/project.json
index 167dcaa3..168999ee 100644
--- a/libs/sdk/javascript-wiki/project.json
+++ b/libs/sdk/javascript-wiki/project.json
@@ -23,8 +23,7 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dev": true,
- "dir": "libs/sdk/javascript-wiki",
- "port": 4200
+ "dir": "libs/sdk/javascript-wiki"
}
},
"test": {
diff --git a/libs/sdk/stackexchange/project.json b/libs/sdk/stackexchange/project.json
index 2449fdb2..b3f86b2c 100644
--- a/libs/sdk/stackexchange/project.json
+++ b/libs/sdk/stackexchange/project.json
@@ -22,7 +22,6 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "libs/sdk/stackexchange",
- "port": 4610,
"dev": true
}
},
diff --git a/libs/sdk/trippin-swc/project.json b/libs/sdk/trippin-swc/project.json
index 52500ad4..192b6de3 100644
--- a/libs/sdk/trippin-swc/project.json
+++ b/libs/sdk/trippin-swc/project.json
@@ -22,7 +22,6 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "libs/sdk/trippin-swc",
- "port": 4630,
"dev": true
}
},
diff --git a/libs/sdk/trippin/project.json b/libs/sdk/trippin/project.json
index 92b41470..28145d80 100644
--- a/libs/sdk/trippin/project.json
+++ b/libs/sdk/trippin/project.json
@@ -22,7 +22,6 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "libs/sdk/trippin",
- "port": 4620,
"dev": true
}
},
diff --git a/libs/sdk/weatherbit/project.json b/libs/sdk/weatherbit/project.json
index af88ed7f..3eb1c75e 100644
--- a/libs/sdk/weatherbit/project.json
+++ b/libs/sdk/weatherbit/project.json
@@ -22,7 +22,6 @@
"executor": "@domjtalbot/nx-plugin-graphql-mesh:serve",
"options": {
"dir": "libs/sdk/weatherbit",
- "port": 4640,
"dev": true
}
},
diff --git a/package.json b/package.json
index 1f0c9d5b..376e4d37 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"@swc/helpers": "0.4.3",
"core-js": "3.22.8",
"encoding": "0.1.13",
+ "get-port": "5.1.1",
"graphql": "16.5.0",
"next": "12.1.6",
"react": "18.2.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 89abde7a..655c317c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -55,6 +55,7 @@ specifiers:
eslint-plugin-react: 7.30.1
eslint-plugin-react-hooks: 4.6.0
fs-extra: 10.1.0
+ get-port: 5.1.1
graphql: 16.5.0
husky: 8.0.1
jest: 27.5.1
@@ -95,6 +96,7 @@ dependencies:
'@swc/helpers': 0.4.3
core-js: 3.22.8
encoding: 0.1.13
+ get-port: 5.1.1
graphql: 16.5.0
next: 12.1.6_biqbaboplfbrettd7655fr4n2y
react: 18.2.0
@@ -10670,6 +10672,14 @@ packages:
}
engines: { node: '>=8.0.0' }
+ /get-port/5.1.1:
+ resolution:
+ {
+ integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==,
+ }
+ engines: { node: '>=8' }
+ dev: false
+
/get-stream/5.2.0:
resolution:
{