@backstage/plugin-devtools 0.0.0-nightly-20230509022028

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # @backstage/plugin-devtools
2
+
3
+ ## 0.0.0-nightly-20230509022028
4
+
5
+ ### Minor Changes
6
+
7
+ - 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details!
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @backstage/plugin-devtools-common@0.0.0-nightly-20230509022028
13
+ - @backstage/core-components@0.0.0-nightly-20230509022028
14
+ - @backstage/core-plugin-api@1.5.1
15
+ - @backstage/plugin-permission-react@0.4.12
16
+ - @backstage/errors@1.1.5
17
+ - @backstage/theme@0.2.19
18
+ - @backstage/types@1.0.2
package/README.md ADDED
@@ -0,0 +1,375 @@
1
+ # DevTools
2
+
3
+ Welcome to the DevTools plugin! This plugin helps elevate useful information about a Backstage instance through the frontend, which can be helpful for an integrator for troubleshooting, reviewing, and understanding their installation.
4
+
5
+ ## Features
6
+
7
+ The DevTools plugin comes with two tabs out of the box.
8
+
9
+ ### Info
10
+
11
+ Lists helpful information about your current running Backstage instance such as: OS, NodeJS version, Backstage version, and package versions.
12
+
13
+ ![Example of Info tab](./docs/devtools-info-tab.png)
14
+
15
+ ### Config
16
+
17
+ Lists the configuration being used by your current running Backstage instance.
18
+
19
+ ![Example of Config tab](./docs/devtools-config-tab.png)
20
+
21
+ ## Optional Features
22
+
23
+ The DevTools plugin can be setup with other tabs with additional helpful features.
24
+
25
+ ### External Dependencies
26
+
27
+ Lists the status of configured External Dependencies based on your current running Backstage instance's ability to reach them.
28
+
29
+ ![Example of external dependencies tab](./docs/devtools-external-dependencies.png)
30
+
31
+ ## Setup
32
+
33
+ The following sections will help you get the DevTools plugin setup and running.
34
+
35
+ ### Backend
36
+
37
+ You need to setup the [DevTools backend plugin](../devtools-backend/README.md) before you move forward with any of the following steps if you haven't already.
38
+
39
+ ### Frontend
40
+
41
+ To setup the DevTools frontend you'll need to do the following steps:
42
+
43
+ 1. First we need to add the `@backstage/plugin-devtools` package to your frontend app:
44
+
45
+ ```sh
46
+ # From your Backstage root directory
47
+ yarn add --cwd packages/app @backstage/plugin-devtools
48
+ ```
49
+
50
+ 2. Now open the `packages/app/src/App.tsx` file
51
+ 3. Then after all the import statements add the following line:
52
+
53
+ ```ts
54
+ import { DevToolsPage } from '@backstage/plugin-devtools';
55
+ ```
56
+
57
+ 4. In this same file just before the closing `</ FlatRoutes>`, this will be near the bottom of the file, add this line:
58
+
59
+ ```ts
60
+ <Route path="/devtools" element={<DevToolsPage />} />
61
+ ```
62
+
63
+ 5. Next open the `packages/app/src/components/Root/Root.tsx` file
64
+ 6. We want to add this icon import after all the existing import statements:
65
+
66
+ ```ts
67
+ import BuildIcon from '@material-ui/icons/Build';
68
+ ```
69
+
70
+ 7. Then add this line just after the `<SidebarSettings />` line:
71
+
72
+ ```ts
73
+ <SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
74
+ ```
75
+
76
+ 8. Now run `yarn dev` from the root of your project and you should see the DevTools option show up just below Settings in your sidebar and clicking on it will get you to the [Info tab](#info)
77
+
78
+ ## Customizing
79
+
80
+ The DevTools plugin has been designed so that you can customize the tabs to suite your needs. You may only want some or none of the out of the box tabs or you may want to add your own. The following sections explains how to do that (assuming you've already done the [setup steps](#setup)). As part of this example we'll also be showing how you can add the optional [External Dependencies](#external-dependencies) tab.
81
+
82
+ 1. In the `packages/app/src/components` folder create a new sub-folder called `devtools`
83
+ 2. Then in this new `devtools` folder add a file called `CustomDevToolsPage.tsx`
84
+ 3. In the `CustomDevToolsPage.tsx` file add the following content:
85
+
86
+ ```tsx
87
+ import {
88
+ ConfigContent,
89
+ ExternalDependenciesContent,
90
+ InfoContent,
91
+ } from '@backstage/plugin-devtools';
92
+ import { DevToolsLayout } from '@backstage/plugin-devtools';
93
+ import React from 'react';
94
+
95
+ export const DevToolsPage = () => {
96
+ return (
97
+ <DevToolsLayout>
98
+ <DevToolsLayout.Route path="info" title="Info">
99
+ <InfoContent />
100
+ </DevToolsLayout.Route>
101
+ <DevToolsLayout.Route path="config" title="Config">
102
+ <ConfigContent />
103
+ </DevToolsLayout.Route>
104
+ <DevToolsLayout.Route
105
+ path="external-dependencies"
106
+ title="External Dependencies"
107
+ >
108
+ <ExternalDependenciesContent />
109
+ </DevToolsLayout.Route>
110
+ </DevToolsLayout>
111
+ );
112
+ };
113
+
114
+ export const customDevToolsPage = <DevToolsPage />;
115
+ ```
116
+
117
+ 4. Now open the `packages/app/src/App.tsx` file and add the following import after all the existing import statements:
118
+
119
+ ```ts
120
+ import { customDevToolsPage } from './components/devtools/CustomDevToolsPage';
121
+ ```
122
+
123
+ 5. Then we need to adjust our route as follows
124
+
125
+ ```diff
126
+ - <Route path="/devtools" element={<DevToolsPage />} />
127
+ + <Route path="/devtools" element={<DevToolsPage />} >
128
+ + {customDevToolsPage}
129
+ + </Route>
130
+ ```
131
+
132
+ 6. Now run `yarn dev` from the root of your project. When you go to the DevTools you'll now see you have a third tab for [External Dependencies](#external-dependencies)
133
+
134
+ With this setup you can add or remove the tabs as you'd like or add your own simply by editing your `CustomDevToolsPage.tsx` file
135
+
136
+ ## Permissions
137
+
138
+ The DevTools plugin supports the [permissions framework](https://backstage.io/docs/permissions/overview), the following sections outline how you can use them with the assumption that you have the permissions framework setup and working.
139
+
140
+ **Note:** These sections are intended as guidance and are completely optional. The DevTools plugin will work with the permission framework off or on without any specific policy setup.
141
+
142
+ ### Secure Sidebar Option
143
+
144
+ To use the permission framework to secure the DevTools sidebar option you'll want to do the following:
145
+
146
+ 1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app:
147
+
148
+ ```sh
149
+ # From your Backstage root directory
150
+ yarn add --cwd packages/app @backstage/plugin-devtools
151
+ ```
152
+
153
+ 2. Then open the `packages/app/src/components/Root/Root.tsx` file
154
+ 3. The add these imports after all the existing import statements:
155
+
156
+ ```ts
157
+ import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common';
158
+ import { RequirePermission } from '@backstage/plugin-permission-react';
159
+ ```
160
+
161
+ 4. Then make the following change:
162
+
163
+ ```diff
164
+ - <SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
165
+ + <RequirePermission
166
+ + permission={devToolsAdministerPermission}
167
+ + errorPage={<></>}>
168
+ + <SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
169
+ + </RequirePermission>
170
+ ```
171
+
172
+ ### Secure the DevTools Route
173
+
174
+ To use the permission framework to secure the DevTools route you'll want to do the following:
175
+
176
+ 1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app (skip this step if you've already done this):
177
+
178
+ ```sh
179
+ # From your Backstage root directory
180
+ yarn add --cwd packages/app @backstage/plugin-devtools-common
181
+ ```
182
+
183
+ 2. Then open the `packages/app/src/App.tsx` file
184
+ 3. The add this import after all the existing import statements:
185
+
186
+ ```ts
187
+ import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common';
188
+ ```
189
+
190
+ 4. Then make the following change:
191
+
192
+ ```diff
193
+ - <Route path="/devtools" element={<DevToolsPage />} />
194
+ + <Route path="/devtools"
195
+ + element={
196
+ + <RequirePermission permission={devToolsAdministerPermission}>
197
+ + <DevToolsPage />
198
+ + </RequirePermission>
199
+ + }
200
+ + />
201
+ ```
202
+
203
+ Note: if you are using a `customDevToolsPage` as per the [Customizing](#customizing) documentation the changes for Step 4 will be:
204
+
205
+ ```diff
206
+ - <Route path="/devtools" element={<DevToolsPage />} />
207
+ + <Route path="/devtools"
208
+ + element={
209
+ + <RequirePermission permission={devToolsAdministerPermission}>
210
+ + <DevToolsPage />
211
+ + </RequirePermission>
212
+ + }
213
+ + >
214
+ + {customDevToolsPage}
215
+ + </Route>
216
+ ```
217
+
218
+ ### Permission Policy
219
+
220
+ Here is an example permission policy that you might use to secure the DevTools plugin:
221
+
222
+ ```ts
223
+ // packages/backend/src/plugins/permission.ts
224
+
225
+ class TestPermissionPolicy implements PermissionPolicy {
226
+ async handle(request: PolicyQuery): Promise<PolicyDecision> {
227
+ if (isPermission(request.permission, devToolsAdministerPermission)) {
228
+ if (
229
+ user?.identity.ownershipEntityRefs.includes(
230
+ 'group:default/backstage-admins',
231
+ )
232
+ ) {
233
+ return { result: AuthorizeResult.ALLOW };
234
+ }
235
+ return { result: AuthorizeResult.DENY };
236
+ }
237
+
238
+ if (isPermission(request.permission, devToolsInfoReadPermission)) {
239
+ if (
240
+ user?.identity.ownershipEntityRefs.includes(
241
+ 'group:default/backstage-admins',
242
+ )
243
+ ) {
244
+ return { result: AuthorizeResult.ALLOW };
245
+ }
246
+ return { result: AuthorizeResult.DENY };
247
+ }
248
+
249
+ if (isPermission(request.permission, devToolsConfigReadPermission)) {
250
+ if (
251
+ user?.identity.ownershipEntityRefs.includes(
252
+ 'group:default/backstage-admins',
253
+ )
254
+ ) {
255
+ return { result: AuthorizeResult.ALLOW };
256
+ }
257
+ return { result: AuthorizeResult.DENY };
258
+ }
259
+
260
+ if (
261
+ isPermission(
262
+ request.permission,
263
+ devToolsExternalDependenciesReadPermission,
264
+ )
265
+ ) {
266
+ if (
267
+ user?.identity.ownershipEntityRefs.includes(
268
+ 'group:default/backstage-admins',
269
+ )
270
+ ) {
271
+ return { result: AuthorizeResult.ALLOW };
272
+ }
273
+ return { result: AuthorizeResult.DENY };
274
+ }
275
+
276
+ return { result: AuthorizeResult.ALLOW };
277
+ }
278
+ }
279
+ ```
280
+
281
+ To use this policy you'll need to make sure to add the `@backstage/plugin-devtools-common` package to your backend you can do that by running this command:
282
+
283
+ ```sh
284
+ # From your Backstage root directory
285
+ yarn add --cwd packages/backend @backstage/plugin-devtools-common
286
+ ```
287
+
288
+ You'll also need to add these imports:
289
+
290
+ ```ts
291
+ import {
292
+ devToolsAdministerPermission,
293
+ devToolsConfigReadPermission,
294
+ devToolsExternalDependenciesReadPermission,
295
+ devToolsInfoReadPermission,
296
+ } from '@backstage/plugin-devtools-common';
297
+ ```
298
+
299
+ **Note:** The group "group:default/backstage-admins" is simply an example and does not exist. You can point this to any group you have in your catalog instead.
300
+
301
+ ### Customizing with Permissions
302
+
303
+ If you followed the [Customizing](#customizing) documentation and want to use permission there this is what your `CustomDevToolsPage.tsx` would look like:
304
+
305
+ ```tsx
306
+ import {
307
+ ConfigContent,
308
+ ExternalDependenciesContent,
309
+ InfoContent,
310
+ } from '@backstage/plugin-devtools';
311
+ import { DevToolsLayout } from '@backstage/plugin-devtools';
312
+ import {
313
+ devToolsConfigReadPermission,
314
+ devToolsExternalDependenciesReadPermission,
315
+ devToolsInfoReadPermission,
316
+ } from '@backstage/plugin-devtools-common';
317
+ import { RequirePermission } from '@backstage/plugin-permission-react';
318
+ import React from 'react';
319
+
320
+ const DevToolsPage = () => {
321
+ return (
322
+ <DevToolsLayout>
323
+ <DevToolsLayout.Route path="info" title="Info">
324
+ <RequirePermission permission={devToolsInfoReadPermission}>
325
+ <InfoContent />
326
+ </RequirePermission>
327
+ </DevToolsLayout.Route>
328
+ <DevToolsLayout.Route path="config" title="Config">
329
+ <RequirePermission permission={devToolsConfigReadPermission}>
330
+ <ConfigContent />
331
+ </RequirePermission>
332
+ </DevToolsLayout.Route>
333
+ <DevToolsLayout.Route
334
+ path="external-dependencies"
335
+ title="External Dependencies"
336
+ >
337
+ <RequirePermission
338
+ permission={devToolsExternalDependenciesReadPermission}
339
+ >
340
+ <ExternalDependenciesContent />
341
+ </RequirePermission>
342
+ </DevToolsLayout.Route>
343
+ </DevToolsLayout>
344
+ );
345
+ };
346
+
347
+ export const customDevToolsPage = <DevToolsPage />;
348
+ ```
349
+
350
+ ## Configuration
351
+
352
+ The following sections outline the configuration for the DevTools plugin
353
+
354
+ ### External Dependencies Configuration
355
+
356
+ If you decide to use the External Dependencies tab then you'll need to setup the configuration for it in your `app-config.yaml`, if there is no config setup then the tab will be empty. Here's an example:
357
+
358
+ ```yaml
359
+ devTools:
360
+ externalDependencies:
361
+ endpoints:
362
+ - name: 'Google'
363
+ type: 'fetch'
364
+ target: 'https://google.ca'
365
+ - name: 'Google Public DNS'
366
+ type: 'ping'
367
+ target: '8.8.8.8'
368
+ ```
369
+
370
+ Configuration details:
371
+
372
+ - `endpoints` is an array
373
+ - `name` is the friendly name for your endpoint
374
+ - `type` can be either `ping` or `fetch` and will perform the respective action on the `target`
375
+ - `target` is either a URL or server that you want to trigger a `type` action on
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { useOutlet } from 'react-router-dom';
3
+ import { devToolsInfoReadPermission, devToolsConfigReadPermission } from '@backstage/plugin-devtools-common';
4
+ import { DevToolsLayout, InfoContent, ConfigContent } from '../index.esm.js';
5
+ import { RequirePermission } from '@backstage/plugin-permission-react';
6
+ import '@backstage/core-plugin-api';
7
+ import '@backstage/errors';
8
+ import '@backstage/core-components';
9
+ import '@material-ui/core';
10
+ import '@material-ui/lab';
11
+ import 'react-json-view';
12
+ import 'react-use/lib/useAsync';
13
+ import '@material-ui/icons/Description';
14
+ import '@material-ui/icons/DeveloperBoard';
15
+ import '@material-ui/icons/FileCopy';
16
+
17
+ const DefaultDevToolsPage = () => /* @__PURE__ */ React.createElement(DevToolsLayout, null, /* @__PURE__ */ React.createElement(DevToolsLayout.Route, { path: "info", title: "Info" }, /* @__PURE__ */ React.createElement(RequirePermission, { permission: devToolsInfoReadPermission }, /* @__PURE__ */ React.createElement(InfoContent, null))), /* @__PURE__ */ React.createElement(DevToolsLayout.Route, { path: "config", title: "Config" }, /* @__PURE__ */ React.createElement(RequirePermission, { permission: devToolsConfigReadPermission }, /* @__PURE__ */ React.createElement(ConfigContent, null))));
18
+
19
+ const DevToolsPage = () => {
20
+ const outlet = useOutlet();
21
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, outlet || /* @__PURE__ */ React.createElement(DefaultDevToolsPage, null));
22
+ };
23
+
24
+ export { DevToolsPage };
25
+ //# sourceMappingURL=index-3bbd2c6b.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-3bbd2c6b.esm.js","sources":["../../src/components/DefaultDevToolsPage/DefaultDevToolsPage.tsx","../../src/components/DevToolsPage/DevToolsPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n devToolsConfigReadPermission,\n devToolsInfoReadPermission,\n} from '@backstage/plugin-devtools-common';\n\nimport { ConfigContent } from '../Content/ConfigContent';\nimport { DevToolsLayout } from '../DevToolsLayout';\nimport { InfoContent } from '../Content/InfoContent';\nimport React from 'react';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\n\n/** @public */\nexport const DefaultDevToolsPage = () => (\n <DevToolsLayout>\n <DevToolsLayout.Route path=\"info\" title=\"Info\">\n <RequirePermission permission={devToolsInfoReadPermission}>\n <InfoContent />\n </RequirePermission>\n </DevToolsLayout.Route>\n <DevToolsLayout.Route path=\"config\" title=\"Config\">\n <RequirePermission permission={devToolsConfigReadPermission}>\n <ConfigContent />\n </RequirePermission>\n </DevToolsLayout.Route>\n </DevToolsLayout>\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport { DefaultDevToolsPage } from '../DefaultDevToolsPage';\n\nexport const DevToolsPage = () => {\n const outlet = useOutlet();\n\n return <>{outlet || <DefaultDevToolsPage />}</>;\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA4BO,MAAM,sBAAsB,sBACjC,KAAA,CAAA,aAAA,CAAC,cACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAe,KAAf,EAAA,EAAqB,IAAK,EAAA,MAAA,EAAO,OAAM,MACtC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,iBAAkB,EAAA,EAAA,UAAA,EAAY,8CAC5B,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAY,CACf,CACF,mBACC,KAAA,CAAA,aAAA,CAAA,cAAA,CAAe,KAAf,EAAA,EAAqB,MAAK,QAAS,EAAA,KAAA,EAAM,QACxC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,qBAAkB,UAAY,EAAA,4BAAA,EAAA,sCAC5B,aAAc,EAAA,IAAA,CACjB,CACF,CACF,CAAA;;ACpBK,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AAEzB,EAAA,uBAAU,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,oBAAW,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA,IAAoB,CAAG,CAAA,CAAA;AAC9C;;;;"}
@@ -0,0 +1,53 @@
1
+ /// <reference types="react" />
2
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
+ import { TabProps } from '@material-ui/core';
4
+ import React from 'react';
5
+
6
+ /** @public */
7
+ declare const devToolsPlugin: _backstage_core_plugin_api.BackstagePlugin<{
8
+ root: _backstage_core_plugin_api.RouteRef<undefined>;
9
+ }, {}, {}>;
10
+ /** @public */
11
+ declare const DevToolsPage: () => JSX.Element;
12
+
13
+ /** @public */
14
+ declare const ConfigContent: () => JSX.Element;
15
+
16
+ /** @public */
17
+ declare const InfoContent: () => JSX.Element;
18
+
19
+ /** @public */
20
+ declare const ExternalDependenciesContent: () => JSX.Element;
21
+
22
+ /** @public */
23
+ type SubRoute = {
24
+ path: string;
25
+ title: string;
26
+ children: JSX.Element;
27
+ tabProps?: TabProps<React.ElementType, {
28
+ component?: React.ElementType;
29
+ }>;
30
+ };
31
+ /** @public */
32
+ type DevToolsLayoutProps = {
33
+ children?: React.ReactNode;
34
+ };
35
+ /**
36
+ * DevTools is a compound component, which allows you to define a custom layout
37
+ *
38
+ * @example
39
+ * ```jsx
40
+ * <DevToolsLayout>
41
+ * <DevToolsLayout.Route path="/example" title="Example tab">
42
+ * <div>This is rendered under /example/anything-here route</div>
43
+ * </DevToolsLayout.Route>
44
+ * </DevToolsLayout>
45
+ * ```
46
+ * @public
47
+ */
48
+ declare const DevToolsLayout: {
49
+ ({ children }: DevToolsLayoutProps): JSX.Element;
50
+ Route: (props: SubRoute) => null;
51
+ };
52
+
53
+ export { ConfigContent, DevToolsLayout, DevToolsLayoutProps, DevToolsPage, ExternalDependenciesContent, InfoContent, SubRoute, devToolsPlugin };
@@ -0,0 +1,345 @@
1
+ import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, createRoutableExtension, useApi, attachComponentData, useElementFilter } from '@backstage/core-plugin-api';
2
+ import { ResponseError } from '@backstage/errors';
3
+ import { Progress, WarningPanel, Table, StatusWarning, StatusError, StatusOK, Page, Header, RoutedTabs } from '@backstage/core-components';
4
+ import { makeStyles, createStyles, useTheme, Box, Paper, Typography, SvgIcon, List, ListItem, ListItemAvatar, Avatar, ListItemText, Divider, Grid } from '@material-ui/core';
5
+ import { Alert } from '@material-ui/lab';
6
+ import React from 'react';
7
+ import ReactJson from 'react-json-view';
8
+ import useAsync from 'react-use/lib/useAsync';
9
+ import DescriptionIcon from '@material-ui/icons/Description';
10
+ import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard';
11
+ import FileCopyIcon from '@material-ui/icons/FileCopy';
12
+
13
+ const devToolsApiRef = createApiRef({
14
+ id: "plugin.devtools.service"
15
+ });
16
+
17
+ class DevToolsClient {
18
+ constructor(options) {
19
+ this.discoveryApi = options.discoveryApi;
20
+ this.identityApi = options.identityApi;
21
+ }
22
+ async getConfig() {
23
+ const urlSegment = "config";
24
+ const configInfo = await this.get(urlSegment);
25
+ return configInfo;
26
+ }
27
+ async getExternalDependencies() {
28
+ const urlSegment = "external-dependencies";
29
+ const externalDependencies = await this.get(urlSegment);
30
+ return externalDependencies;
31
+ }
32
+ async getInfo() {
33
+ const urlSegment = "info";
34
+ const info = await this.get(urlSegment);
35
+ return info;
36
+ }
37
+ async get(path) {
38
+ const baseUrl = `${await this.discoveryApi.getBaseUrl("devtools")}/`;
39
+ const url = new URL(path, baseUrl);
40
+ const { token } = await this.identityApi.getCredentials();
41
+ const response = await fetch(url.toString(), {
42
+ headers: token ? { Authorization: `Bearer ${token}` } : {}
43
+ });
44
+ if (!response.ok) {
45
+ throw await ResponseError.fromResponse(response);
46
+ }
47
+ return response.json();
48
+ }
49
+ }
50
+
51
+ const rootRouteRef = createRouteRef({
52
+ id: "devtools"
53
+ });
54
+
55
+ const devToolsPlugin = createPlugin({
56
+ id: "devtools",
57
+ apis: [
58
+ createApiFactory({
59
+ api: devToolsApiRef,
60
+ deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
61
+ factory: ({ discoveryApi, identityApi }) => new DevToolsClient({ discoveryApi, identityApi })
62
+ })
63
+ ],
64
+ routes: {
65
+ root: rootRouteRef
66
+ }
67
+ });
68
+ const DevToolsPage = devToolsPlugin.provide(
69
+ createRoutableExtension({
70
+ name: "DevToolsPage",
71
+ component: () => import('./esm/index-3bbd2c6b.esm.js').then((m) => m.DevToolsPage),
72
+ mountPoint: rootRouteRef
73
+ })
74
+ );
75
+
76
+ function useConfig() {
77
+ const api = useApi(devToolsApiRef);
78
+ const { value, loading, error } = useAsync(() => {
79
+ return api.getConfig();
80
+ }, [api]);
81
+ return {
82
+ configInfo: value,
83
+ loading,
84
+ error
85
+ };
86
+ }
87
+
88
+ function useExternalDependencies() {
89
+ const api = useApi(devToolsApiRef);
90
+ const { value, loading, error } = useAsync(() => {
91
+ return api.getExternalDependencies();
92
+ }, [api]);
93
+ return {
94
+ externalDependencies: value,
95
+ loading,
96
+ error
97
+ };
98
+ }
99
+
100
+ function useInfo() {
101
+ const api = useApi(devToolsApiRef);
102
+ const { value, loading, error } = useAsync(() => {
103
+ return api.getInfo();
104
+ }, [api]);
105
+ return {
106
+ about: value,
107
+ loading,
108
+ error
109
+ };
110
+ }
111
+
112
+ const useStyles$2 = makeStyles(
113
+ (theme) => createStyles({
114
+ warningStyle: {
115
+ paddingBottom: theme.spacing(2)
116
+ },
117
+ paperStyle: {
118
+ padding: theme.spacing(2)
119
+ }
120
+ })
121
+ );
122
+ const WarningContent = ({ error }) => {
123
+ if (!error.messages) {
124
+ return /* @__PURE__ */ React.createElement(Typography, null, error.message);
125
+ }
126
+ const messages = error.messages;
127
+ return /* @__PURE__ */ React.createElement(Box, null, messages.map((message) => /* @__PURE__ */ React.createElement(Typography, null, message)));
128
+ };
129
+ const ConfigContent = () => {
130
+ const classes = useStyles$2();
131
+ const theme = useTheme();
132
+ const { configInfo, loading, error } = useConfig();
133
+ if (loading) {
134
+ return /* @__PURE__ */ React.createElement(Progress, null);
135
+ } else if (error) {
136
+ return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
137
+ }
138
+ if (!configInfo) {
139
+ return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "Unable to load config data");
140
+ }
141
+ return /* @__PURE__ */ React.createElement(Box, null, configInfo && configInfo.error && /* @__PURE__ */ React.createElement(Box, { className: classes.warningStyle }, /* @__PURE__ */ React.createElement(WarningPanel, { title: "Config validation failed" }, /* @__PURE__ */ React.createElement(WarningContent, { error: configInfo.error }))), /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(
142
+ ReactJson,
143
+ {
144
+ src: configInfo.config,
145
+ name: "config",
146
+ enableClipboard: false,
147
+ theme: theme.palette.type === "dark" ? "monokai" : "rjv-default"
148
+ }
149
+ )));
150
+ };
151
+
152
+ const columns$1 = [
153
+ {
154
+ title: "Name",
155
+ width: "auto",
156
+ field: "name",
157
+ defaultSort: "asc"
158
+ },
159
+ {
160
+ title: "Versions",
161
+ width: "auto",
162
+ field: "versions"
163
+ }
164
+ ];
165
+ const InfoDependenciesTable = ({
166
+ infoDependencies
167
+ }) => {
168
+ return /* @__PURE__ */ React.createElement(
169
+ Table,
170
+ {
171
+ title: "Package Dependencies",
172
+ options: {
173
+ paging: true,
174
+ pageSize: 15,
175
+ pageSizeOptions: [15, 30, 100],
176
+ loadingType: "linear",
177
+ padding: "dense"
178
+ },
179
+ columns: columns$1,
180
+ data: infoDependencies || []
181
+ }
182
+ );
183
+ };
184
+
185
+ const BackstageLogoIcon = (props) => /* @__PURE__ */ React.createElement(SvgIcon, { ...props, viewBox: "0 0 337.46 428.5" }, /* @__PURE__ */ React.createElement("path", { d: "M303 166.05a80.69 80.69 0 0013.45-10.37c.79-.77 1.55-1.53 2.3-2.3a83.12 83.12 0 007.93-9.38 63.69 63.69 0 006.32-10.77 48.58 48.58 0 004.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56 0 78.3 115.23 0 190.25l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.69 19.16-18.36 25.52-42.12 13.7-61.87a49.22 49.22 0 00-6.8-8.87 89.17 89.17 0 0019.32 2.15h.15a85.08 85.08 0 0031-5.79 80.88 80.88 0 0012.85-6.45zm-100.55 59.81c-19.32 18.51-50.4 21.23-75.7 5.9l-75.14-45.61 67.45-64.64 76.41 46.38c27.53 16.69 26.02 39.72 6.98 57.97zm8.93-82.22l-70.65-42.89L205.14 39l69.37 42.1c25.94 15.72 29.31 37 10.55 55a60.69 60.69 0 01-73.68 7.54zm29.86 190c-19.57 18.75-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 282.52v24.67l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.75-46.17 29.08-74.88 29.08a123.81 123.81 0 01-64.1-18.19L0 243.53v24.68l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.5v-1.78a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.76-46.17 29.09-74.88 29.09a123.81 123.81 0 01-64.1-18.19L0 204.55v24.68l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.68 12.88-12.35 20-27.13 19.68-41.5v-1.82a86.09 86.09 0 01-11.22 13.16zm83.7 25.74a94.15 94.15 0 01-60.2 25.86V334a81.6 81.6 0 0051.74-22.37c14-13.38 21.14-28.11 21-42.64v-2.19a94.92 94.92 0 01-12.54 14.65zm-83.7 91.21c-19.57 18.76-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 321.5v24.68l108.6 65.9a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.8 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a86.29 86.29 0 01-11.22 13.13zM327 162.45c-.68.69-1.35 1.38-2.05 2.06a94.37 94.37 0 01-10.64 8.65 91.35 91.35 0 01-11.6 7 94.53 94.53 0 01-26.24 8.71 97.69 97.69 0 01-14.16 1.57c.5 1.61.9 3.25 1.25 4.9a53.27 53.27 0 011.14 12V217h.05a84.41 84.41 0 0025.35-5.55 81 81 0 0026.39-16.82c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.32-10.74 48.55 48.55 0 004.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08 1.54-2.25 3.09a96.73 96.73 0 01-8.26 9.36zm0 77.92c-.69.7-1.31 1.41-2 2.1a94.2 94.2 0 01-60.2 25.86V295a81.6 81.6 0 0051.74-22.37 73.51 73.51 0 0016.46-22.5 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74 1.07-1.46 2.15-2.27 3.21a95.68 95.68 0 01-8.24 9.37zm0-39c-.69.7-1.31 1.41-2 2.1a93.18 93.18 0 01-10.63 8.65 91.63 91.63 0 01-11.63 7 95.47 95.47 0 01-37.94 10.18V256a81.65 81.65 0 0051.74-22.37c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.27-10.76 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74 1.08-1.46 2.16-2.27 3.22a95.68 95.68 0 01-8.24 9.37z" }));
186
+
187
+ const useStyles$1 = makeStyles(
188
+ (theme) => createStyles({
189
+ paperStyle: {
190
+ marginBottom: theme.spacing(2)
191
+ },
192
+ flexContainer: {
193
+ display: "flex",
194
+ flexDirection: "row",
195
+ padding: 0
196
+ },
197
+ copyButton: {
198
+ float: "left",
199
+ margin: theme.spacing(2)
200
+ }
201
+ })
202
+ );
203
+ const copyToClipboard = ({ about }) => {
204
+ if (about) {
205
+ let formatted = `OS: ${about.operatingSystem}
206
+ node: ${about.nodeJsVersion}
207
+ backstage: ${about.backstageVersion}
208
+ Dependencies:
209
+ `;
210
+ const deps = about.dependencies;
211
+ for (const key in deps) {
212
+ if (Object.prototype.hasOwnProperty.call(deps, key)) {
213
+ formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}
214
+ `;
215
+ }
216
+ }
217
+ window.navigator.clipboard.writeText(formatted);
218
+ }
219
+ };
220
+ const InfoContent = () => {
221
+ const classes = useStyles$1();
222
+ const { about, loading, error } = useInfo();
223
+ if (loading) {
224
+ return /* @__PURE__ */ React.createElement(Progress, null);
225
+ } else if (error) {
226
+ return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
227
+ }
228
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(List, { className: classes.flexContainer }, /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(DeveloperBoardIcon, null))), /* @__PURE__ */ React.createElement(
229
+ ListItemText,
230
+ {
231
+ primary: "Operating System",
232
+ secondary: about == null ? void 0 : about.operatingSystem
233
+ }
234
+ )), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(DescriptionIcon, null))), /* @__PURE__ */ React.createElement(
235
+ ListItemText,
236
+ {
237
+ primary: "NodeJS Version",
238
+ secondary: about == null ? void 0 : about.nodeJsVersion
239
+ }
240
+ )), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(BackstageLogoIcon, null))), /* @__PURE__ */ React.createElement(
241
+ ListItemText,
242
+ {
243
+ primary: "Backstage Version",
244
+ secondary: about == null ? void 0 : about.backstageVersion
245
+ }
246
+ )), /* @__PURE__ */ React.createElement(Divider, { orientation: "vertical", variant: "middle", flexItem: true }), /* @__PURE__ */ React.createElement(
247
+ ListItem,
248
+ {
249
+ button: true,
250
+ onClick: () => {
251
+ copyToClipboard({ about });
252
+ },
253
+ className: classes.copyButton
254
+ },
255
+ /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(FileCopyIcon, null))),
256
+ /* @__PURE__ */ React.createElement(ListItemText, { primary: "Copy Info to Clipboard" })
257
+ ))), /* @__PURE__ */ React.createElement(InfoDependenciesTable, { infoDependencies: about == null ? void 0 : about.dependencies }));
258
+ };
259
+
260
+ const useStyles = makeStyles(
261
+ (theme) => createStyles({
262
+ paperStyle: {
263
+ padding: theme.spacing(2)
264
+ }
265
+ })
266
+ );
267
+ const getExternalDependencyStatus = (result) => {
268
+ switch (result == null ? void 0 : result.status) {
269
+ case "Healthy":
270
+ return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusOK, null), " ", result.status);
271
+ case "Unhealthy":
272
+ return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusError, null), " ", `${result.status}`);
273
+ case void 0:
274
+ default:
275
+ return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusWarning, null), " Unknown");
276
+ }
277
+ };
278
+ const columns = [
279
+ {
280
+ title: "Name",
281
+ width: "auto",
282
+ field: "name"
283
+ },
284
+ {
285
+ title: "Target",
286
+ width: "auto",
287
+ field: "target"
288
+ },
289
+ {
290
+ title: "Type",
291
+ width: "auto",
292
+ field: "type"
293
+ },
294
+ {
295
+ title: "Status",
296
+ width: "auto",
297
+ render: (row) => /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "button" }, getExternalDependencyStatus(row))), /* @__PURE__ */ React.createElement(Grid, { item: true }, row.error && /* @__PURE__ */ React.createElement(Typography, null, row.error)))
298
+ }
299
+ ];
300
+ const ExternalDependenciesContent = () => {
301
+ const classes = useStyles();
302
+ const { externalDependencies, loading, error } = useExternalDependencies();
303
+ if (loading) {
304
+ return /* @__PURE__ */ React.createElement(Progress, null);
305
+ } else if (error) {
306
+ return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
307
+ }
308
+ if (!externalDependencies || externalDependencies.length === 0) {
309
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(Typography, null, "No external dependencies found")));
310
+ }
311
+ return /* @__PURE__ */ React.createElement(
312
+ Table,
313
+ {
314
+ title: "Status",
315
+ options: {
316
+ paging: true,
317
+ pageSize: 20,
318
+ pageSizeOptions: [20, 50, 100],
319
+ loadingType: "linear",
320
+ showEmptyDataSourceMessage: !loading
321
+ },
322
+ columns,
323
+ data: externalDependencies || []
324
+ }
325
+ );
326
+ };
327
+
328
+ const dataKey = "plugin.devtools.devtoolsLayoutRoute";
329
+ const Route = () => null;
330
+ attachComponentData(Route, dataKey, true);
331
+ attachComponentData(Route, "core.gatherMountPoints", true);
332
+ const DevToolsLayout = ({ children }) => {
333
+ const routes = useElementFilter(
334
+ children,
335
+ (elements) => elements.selectByComponentData({
336
+ key: dataKey,
337
+ withStrictError: "Child of DevToolsLayout must be an DevToolsLayout.Route"
338
+ }).getElements().map((child) => child.props)
339
+ );
340
+ return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Header, { title: "Backstage DevTools" }), /* @__PURE__ */ React.createElement(RoutedTabs, { routes }));
341
+ };
342
+ DevToolsLayout.Route = Route;
343
+
344
+ export { ConfigContent, DevToolsLayout, DevToolsPage, ExternalDependenciesContent, InfoContent, devToolsPlugin };
345
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/api/DevToolsApi.ts","../src/api/DevToolsClient.ts","../src/routes.ts","../src/plugin.ts","../src/hooks/useConfig.ts","../src/hooks/useExternalDependencies.ts","../src/hooks/useInfo.ts","../src/components/Content/ConfigContent/ConfigContent.tsx","../src/components/Content/InfoContent/InfoDependenciesTable.tsx","../src/components/Content/InfoContent/BackstageLogoIcon.tsx","../src/components/Content/InfoContent/InfoContent.tsx","../src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx","../src/components/DevToolsLayout/DevToolsLayout.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport {\n ConfigInfo,\n DevToolsInfo,\n ExternalDependency,\n} from '@backstage/plugin-devtools-common';\n\nexport const devToolsApiRef = createApiRef<DevToolsApi>({\n id: 'plugin.devtools.service',\n});\n\nexport interface DevToolsApi {\n getConfig(): Promise<ConfigInfo | undefined>;\n getExternalDependencies(): Promise<ExternalDependency[] | undefined>;\n getInfo(): Promise<DevToolsInfo | undefined>;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';\nimport {\n ConfigInfo,\n DevToolsInfo,\n ExternalDependency,\n} from '@backstage/plugin-devtools-common';\nimport { ResponseError } from '@backstage/errors';\nimport { DevToolsApi } from './DevToolsApi';\n\nexport class DevToolsClient implements DevToolsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n public async getConfig(): Promise<ConfigInfo | undefined> {\n const urlSegment = 'config';\n\n const configInfo = await this.get<ConfigInfo | undefined>(urlSegment);\n return configInfo;\n }\n\n public async getExternalDependencies(): Promise<\n ExternalDependency[] | undefined\n > {\n const urlSegment = 'external-dependencies';\n\n const externalDependencies = await this.get<\n ExternalDependency[] | undefined\n >(urlSegment);\n return externalDependencies;\n }\n\n public async getInfo(): Promise<DevToolsInfo | undefined> {\n const urlSegment = 'info';\n\n const info = await this.get<DevToolsInfo | undefined>(urlSegment);\n return info;\n }\n\n private async get<T>(path: string): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('devtools')}/`;\n const url = new URL(path, baseUrl);\n\n const { token } = await this.identityApi.getCredentials();\n const response = await fetch(url.toString(), {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'devtools',\n});\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport { devToolsApiRef, DevToolsClient } from './api';\n\nimport { rootRouteRef } from './routes';\n\n/** @public */\nexport const devToolsPlugin = createPlugin({\n id: 'devtools',\n apis: [\n createApiFactory({\n api: devToolsApiRef,\n deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },\n factory: ({ discoveryApi, identityApi }) =>\n new DevToolsClient({ discoveryApi, identityApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/** @public */\nexport const DevToolsPage = devToolsPlugin.provide(\n createRoutableExtension({\n name: 'DevToolsPage',\n component: () =>\n import('./components/DevToolsPage').then(m => m.DevToolsPage),\n mountPoint: rootRouteRef,\n }),\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { ConfigInfo } from '@backstage/plugin-devtools-common';\n\nexport function useConfig(): {\n configInfo?: ConfigInfo;\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getConfig();\n }, [api]);\n\n return {\n configInfo: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { ExternalDependency } from '@backstage/plugin-devtools-common';\n\nexport function useExternalDependencies(): {\n externalDependencies?: ExternalDependency[];\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getExternalDependencies();\n }, [api]);\n\n return {\n externalDependencies: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { DevToolsInfo } from '@backstage/plugin-devtools-common';\n\nexport function useInfo(): {\n about?: DevToolsInfo;\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getInfo();\n }, [api]);\n\n return {\n about: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Progress, WarningPanel } from '@backstage/core-components';\nimport {\n Box,\n createStyles,\n makeStyles,\n Paper,\n Theme,\n Typography,\n useTheme,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport ReactJson from 'react-json-view';\nimport { useConfig } from '../../../hooks';\nimport { ConfigError } from '@backstage/plugin-devtools-common';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n warningStyle: {\n paddingBottom: theme.spacing(2),\n },\n paperStyle: {\n padding: theme.spacing(2),\n },\n }),\n);\n\nexport const WarningContent = ({ error }: { error: ConfigError }) => {\n if (!error.messages) {\n return <Typography>{error.message}</Typography>;\n }\n\n const messages = error.messages as string[];\n\n return (\n <Box>\n {messages.map(message => (\n <Typography>{message}</Typography>\n ))}\n </Box>\n );\n};\n\n/** @public */\nexport const ConfigContent = () => {\n const classes = useStyles();\n const theme = useTheme();\n const { configInfo, loading, error } = useConfig();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!configInfo) {\n return <Alert severity=\"error\">Unable to load config data</Alert>;\n }\n\n return (\n <Box>\n {configInfo && configInfo.error && (\n <Box className={classes.warningStyle}>\n <WarningPanel title=\"Config validation failed\">\n <WarningContent error={configInfo.error} />\n </WarningPanel>\n </Box>\n )}\n <Paper className={classes.paperStyle}>\n <ReactJson\n src={configInfo.config as object}\n name=\"config\"\n enableClipboard={false}\n theme={theme.palette.type === 'dark' ? 'monokai' : 'rjv-default'}\n />\n </Paper>\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Table, TableColumn } from '@backstage/core-components';\nimport { PackageDependency } from '@backstage/plugin-devtools-common';\n\nimport React from 'react';\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n width: 'auto',\n field: 'name',\n defaultSort: 'asc',\n },\n {\n title: 'Versions',\n width: 'auto',\n field: 'versions',\n },\n];\n\nexport const InfoDependenciesTable = ({\n infoDependencies,\n}: {\n infoDependencies: PackageDependency[] | undefined;\n}) => {\n return (\n <Table\n title=\"Package Dependencies\"\n options={{\n paging: true,\n pageSize: 15,\n pageSizeOptions: [15, 30, 100],\n loadingType: 'linear',\n padding: 'dense',\n }}\n columns={columns}\n data={infoDependencies || []}\n />\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SvgIcon, SvgIconProps } from '@material-ui/core';\n\nimport React from 'react';\n\nexport const BackstageLogoIcon = (props: SvgIconProps) => (\n <SvgIcon {...props} viewBox=\"0 0 337.46 428.5\">\n <path d=\"M303 166.05a80.69 80.69 0 0013.45-10.37c.79-.77 1.55-1.53 2.3-2.3a83.12 83.12 0 007.93-9.38 63.69 63.69 0 006.32-10.77 48.58 48.58 0 004.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56 0 78.3 115.23 0 190.25l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.69 19.16-18.36 25.52-42.12 13.7-61.87a49.22 49.22 0 00-6.8-8.87 89.17 89.17 0 0019.32 2.15h.15a85.08 85.08 0 0031-5.79 80.88 80.88 0 0012.85-6.45zm-100.55 59.81c-19.32 18.51-50.4 21.23-75.7 5.9l-75.14-45.61 67.45-64.64 76.41 46.38c27.53 16.69 26.02 39.72 6.98 57.97zm8.93-82.22l-70.65-42.89L205.14 39l69.37 42.1c25.94 15.72 29.31 37 10.55 55a60.69 60.69 0 01-73.68 7.54zm29.86 190c-19.57 18.75-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 282.52v24.67l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.75-46.17 29.08-74.88 29.08a123.81 123.81 0 01-64.1-18.19L0 243.53v24.68l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.5v-1.78a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.76-46.17 29.09-74.88 29.09a123.81 123.81 0 01-64.1-18.19L0 204.55v24.68l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.68 12.88-12.35 20-27.13 19.68-41.5v-1.82a86.09 86.09 0 01-11.22 13.16zm83.7 25.74a94.15 94.15 0 01-60.2 25.86V334a81.6 81.6 0 0051.74-22.37c14-13.38 21.14-28.11 21-42.64v-2.19a94.92 94.92 0 01-12.54 14.65zm-83.7 91.21c-19.57 18.76-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 321.5v24.68l108.6 65.9a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.8 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a86.29 86.29 0 01-11.22 13.13zM327 162.45c-.68.69-1.35 1.38-2.05 2.06a94.37 94.37 0 01-10.64 8.65 91.35 91.35 0 01-11.6 7 94.53 94.53 0 01-26.24 8.71 97.69 97.69 0 01-14.16 1.57c.5 1.61.9 3.25 1.25 4.9a53.27 53.27 0 011.14 12V217h.05a84.41 84.41 0 0025.35-5.55 81 81 0 0026.39-16.82c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.32-10.74 48.55 48.55 0 004.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08 1.54-2.25 3.09a96.73 96.73 0 01-8.26 9.36zm0 77.92c-.69.7-1.31 1.41-2 2.1a94.2 94.2 0 01-60.2 25.86V295a81.6 81.6 0 0051.74-22.37 73.51 73.51 0 0016.46-22.5 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74 1.07-1.46 2.15-2.27 3.21a95.68 95.68 0 01-8.24 9.37zm0-39c-.69.7-1.31 1.41-2 2.1a93.18 93.18 0 01-10.63 8.65 91.63 91.63 0 01-11.63 7 95.47 95.47 0 01-37.94 10.18V256a81.65 81.65 0 0051.74-22.37c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.27-10.76 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74 1.08-1.46 2.16-2.27 3.22a95.68 95.68 0 01-8.24 9.37z\" />\n </SvgIcon>\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Progress } from '@backstage/core-components';\nimport {\n Avatar,\n Box,\n createStyles,\n Divider,\n List,\n ListItem,\n ListItemAvatar,\n ListItemText,\n makeStyles,\n Paper,\n Theme,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useInfo } from '../../../hooks';\nimport { InfoDependenciesTable } from './InfoDependenciesTable';\nimport DescriptionIcon from '@material-ui/icons/Description';\nimport DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard';\nimport { BackstageLogoIcon } from './BackstageLogoIcon';\nimport FileCopyIcon from '@material-ui/icons/FileCopy';\nimport { DevToolsInfo } from '@backstage/plugin-devtools-common';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n paperStyle: {\n marginBottom: theme.spacing(2),\n },\n flexContainer: {\n display: 'flex',\n flexDirection: 'row',\n padding: 0,\n },\n copyButton: {\n float: 'left',\n margin: theme.spacing(2),\n },\n }),\n);\n\nconst copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => {\n if (about) {\n let formatted = `OS: ${about.operatingSystem}\\nnode: ${about.nodeJsVersion}\\nbackstage: ${about.backstageVersion}\\nDependencies:\\n`;\n const deps = about.dependencies;\n for (const key in deps) {\n if (Object.prototype.hasOwnProperty.call(deps, key)) {\n formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}\\n`;\n }\n }\n window.navigator.clipboard.writeText(formatted);\n }\n};\n\n/** @public */\nexport const InfoContent = () => {\n const classes = useStyles();\n const { about, loading, error } = useInfo();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n return (\n <Box>\n <Paper className={classes.paperStyle}>\n <List className={classes.flexContainer}>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <DeveloperBoardIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"Operating System\"\n secondary={about?.operatingSystem}\n />\n </ListItem>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <DescriptionIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"NodeJS Version\"\n secondary={about?.nodeJsVersion}\n />\n </ListItem>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <BackstageLogoIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"Backstage Version\"\n secondary={about?.backstageVersion}\n />\n </ListItem>\n <Divider orientation=\"vertical\" variant=\"middle\" flexItem />\n <ListItem\n button\n onClick={() => {\n copyToClipboard({ about });\n }}\n className={classes.copyButton}\n >\n <ListItemAvatar>\n <Avatar>\n <FileCopyIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText primary=\"Copy Info to Clipboard\" />\n </ListItem>\n </List>\n </Paper>\n <InfoDependenciesTable infoDependencies={about?.dependencies} />\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Progress,\n StatusError,\n StatusOK,\n StatusWarning,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { ExternalDependency } from '@backstage/plugin-devtools-common';\nimport {\n Box,\n createStyles,\n Grid,\n makeStyles,\n Paper,\n Theme,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useExternalDependencies } from '../../../hooks';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n paperStyle: {\n padding: theme.spacing(2),\n },\n }),\n);\n\nexport const getExternalDependencyStatus = (\n result: Partial<ExternalDependency> | undefined,\n) => {\n switch (result?.status) {\n case 'Healthy':\n return (\n <Typography component=\"span\">\n <StatusOK /> {result.status}\n </Typography>\n );\n case 'Unhealthy':\n return (\n <Typography component=\"span\">\n <StatusError /> {`${result.status}`}\n </Typography>\n );\n case undefined:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n width: 'auto',\n field: 'name',\n },\n {\n title: 'Target',\n width: 'auto',\n field: 'target',\n },\n {\n title: 'Type',\n width: 'auto',\n field: 'type',\n },\n {\n title: 'Status',\n width: 'auto',\n render: (row: Partial<ExternalDependency>) => (\n <Grid container direction=\"column\">\n <Grid item>\n <Typography variant=\"button\">\n {getExternalDependencyStatus(row)}\n </Typography>\n </Grid>\n <Grid item>{row.error && <Typography>{row.error}</Typography>}</Grid>\n </Grid>\n ),\n },\n];\n\n/** @public */\nexport const ExternalDependenciesContent = () => {\n const classes = useStyles();\n const { externalDependencies, loading, error } = useExternalDependencies();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!externalDependencies || externalDependencies.length === 0) {\n return (\n <Box>\n <Paper className={classes.paperStyle}>\n <Typography>No external dependencies found</Typography>\n </Paper>\n </Box>\n );\n }\n\n return (\n <Table\n title=\"Status\"\n options={{\n paging: true,\n pageSize: 20,\n pageSizeOptions: [20, 50, 100],\n loadingType: 'linear',\n showEmptyDataSourceMessage: !loading,\n }}\n columns={columns}\n data={externalDependencies || []}\n />\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Header, Page, RoutedTabs } from '@backstage/core-components';\nimport {\n attachComponentData,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport { TabProps } from '@material-ui/core';\nimport { default as React } from 'react';\n\n/** @public */\nexport type SubRoute = {\n path: string;\n title: string;\n children: JSX.Element;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\nconst dataKey = 'plugin.devtools.devtoolsLayoutRoute';\n\nconst Route: (props: SubRoute) => null = () => null;\nattachComponentData(Route, dataKey, true);\n\n// This causes all mount points that are discovered within this route to use the path of the route itself\nattachComponentData(Route, 'core.gatherMountPoints', true);\n\n/** @public */\nexport type DevToolsLayoutProps = {\n children?: React.ReactNode;\n};\n\n/**\n * DevTools is a compound component, which allows you to define a custom layout\n *\n * @example\n * ```jsx\n * <DevToolsLayout>\n * <DevToolsLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </DevToolsLayout.Route>\n * </DevToolsLayout>\n * ```\n * @public\n */\nexport const DevToolsLayout = ({ children }: DevToolsLayoutProps) => {\n const routes = useElementFilter(children, elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of DevToolsLayout must be an DevToolsLayout.Route',\n })\n .getElements<SubRoute>()\n .map(child => child.props),\n );\n\n return (\n <Page themeId=\"home\">\n <Header title=\"Backstage DevTools\" />\n <RoutedTabs routes={routes} />\n </Page>\n );\n};\n\nDevToolsLayout.Route = Route;\n"],"names":["useStyles","columns"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@backstage/plugin-devtools",
3
+ "version": "0.0.0-nightly-20230509022028",
4
+ "main": "dist/index.esm.js",
5
+ "types": "dist/index.d.ts",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "main": "dist/index.esm.js",
10
+ "types": "dist/index.d.ts"
11
+ },
12
+ "backstage": {
13
+ "role": "frontend-plugin"
14
+ },
15
+ "homepage": "https://backstage.io",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/backstage/backstage",
19
+ "directory": "plugins/devtools"
20
+ },
21
+ "scripts": {
22
+ "start": "backstage-cli package start",
23
+ "build": "backstage-cli package build",
24
+ "lint": "backstage-cli package lint",
25
+ "test": "backstage-cli package test",
26
+ "clean": "backstage-cli package clean",
27
+ "prepack": "backstage-cli package prepack",
28
+ "postpack": "backstage-cli package postpack"
29
+ },
30
+ "dependencies": {
31
+ "@backstage/core-components": "^0.0.0-nightly-20230509022028",
32
+ "@backstage/core-plugin-api": "^1.5.1",
33
+ "@backstage/errors": "^1.1.5",
34
+ "@backstage/plugin-devtools-common": "^0.0.0-nightly-20230509022028",
35
+ "@backstage/plugin-permission-react": "^0.4.12",
36
+ "@backstage/theme": "^0.2.19",
37
+ "@backstage/types": "^1.0.2",
38
+ "@material-ui/core": "^4.9.13",
39
+ "@material-ui/icons": "^4.9.1",
40
+ "@material-ui/lab": "^4.0.0-alpha.57",
41
+ "react-json-view": "^1.21.3",
42
+ "react-use": "^17.2.4"
43
+ },
44
+ "peerDependencies": {
45
+ "@types/react": "^16.13.1 || ^17.0.0",
46
+ "react": "^16.13.1 || ^17.0.0",
47
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
48
+ },
49
+ "devDependencies": {
50
+ "@backstage/cli": "^0.0.0-nightly-20230509022028",
51
+ "@backstage/core-app-api": "^0.0.0-nightly-20230509022028",
52
+ "@backstage/dev-utils": "^0.0.0-nightly-20230509022028",
53
+ "@backstage/test-utils": "^0.0.0-nightly-20230509022028",
54
+ "@testing-library/jest-dom": "^5.10.1",
55
+ "@testing-library/react": "^12.1.3",
56
+ "@testing-library/user-event": "^14.0.0",
57
+ "@types/node": "*",
58
+ "cross-fetch": "^3.1.5",
59
+ "msw": "^0.47.0"
60
+ },
61
+ "files": [
62
+ "dist"
63
+ ],
64
+ "module": "./dist/index.esm.js"
65
+ }