diff --git a/.changeset/clean-houses-invent.md b/.changeset/clean-houses-invent.md
new file mode 100644
index 0000000000..fe4a252d48
--- /dev/null
+++ b/.changeset/clean-houses-invent.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-graphiql': patch
+---
+
+Added experimental exports for the new frontend system under `/alpha`.
diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx
index 82b0c927e9..0452cc3709 100644
--- a/packages/app-next/src/App.tsx
+++ b/packages/app-next/src/App.tsx
@@ -18,7 +18,7 @@ import { graphiqlPlugin as legacyGraphiqlPlugin } from '@backstage/plugin-graphi
import { createApp as createLegacyApp } from '@backstage/app-defaults';
import { createApp } from '@backstage/frontend-app-api';
import { pagesPlugin } from './examples/pagesPlugin';
-import { graphiqlPlugin } from './examples/graphiqlPlugin';
+import graphiqlPlugin from '@backstage/plugin-graphiql/alpha';
/*
diff --git a/packages/app-next/src/examples/graphiqlPlugin.tsx b/packages/app-next/src/examples/graphiqlPlugin.tsx
deleted file mode 100644
index 4e3768dafa..0000000000
--- a/packages/app-next/src/examples/graphiqlPlugin.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {
- createPageExtension,
- createPlugin,
-} from '@backstage/frontend-plugin-api';
-import React from 'react';
-
-export const GraphiqlPage = createPageExtension({
- id: 'graphiql.page',
- defaultPath: '/graphiql',
- component: () =>
- import('@backstage/plugin-graphiql').then(({ Router }) => ),
-});
-
-export const graphiqlPlugin = createPlugin({
- id: 'graphiql',
- extensions: [GraphiqlPage],
-});
diff --git a/plugins/graphiql/alpha-api-report.md b/plugins/graphiql/alpha-api-report.md
new file mode 100644
index 0000000000..31bad223b1
--- /dev/null
+++ b/plugins/graphiql/alpha-api-report.md
@@ -0,0 +1,33 @@
+## API Report File for "@backstage/plugin-graphiql"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { BackstagePlugin } from '@backstage/frontend-plugin-api';
+import { Extension } from '@backstage/frontend-plugin-api';
+import { GraphQLEndpoint } from '@backstage/plugin-graphiql';
+import { PortableSchema } from '@backstage/frontend-plugin-api';
+
+// @alpha (undocumented)
+export function createEndpointExtension(options: {
+ id: string;
+ configSchema?: PortableSchema;
+ factory: (options: { config: TConfig }) => {
+ endpoint: GraphQLEndpoint;
+ };
+}): Extension;
+
+// @alpha (undocumented)
+const _default: BackstagePlugin;
+export default _default;
+
+// @alpha (undocumented)
+export const graphiqlBrowseApi: Extension<{}>;
+
+// @alpha (undocumented)
+export const GraphiqlPage: Extension<{
+ path: string;
+}>;
+
+// (No @packageDocumentation comment for this package)
+```
diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json
index e519a34819..da12ebe67d 100644
--- a/plugins/graphiql/package.json
+++ b/plugins/graphiql/package.json
@@ -3,9 +3,7 @@
"description": "Backstage plugin for browsing GraphQL APIs",
"version": "0.2.54-next.2",
"publishConfig": {
- "access": "public",
- "main": "dist/index.esm.js",
- "types": "dist/index.d.ts"
+ "access": "public"
},
"backstage": {
"role": "frontend-plugin"
@@ -19,6 +17,21 @@
"keywords": [
"backstage"
],
+ "exports": {
+ ".": "./src/index.ts",
+ "./alpha": "./src/alpha.tsx",
+ "./package.json": "./package.json"
+ },
+ "typesVersions": {
+ "*": {
+ "alpha": [
+ "src/alpha.tsx"
+ ],
+ "package.json": [
+ "package.json"
+ ]
+ }
+ },
"license": "Apache-2.0",
"main": "src/index.ts",
"types": "src/index.ts",
@@ -35,6 +48,7 @@
"dependencies": {
"@backstage/core-components": "workspace:^",
"@backstage/core-plugin-api": "workspace:^",
+ "@backstage/frontend-plugin-api": "workspace:^",
"@backstage/theme": "workspace:^",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx
new file mode 100644
index 0000000000..ded517e3c7
--- /dev/null
+++ b/plugins/graphiql/src/alpha.tsx
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2023 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import {
+ createApiExtension,
+ createExtension,
+ createExtensionDataRef,
+ createPageExtension,
+ createPlugin,
+ createSchemaFromZod,
+ PortableSchema,
+} from '@backstage/frontend-plugin-api';
+import {
+ graphQlBrowseApiRef,
+ GraphQLEndpoints,
+ GraphQLEndpoint,
+} from '@backstage/plugin-graphiql';
+import { createApiFactory } from '@backstage/core-plugin-api';
+
+/** @alpha */
+export const GraphiqlPage = createPageExtension({
+ id: 'plugin.graphiql.page',
+ defaultPath: '/graphiql',
+ component: () => import('./components').then(m => ),
+});
+
+/** @internal */
+const endpointDataRef = createExtensionDataRef(
+ 'plugin.graphiql.endpoint',
+);
+
+/** @alpha */
+export const graphiqlBrowseApi = createApiExtension({
+ api: graphQlBrowseApiRef, // apis.plugin.graphiql.browse
+ inputs: {
+ endpoints: {
+ extensionData: {
+ endpoint: endpointDataRef,
+ },
+ },
+ },
+ factory({ inputs }) {
+ return createApiFactory(
+ graphQlBrowseApiRef,
+ GraphQLEndpoints.from(inputs.endpoints.map(i => i.endpoint)),
+ );
+ },
+});
+
+/** @alpha */
+export function createEndpointExtension(options: {
+ id: string;
+ configSchema?: PortableSchema;
+ factory: (options: { config: TConfig }) => { endpoint: GraphQLEndpoint };
+}) {
+ return createExtension({
+ id: `apis.plugin.graphiql.browse.${options.id}`,
+ at: 'apis.plugin.graphiql.browse/endpoints',
+ configSchema: options.configSchema,
+ disabled: true,
+ output: {
+ endpoint: endpointDataRef,
+ },
+ factory({ bind, config }) {
+ bind({
+ endpoint: options.factory({ config }).endpoint,
+ });
+ },
+ });
+}
+
+/** @alpha */
+const gitlabGraphiQLBrowseExtension = createEndpointExtension({
+ id: 'gitlab',
+ configSchema: createSchemaFromZod(z =>
+ z
+ .object({
+ id: z.string().default('gitlab'),
+ title: z.string().default('GitLab'),
+ url: z.string().default('https://gitlab.com/api/graphql'),
+ })
+ .default({}),
+ ),
+ factory: ({ config }) => ({ endpoint: GraphQLEndpoints.create(config) }),
+});
+
+/** @alpha */
+export default createPlugin({
+ id: 'graphiql',
+ extensions: [GraphiqlPage, graphiqlBrowseApi, gitlabGraphiQLBrowseExtension],
+});
diff --git a/yarn.lock b/yarn.lock
index 4677a6ee5b..7075f315dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7201,6 +7201,7 @@ __metadata:
"@backstage/core-components": "workspace:^"
"@backstage/core-plugin-api": "workspace:^"
"@backstage/dev-utils": "workspace:^"
+ "@backstage/frontend-plugin-api": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/theme": "workspace:^"
"@material-ui/core": ^4.12.2