From a3ef411616847eb2170d0342b47d60c572c58cff Mon Sep 17 00:00:00 2001 From: David Glasser Date: Mon, 15 Aug 2022 17:47:06 -0700 Subject: [PATCH] Move ApolloServerPluginLandingPageGraphQLPlayground to new package GraphQL Playground was unmaintained when we released Apollo Server 3, and the Apollo Server team has had to put significant work into fixing security issues in GraphQL Playground. While we will still publish a landing page plugin to enable folks upgrading from AS2 to not have to immediately retrain their users on how to use Apollo Sandbox or another interface, we remove it from the main `@apollo/server` package and move it to its own `@apollo/server-plugin-landing-page-graphql-playground` package. This lets us remove the Playground HTML package's dependencies (like `xss`) from Apollo Server's main package. Fixes #6109. --- .changeset/ninety-panthers-accept.md | 7 ++++ docs/source/migration.mdx | 6 ++- package-lock.json | 28 +++++++++++++- packages/integration-testsuite/package.json | 1 + .../src/apolloServerTests.ts | 2 +- packages/integration-testsuite/tsconfig.json | 1 + .../README.md | 21 +++++++++++ .../package.json | 37 +++++++++++++++++++ .../src}/index.ts | 5 +-- .../tsconfig.cjs.json | 11 ++++++ .../tsconfig.json | 14 +++++++ packages/server/package.json | 6 --- .../graphqlPlayground/package.json | 8 ---- scripts/postcompile.mjs | 6 ++- smoke-test/smoke-test.cjs | 1 - smoke-test/smoke-test.cts | 1 - smoke-test/smoke-test.mjs | 1 - smoke-test/smoke-test.mts | 1 - tsconfig.build.json | 2 + 19 files changed, 131 insertions(+), 28 deletions(-) create mode 100644 .changeset/ninety-panthers-accept.md create mode 100644 packages/plugin-landing-page-graphql-playground/README.md create mode 100644 packages/plugin-landing-page-graphql-playground/package.json rename packages/{server/src/plugin/landingPage/graphqlPlayground => plugin-landing-page-graphql-playground/src}/index.ts (94%) create mode 100644 packages/plugin-landing-page-graphql-playground/tsconfig.cjs.json create mode 100644 packages/plugin-landing-page-graphql-playground/tsconfig.json delete mode 100644 packages/server/plugin/landingPage/graphqlPlayground/package.json diff --git a/.changeset/ninety-panthers-accept.md b/.changeset/ninety-panthers-accept.md new file mode 100644 index 00000000000..580625636c5 --- /dev/null +++ b/.changeset/ninety-panthers-accept.md @@ -0,0 +1,7 @@ +--- +"@apollo/server-plugin-landing-page-graphql-playground": major +"@apollo/server-integration-testsuite": patch +"@apollo/server": patch +--- + +Move ApolloServerPluginGraphQLPlayground into its own package. diff --git a/docs/source/migration.mdx b/docs/source/migration.mdx index 33c5f2ada75..939a48ecc28 100644 --- a/docs/source/migration.mdx +++ b/docs/source/migration.mdx @@ -300,7 +300,9 @@ In Apollo Server 3, the `apollo-server-core` package exports built-in plugins, l In Apollo Server 4, these built-in plugins are part of the main `@apollo/server` package, which also imports the `ApolloServer` class. The `@apollo/server` package exports these built-in plugins with deep exports. This means you use deep imports for each built-in plugin, enabling you to evaluate only the plugin you use in your app and making it easier for bundlers to eliminate unused code. - The `@apollo/server` package exports the following plugins: +There's one exception: the plugin `ApolloServerPluginLandingPageGraphQLPlayground` has been moved to its own package `@apollo/server-plugin-landing-page-graphql-playground` which must be installed separately. (This plugin installs the [unmaintained](https://github.com/graphql/graphql-playground/issues/1143) project GraphQL Playground as a landing page, and is provided for compatibility with Apollo Server 2. We encourage you to switch to the [default landing page](/apollo-server/v3/api/plugin/landing-pages), which installs the similar but the actively maintained Apollo Sandbox instead.) + + Apollo Server exports the following plugins: | Plugin | Import path | |--------|-------------| @@ -310,7 +312,7 @@ In Apollo Server 4, these built-in plugins are part of the main `@apollo/server` | `ApolloServerPluginInlineTrace` | `@apollo/server/plugin/inlineTrace` | | `ApolloServerPluginInlineTraceDisabled` | `@apollo/server/plugin/disabled` | | `ApolloServerPluginLandingPageDisabled` | `@apollo/server/plugin/disabled` | -| `ApolloServerPluginLandingPageGraphQLPlayground` | `@apollo/server/plugin/landingPage/graphqlPlayground` | +| `ApolloServerPluginLandingPageGraphQLPlayground` | `@apollo/server-plugin-landing-page-graphql-playground` | | `ApolloServerPluginLandingPageLocalDefault` | `@apollo/server/plugin/landingPage/default` | | `ApolloServerPluginLandingPageProductionDefault` | `@apollo/server/plugin/landingPage/default` | | `ApolloServerPluginSchemaReporting` | `@apollo/server/plugin/schemaReporting` | diff --git a/package-lock.json b/package-lock.json index 42a5ce1448f..6524f95ead2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -308,6 +308,10 @@ "resolved": "packages/integration-testsuite", "link": true }, + "node_modules/@apollo/server-plugin-landing-page-graphql-playground": { + "resolved": "packages/plugin-landing-page-graphql-playground", + "link": true + }, "node_modules/@apollo/server-plugin-response-cache": { "resolved": "packages/plugin-response-cache", "link": true @@ -15050,6 +15054,7 @@ "dependencies": { "@apollo/cache-control-types": "^1.0.2", "@apollo/client": "^3.6.9", + "@apollo/server-plugin-landing-page-graphql-playground": "3.0.0", "@apollo/usage-reporting-protobuf": "^4.0.0-alpha.1", "@apollo/utils.createhash": "^1.1.0", "@apollo/utils.keyvaluecache": "^1.0.1", @@ -15071,6 +15076,20 @@ "jest": "28.x" } }, + "packages/plugin-landing-page-graphql-playground": { + "name": "@apollo/server-plugin-landing-page-graphql-playground", + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@apollographql/graphql-playground-html": "1.6.29" + }, + "engines": { + "node": ">=14.0" + }, + "peerDependencies": { + "@apollo/server": "^4.0.0-alpha.6" + } + }, "packages/plugin-response-cache": { "name": "@apollo/server-plugin-response-cache", "version": "4.0.0-alpha.4", @@ -15102,7 +15121,6 @@ "@apollo/utils.logger": "^1.0.0", "@apollo/utils.usagereporting": "^1.0.0", "@apollo/utils.withrequired": "^1.0.0", - "@apollographql/graphql-playground-html": "1.6.29", "@graphql-tools/schema": "^9.0.0", "@josephg/resolvable": "^1.0.0", "@types/express": "4.17.13", @@ -15284,7 +15302,6 @@ "@apollo/utils.logger": "^1.0.0", "@apollo/utils.usagereporting": "^1.0.0", "@apollo/utils.withrequired": "^1.0.0", - "@apollographql/graphql-playground-html": "1.6.29", "@graphql-tools/schema": "^9.0.0", "@josephg/resolvable": "^1.0.0", "@types/express": "4.17.13", @@ -15323,6 +15340,7 @@ "requires": { "@apollo/cache-control-types": "^1.0.2", "@apollo/client": "^3.6.9", + "@apollo/server-plugin-landing-page-graphql-playground": "3.0.0", "@apollo/usage-reporting-protobuf": "^4.0.0-alpha.1", "@apollo/utils.createhash": "^1.1.0", "@apollo/utils.keyvaluecache": "^1.0.1", @@ -15335,6 +15353,12 @@ "supertest": "^6.2.3" } }, + "@apollo/server-plugin-landing-page-graphql-playground": { + "version": "file:packages/plugin-landing-page-graphql-playground", + "requires": { + "@apollographql/graphql-playground-html": "1.6.29" + } + }, "@apollo/server-plugin-response-cache": { "version": "file:packages/plugin-response-cache", "requires": { diff --git a/packages/integration-testsuite/package.json b/packages/integration-testsuite/package.json index 36bcd12cb34..c1d1e1252de 100644 --- a/packages/integration-testsuite/package.json +++ b/packages/integration-testsuite/package.json @@ -29,6 +29,7 @@ "dependencies": { "@apollo/cache-control-types": "^1.0.2", "@apollo/client": "^3.6.9", + "@apollo/server-plugin-landing-page-graphql-playground": "3.0.0", "@apollo/utils.keyvaluecache": "^1.0.1", "@apollo/utils.createhash": "^1.1.0", "@apollo/usage-reporting-protobuf": "^4.0.0-alpha.1", diff --git a/packages/integration-testsuite/src/apolloServerTests.ts b/packages/integration-testsuite/src/apolloServerTests.ts index 63761d8b062..3399db5bcc9 100644 --- a/packages/integration-testsuite/src/apolloServerTests.ts +++ b/packages/integration-testsuite/src/apolloServerTests.ts @@ -57,7 +57,7 @@ import { ApolloServerPluginUsageReportingDisabled, } from '@apollo/server/plugin/disabled'; import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default'; -import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server/plugin/landingPage/graphqlPlayground'; +import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-plugin-landing-page-graphql-playground'; import { jest, describe, diff --git a/packages/integration-testsuite/tsconfig.json b/packages/integration-testsuite/tsconfig.json index 21ab8bd4e84..e3506eaddac 100644 --- a/packages/integration-testsuite/tsconfig.json +++ b/packages/integration-testsuite/tsconfig.json @@ -9,6 +9,7 @@ }, "include": ["src/**/*"], "references": [ + { "path": "../plugin-landing-page-graphql-playground" }, { "path": "../server" }, ], } diff --git a/packages/plugin-landing-page-graphql-playground/README.md b/packages/plugin-landing-page-graphql-playground/README.md new file mode 100644 index 00000000000..3016cf326e8 --- /dev/null +++ b/packages/plugin-landing-page-graphql-playground/README.md @@ -0,0 +1,21 @@ +# GraphQL Playground plugin + +This is a plugin for Apollo Server 4 that makes your GraphQL server serve the [GraphQL Playground IDE](https://github.com/graphql/graphql-playground) as a landing page. + +GraphQL Playground was the only landing page available for Apollo Server 2. The GraphQL Playground project is officially [retired](https://github.com/graphql/graphql-playground/issues/1143) and we do not recommend its continued use. We recommend Apollo Server 4's default landing page, which serves the similar but actively maintained [Apollo Sandbox](https://www.apollographql.com/docs/studio/explorer/sandbox/), or a custom landing page. + +To help developers migrating from Apollo Server 2, we do still provide a landing page plugin that allows you to use GraphQL Playground with Apollo Server. In Apollo Server 3, that plugin is distributed as part of the `apollo-server-core` package. In Apollo Server 4, that plugin is distributed separately in this package. + +To use GraphQL Playground with Apollo Server 4, first `npm install @apollo/server-plugin-landing-page-graphql-playground`, and then: + +```ts +import { ApolloServer } from '@apollo/server'; +import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-plugin-landing-page-graphql-playground'; + +const server = new ApolloServer({ + plugins: [ApolloServerPluginLandingPageGraphQLPlayground()], + // ... other options ... +}); +``` + +Note that this will serve GraphQL Playground unconditionally. If you would prefer to only serve it when not in production, you can use `process.env.NODE_ENV` to determine whether to include the plugin in the `plugins` option yourself. diff --git a/packages/plugin-landing-page-graphql-playground/package.json b/packages/plugin-landing-page-graphql-playground/package.json new file mode 100644 index 00000000000..0dd4d136b1e --- /dev/null +++ b/packages/plugin-landing-page-graphql-playground/package.json @@ -0,0 +1,37 @@ +{ + "name": "@apollo/server-plugin-landing-page-graphql-playground", + "version": "3.0.0", + "description": "Apollo Server landing page plugin for GraphQL Playground", + "type": "module", + "main": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "types": "dist/esm/index.d.ts", + "exports": { + ".": { + "types": "./dist/esm/index.d.ts", + "import": "./dist/esm/index.js", + "require": "./dist/cjs/index.js" + } + }, + "repository": { + "type": "git", + "url": "https://github.com/apollographql/apollo-server", + "directory": "packages/plugin-landing-page-graphql-playground" + }, + "keywords": [], + "author": "Apollo ", + "license": "MIT", + "bugs": { + "url": "https://github.com/apollographql/apollo-server/issues" + }, + "homepage": "https://github.com/apollographql/apollo-server#readme", + "engines": { + "node": ">=14.0" + }, + "dependencies": { + "@apollographql/graphql-playground-html": "1.6.29" + }, + "peerDependencies": { + "@apollo/server": "^4.0.0-alpha.6" + } +} diff --git a/packages/server/src/plugin/landingPage/graphqlPlayground/index.ts b/packages/plugin-landing-page-graphql-playground/src/index.ts similarity index 94% rename from packages/server/src/plugin/landingPage/graphqlPlayground/index.ts rename to packages/plugin-landing-page-graphql-playground/src/index.ts index 2f54902cf1e..ff80e1e78b2 100644 --- a/packages/server/src/plugin/landingPage/graphqlPlayground/index.ts +++ b/packages/plugin-landing-page-graphql-playground/src/index.ts @@ -5,10 +5,7 @@ // specifying `version` when installing the plugin. import { renderPlaygroundPage } from '@apollographql/graphql-playground-html'; -import type { - ApolloServerPlugin, - GraphQLServerListener, -} from '../../../externalTypes'; +import type { ApolloServerPlugin, GraphQLServerListener } from '@apollo/server'; // This specifies the React version of our fork of GraphQL Playground, // `@apollographql/graphql-playground-react`. It is related to, but not to diff --git a/packages/plugin-landing-page-graphql-playground/tsconfig.cjs.json b/packages/plugin-landing-page-graphql-playground/tsconfig.cjs.json new file mode 100644 index 00000000000..3433a2cfa0c --- /dev/null +++ b/packages/plugin-landing-page-graphql-playground/tsconfig.cjs.json @@ -0,0 +1,11 @@ +{ + "extends": ".", + "compilerOptions": { + "module": "commonjs", + "outDir": "./dist/cjs", + // We delete the CJS .d.ts files in postcompile so we don't need to + // ever make their maps. (We can't disable creating the files because + // this is a composite project.) + "declarationMap": false, + }, +} diff --git a/packages/plugin-landing-page-graphql-playground/tsconfig.json b/packages/plugin-landing-page-graphql-playground/tsconfig.json new file mode 100644 index 00000000000..03ea4ef3e4a --- /dev/null +++ b/packages/plugin-landing-page-graphql-playground/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist/esm" + }, + "include": ["src/**/*"], + "exclude": ["**/__tests__"], + "references": [ + { + "path": "../server" + } + ] +} diff --git a/packages/server/package.json b/packages/server/package.json index 654c109cca5..793ee7379d9 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -52,11 +52,6 @@ "import": "./dist/esm/plugin/landingPage/default/index.js", "require": "./dist/cjs/plugin/landingPage/default/index.js" }, - "./plugin/landingPage/graphqlPlayground": { - "types": "./dist/esm/plugin/landingPage/graphqlPlayground/index.d.ts", - "import": "./dist/esm/plugin/landingPage/graphqlPlayground/index.js", - "require": "./dist/cjs/plugin/landingPage/graphqlPlayground/index.js" - }, "./plugin/schemaReporting": { "types": "./dist/esm/plugin/schemaReporting/index.d.ts", "import": "./dist/esm/plugin/schemaReporting/index.js", @@ -99,7 +94,6 @@ "@apollo/utils.logger": "^1.0.0", "@apollo/utils.usagereporting": "^1.0.0", "@apollo/utils.withrequired": "^1.0.0", - "@apollographql/graphql-playground-html": "1.6.29", "@graphql-tools/schema": "^9.0.0", "@josephg/resolvable": "^1.0.0", "@types/express-serve-static-core": "4.17.30", diff --git a/packages/server/plugin/landingPage/graphqlPlayground/package.json b/packages/server/plugin/landingPage/graphqlPlayground/package.json deleted file mode 100644 index 21d28d18622..00000000000 --- a/packages/server/plugin/landingPage/graphqlPlayground/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@apollo/server/plugin/landingPage/graphqlPlayground", - "type": "module", - "main": "../../../dist/cjs/plugin/landingPage/graphqlPlayground/index.js", - "module": "../../../dist/esm/plugin/landingPage/graphqlPlayground/index.js", - "types": "../../../dist/esm/plugin/landingPage/graphqlPlayground/index.d.ts", - "sideEffects": false -} diff --git a/scripts/postcompile.mjs b/scripts/postcompile.mjs index f32478da5d1..b0803fb057b 100644 --- a/scripts/postcompile.mjs +++ b/scripts/postcompile.mjs @@ -12,7 +12,11 @@ import { writeFileSync } from 'fs'; import rimraf from 'rimraf'; // Tell Node what kinds of files the ".js" files in these subdirectories are. -for (const dir of ['plugin-response-cache', 'server']) { +for (const dir of [ + 'plugin-response-cache', + 'plugin-landing-page-graphql-playground', + 'server', +]) { writeFileSync( path.join('packages', dir, 'dist', 'esm', 'package.json'), JSON.stringify({ type: 'module' }), diff --git a/smoke-test/smoke-test.cjs b/smoke-test/smoke-test.cjs index 16a52bbc179..8c92edbbbeb 100644 --- a/smoke-test/smoke-test.cjs +++ b/smoke-test/smoke-test.cjs @@ -10,7 +10,6 @@ async function validateAllImports() { require('@apollo/server/plugin/drainHttpServer'); require('@apollo/server/plugin/inlineTrace'); require('@apollo/server/plugin/landingPage/default'); - require('@apollo/server/plugin/landingPage/graphqlPlayground'); require('@apollo/server/plugin/schemaReporting'); require('@apollo/server/plugin/usageReporting'); require('@apollo/server/standalone'); diff --git a/smoke-test/smoke-test.cts b/smoke-test/smoke-test.cts index 3b98a702361..0bedeed3e13 100644 --- a/smoke-test/smoke-test.cts +++ b/smoke-test/smoke-test.cts @@ -10,7 +10,6 @@ async function validateAllImports() { await import('@apollo/server/plugin/drainHttpServer'); await import('@apollo/server/plugin/inlineTrace'); await import('@apollo/server/plugin/landingPage/default'); - await import('@apollo/server/plugin/landingPage/graphqlPlayground'); await import('@apollo/server/plugin/schemaReporting'); await import('@apollo/server/plugin/usageReporting'); await import('@apollo/server/standalone'); diff --git a/smoke-test/smoke-test.mjs b/smoke-test/smoke-test.mjs index 95d9caee7b2..2009dcf75a3 100644 --- a/smoke-test/smoke-test.mjs +++ b/smoke-test/smoke-test.mjs @@ -10,7 +10,6 @@ await import('@apollo/server/plugin/disabled'); await import('@apollo/server/plugin/drainHttpServer'); await import('@apollo/server/plugin/inlineTrace'); await import('@apollo/server/plugin/landingPage/default'); -await import('@apollo/server/plugin/landingPage/graphqlPlayground'); await import('@apollo/server/plugin/schemaReporting'); await import('@apollo/server/plugin/usageReporting'); await import('@apollo/server/standalone'); diff --git a/smoke-test/smoke-test.mts b/smoke-test/smoke-test.mts index a3d94885089..fe5ff0b2377 100644 --- a/smoke-test/smoke-test.mts +++ b/smoke-test/smoke-test.mts @@ -10,7 +10,6 @@ async function validateAllImports() { await import('@apollo/server/plugin/drainHttpServer'); await import('@apollo/server/plugin/inlineTrace'); await import('@apollo/server/plugin/landingPage/default'); - await import('@apollo/server/plugin/landingPage/graphqlPlayground'); await import('@apollo/server/plugin/schemaReporting'); await import('@apollo/server/plugin/usageReporting'); await import('@apollo/server/standalone'); diff --git a/tsconfig.build.json b/tsconfig.build.json index 4efc7b53f2d..6349712c70a 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -6,6 +6,8 @@ "include": [], "references": [ { "path": "./packages/integration-testsuite/" }, + { "path": "./packages/plugin-landing-page-graphql-playground" }, + { "path": "./packages/plugin-landing-page-graphql-playground/tsconfig.cjs.json" }, { "path": "./packages/plugin-response-cache" }, { "path": "./packages/plugin-response-cache/tsconfig.cjs.json" }, { "path": "./packages/server" },