@backstage/create-app 0.3.37 → 0.3.41

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 CHANGED
@@ -1,5 +1,136 @@
1
1
  # @backstage/create-app
2
2
 
3
+ ## 0.3.41
4
+
5
+ ## 0.3.40
6
+
7
+ ### Patch Changes
8
+
9
+ - a5013957e: Updated the search configuration class to use the static `fromConfig`-based constructor for the `DefaultCatalogCollator`.
10
+
11
+ To apply this change to an existing app, replace the following line in `search.ts`:
12
+
13
+ ```diff
14
+ -collator: new DefaultCatalogCollator({ discovery })
15
+ +collator: DefaultCatalogCollator.fromConfig(config, { discovery })
16
+ ```
17
+
18
+ The `config` parameter was not needed before, so make sure you also add that in the signature of `createPlugin`
19
+ in `search.ts`:
20
+
21
+ ```diff
22
+ export default async function createPlugin({
23
+ logger,
24
+ discovery,
25
+ + config,
26
+ }: PluginEnvironment) {
27
+ ```
28
+
29
+ - Updated dependencies
30
+ - @backstage/cli-common@0.1.3
31
+
32
+ ## 0.3.39
33
+
34
+ ### Patch Changes
35
+
36
+ - 25924638b: Minor tweaks to the create-app template to match earlier documented changes
37
+
38
+ ## 0.3.38
39
+
40
+ ### Patch Changes
41
+
42
+ - 787bc0826: Wire up TechDocs, which now relies on the composability API for routing.
43
+
44
+ First, ensure you've mounted `<TechDocsReaderPage />`. If you already updated
45
+ to use the composable `<TechDocsIndexPage />` (see below), no action is
46
+ necessary. Otherwise, update your `App.tsx` so that `<TechDocsReaderPage />` is
47
+ mounted:
48
+
49
+ ```diff
50
+ <Route path="/docs" element={<TechdocsPage />} />
51
+ + <Route
52
+ + path="/docs/:namespace/:kind/:name/*"
53
+ + element={<TechDocsReaderPage />}
54
+ + />
55
+ ```
56
+
57
+ Next, ensure links from the Catalog Entity Page to its TechDocs site are bound:
58
+
59
+ ```diff
60
+ bindRoutes({ bind }) {
61
+ bind(catalogPlugin.externalRoutes, {
62
+ createComponent: scaffolderPlugin.routes.root,
63
+ + viewTechDoc: techdocsPlugin.routes.docRoot,
64
+ });
65
+ ```
66
+
67
+ - d02768171: Updated the default create-app `EntityPage` to include orphan and processing error alerts for all entity types. Previously these were only shown for entities with the `Component` kind. This also adds the `EntityLinkCard` for API entities.
68
+
69
+ As an example, you might add this to your `packages/app/src/components/catalog/EntityPage.tsx`:
70
+
71
+ ```tsx
72
+ const entityWarningContent = (
73
+ <>
74
+ <EntitySwitch>
75
+ <EntitySwitch.Case if={isOrphan}>
76
+ <Grid item xs={12}>
77
+ <EntityOrphanWarning />
78
+ </Grid>
79
+ </EntitySwitch.Case>
80
+ </EntitySwitch>
81
+ <EntitySwitch>
82
+ <EntitySwitch.Case if={hasCatalogProcessingErrors}>
83
+ <Grid item xs={12}>
84
+ <EntityProcessingErrorsPanel />
85
+ </Grid>
86
+ </EntitySwitch.Case>
87
+ </EntitySwitch>
88
+ </>
89
+ );
90
+ ```
91
+
92
+ and then add that at the top of your various content pages:
93
+
94
+ ```diff
95
+ const overviewContent = (
96
+ <Grid container spacing={3} alignItems="stretch">
97
+ + {entityWarningContent}
98
+ <Grid item md={6}>
99
+ <EntityAboutCard variant="gridItem" />
100
+ </Grid>
101
+ ```
102
+
103
+ or in actual page wrappers:
104
+
105
+ ```diff
106
+ const apiPage = (
107
+ <EntityLayout>
108
+ <EntityLayout.Route path="/" title="Overview">
109
+ <Grid container spacing={3}>
110
+ + {entityWarningContent}
111
+ <Grid item md={6}>
112
+ <EntityAboutCard />
113
+ </Grid>
114
+ ```
115
+
116
+ Note that there may be many such `*Page` pages in that file, and you probably want that warning at the top of them all.
117
+
118
+ You can also add the links card to your API page if you do not already have it:
119
+
120
+ ```diff
121
+ const apiPage = (
122
+ <EntityLayout>
123
+ <EntityLayout.Route path="/" title="Overview">
124
+ <Grid container spacing={3}>
125
+ + {entityWarningContent}
126
+ <Grid item md={6}>
127
+ <EntityAboutCard />
128
+ </Grid>
129
+ + <Grid item md={4} xs={12}>
130
+ + <EntityLinksCard />
131
+ + </Grid>
132
+ ```
133
+
3
134
  ## 0.3.37
4
135
 
5
136
  ## 0.3.36
@@ -594,7 +725,7 @@
594
725
  -<Route path="/search" element={<SearchPage />} />
595
726
  +<Route path="/search" element={<SearchPage />}>
596
727
  + {searchPage}
597
- +</Route>;
728
+ +</Route>
598
729
  ```
599
730
 
600
731
  - Updated dependencies [9cd3c533c]
package/dist/index.cjs.js CHANGED
@@ -55,77 +55,77 @@ ${chalk__default['default'].red(`${error}`)}
55
55
  }
56
56
  }
57
57
 
58
- var version$z = "0.3.37";
58
+ var version$z = "0.3.41";
59
59
 
60
- var version$y = "0.8.10";
60
+ var version$y = "0.9.3";
61
61
 
62
- var version$x = "0.3.18";
62
+ var version$x = "0.3.19";
63
63
 
64
- var version$w = "0.9.0";
64
+ var version$w = "0.9.2";
65
65
 
66
- var version$v = "0.7.9";
66
+ var version$v = "0.7.12";
67
67
 
68
- var version$u = "0.1.7";
68
+ var version$u = "0.1.9";
69
69
 
70
- var version$t = "0.1.9";
70
+ var version$t = "0.1.13";
71
71
 
72
- var version$s = "0.3.2";
72
+ var version$s = "0.4.2";
73
73
 
74
- var version$r = "0.1.6";
74
+ var version$r = "0.1.8";
75
75
 
76
- var version$q = "0.1.1";
76
+ var version$q = "0.1.2";
77
77
 
78
- var version$p = "0.1.7";
78
+ var version$p = "0.1.9";
79
79
 
80
80
  var version$o = "0.1.17";
81
81
 
82
82
  var version$n = "0.2.10";
83
83
 
84
- var version$m = "0.6.6";
84
+ var version$m = "0.6.8";
85
85
 
86
- var version$l = "0.3.15";
86
+ var version$l = "0.3.16";
87
87
 
88
- var version$k = "0.3.22";
88
+ var version$k = "0.4.0";
89
89
 
90
- var version$j = "0.6.12";
90
+ var version$j = "0.6.15";
91
91
 
92
- var version$i = "0.4.3";
92
+ var version$i = "0.4.6";
93
93
 
94
- var version$h = "0.13.4";
94
+ var version$h = "0.13.8";
95
95
 
96
- var version$g = "0.5.18";
96
+ var version$g = "0.5.21";
97
97
 
98
- var version$f = "0.2.21";
98
+ var version$f = "0.2.23";
99
99
 
100
- var version$e = "0.3.13";
100
+ var version$e = "0.3.16";
101
101
 
102
- var version$d = "0.4.16";
102
+ var version$d = "0.4.18";
103
103
 
104
- var version$c = "0.2.23";
104
+ var version$c = "0.2.25";
105
105
 
106
- var version$b = "0.3.19";
106
+ var version$b = "0.3.23";
107
107
 
108
- var version$a = "0.2.11";
108
+ var version$a = "0.2.12";
109
109
 
110
- var version$9 = "0.1.13";
110
+ var version$9 = "0.1.14";
111
111
 
112
- var version$8 = "0.11.1";
112
+ var version$8 = "0.11.4";
113
113
 
114
- var version$7 = "0.15.1";
114
+ var version$7 = "0.15.5";
115
115
 
116
- var version$6 = "0.4.7";
116
+ var version$6 = "0.4.11";
117
117
 
118
- var version$5 = "0.2.4";
118
+ var version$5 = "0.2.6";
119
119
 
120
- var version$4 = "0.4.1";
120
+ var version$4 = "0.4.2";
121
121
 
122
- var version$3 = "0.4.5";
122
+ var version$3 = "0.4.7";
123
123
 
124
- var version$2 = "0.10.4";
124
+ var version$2 = "0.11.2";
125
125
 
126
- var version$1 = "0.9.2";
126
+ var version$1 = "0.10.2";
127
127
 
128
- var version = "0.3.3";
128
+ var version = "0.3.5";
129
129
 
130
130
  const packageVersions = {
131
131
  "@backstage/backend-common": version$y,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/lib/errors.ts","../src/lib/versions.ts","../src/lib/tasks.ts","../src/createApp.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright 2020 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 chalk from 'chalk';\n\nexport class CustomError extends Error {\n get name(): string {\n return this.constructor.name;\n }\n}\n\nexport class ExitCodeError extends CustomError {\n readonly code: number;\n\n constructor(code: number, command?: string) {\n if (command) {\n super(`Command '${command}' exited with code ${code}`);\n } else {\n super(`Child exited with code ${code}`);\n }\n this.code = code;\n }\n}\n\nexport function exitWithError(error: Error): never {\n if (error instanceof ExitCodeError) {\n process.stderr.write(`\\n${chalk.red(error.message)}\\n\\n`);\n process.exit(error.code);\n } else {\n process.stderr.write(`\\n${chalk.red(`${error}`)}\\n\\n`);\n process.exit(1);\n }\n}\n","/*\n * Copyright 2020 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\n/* eslint-disable monorepo/no-relative-import */\n\n/*\nThis is a list of all packages used by the template. If dependencies are added or removed,\nthis list should be updated as well.\n\nThe list, and the accompanying peerDependencies entries, are here to ensure correct versioning\nand bumping of this package. Without this list the version would not be bumped unless we\nmanually trigger a release.\n\nThis does not create an actual dependency on these packages and does not bring in any code.\nRelative imports are used rather than package imports to make sure the packages aren't externalized.\nRollup will extract the value of the version field in each package at build time without\nleaving any imports in place.\n*/\n\nimport { version as backendCommon } from '../../../backend-common/package.json';\nimport { version as catalogClient } from '../../../catalog-client/package.json';\nimport { version as catalogModel } from '../../../catalog-model/package.json';\nimport { version as cli } from '../../../cli/package.json';\nimport { version as config } from '../../../config/package.json';\nimport { version as coreAppApi } from '../../../core-app-api/package.json';\nimport { version as coreComponents } from '../../../core-components/package.json';\nimport { version as corePluginApi } from '../../../core-plugin-api/package.json';\nimport { version as errors } from '../../../errors/package.json';\nimport { version as integrationReact } from '../../../integration-react/package.json';\nimport { version as testUtils } from '../../../test-utils/package.json';\nimport { version as theme } from '../../../theme/package.json';\n\nimport { version as pluginApiDocs } from '../../../../plugins/api-docs/package.json';\nimport { version as pluginAppBackend } from '../../../../plugins/app-backend/package.json';\nimport { version as pluginAuthBackend } from '../../../../plugins/auth-backend/package.json';\nimport { version as pluginCatalog } from '../../../../plugins/catalog/package.json';\nimport { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json';\nimport { version as pluginCatalogBackend } from '../../../../plugins/catalog-backend/package.json';\nimport { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json';\nimport { version as pluginCircleci } from '../../../../plugins/circleci/package.json';\nimport { version as pluginExplore } from '../../../../plugins/explore/package.json';\nimport { version as pluginGithubActions } from '../../../../plugins/github-actions/package.json';\nimport { version as pluginLighthouse } from '../../../../plugins/lighthouse/package.json';\nimport { version as pluginOrg } from '../../../../plugins/org/package.json';\nimport { version as pluginProxyBackend } from '../../../../plugins/proxy-backend/package.json';\nimport { version as pluginRollbarBackend } from '../../../../plugins/rollbar-backend/package.json';\nimport { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json';\nimport { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json';\nimport { version as pluginSearch } from '../../../../plugins/search/package.json';\nimport { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json';\nimport { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json';\nimport { version as pluginTechRadar } from '../../../../plugins/tech-radar/package.json';\nimport { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json';\nimport { version as pluginTechdocsBackend } from '../../../../plugins/techdocs-backend/package.json';\nimport { version as pluginUserSettings } from '../../../../plugins/user-settings/package.json';\n\nexport const packageVersions = {\n '@backstage/backend-common': backendCommon,\n '@backstage/catalog-client': catalogClient,\n '@backstage/catalog-model': catalogModel,\n '@backstage/cli': cli,\n '@backstage/config': config,\n '@backstage/core-app-api': coreAppApi,\n '@backstage/core-components': coreComponents,\n '@backstage/core-plugin-api': corePluginApi,\n '@backstage/errors': errors,\n '@backstage/integration-react': integrationReact,\n '@backstage/plugin-api-docs': pluginApiDocs,\n '@backstage/plugin-app-backend': pluginAppBackend,\n '@backstage/plugin-auth-backend': pluginAuthBackend,\n '@backstage/plugin-catalog': pluginCatalog,\n '@backstage/plugin-catalog-react': pluginCatalogReact,\n '@backstage/plugin-catalog-backend': pluginCatalogBackend,\n '@backstage/plugin-catalog-import': pluginCatalogImport,\n '@backstage/plugin-circleci': pluginCircleci,\n '@backstage/plugin-explore': pluginExplore,\n '@backstage/plugin-github-actions': pluginGithubActions,\n '@backstage/plugin-lighthouse': pluginLighthouse,\n '@backstage/plugin-org': pluginOrg,\n '@backstage/plugin-proxy-backend': pluginProxyBackend,\n '@backstage/plugin-rollbar-backend': pluginRollbarBackend,\n '@backstage/plugin-scaffolder': pluginScaffolder,\n '@backstage/plugin-scaffolder-backend': pluginScaffolderBackend,\n '@backstage/plugin-search': pluginSearch,\n '@backstage/plugin-search-backend': pluginSearchBackend,\n '@backstage/plugin-search-backend-node': pluginSearchBackendNode,\n '@backstage/plugin-tech-radar': pluginTechRadar,\n '@backstage/plugin-techdocs': pluginTechdocs,\n '@backstage/plugin-techdocs-backend': pluginTechdocsBackend,\n '@backstage/plugin-user-settings': pluginUserSettings,\n '@backstage/test-utils': testUtils,\n '@backstage/theme': theme,\n};\n","/*\n * Copyright 2020 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 chalk from 'chalk';\nimport fs from 'fs-extra';\nimport handlebars from 'handlebars';\nimport ora from 'ora';\nimport { basename, dirname } from 'path';\nimport recursive from 'recursive-readdir';\nimport { packageVersions } from './versions';\n\nconst TASK_NAME_MAX_LENGTH = 14;\n\nexport class Task {\n static log(name: string = '') {\n process.stdout.write(`${chalk.green(name)}\\n`);\n }\n\n static error(message: string = '') {\n process.stdout.write(`\\n${chalk.red(message)}\\n\\n`);\n }\n\n static section(name: string) {\n const title = chalk.green(`${name}:`);\n process.stdout.write(`\\n ${title}\\n`);\n }\n\n static exit(code: number = 0) {\n process.exit(code);\n }\n\n static async forItem(\n task: string,\n item: string,\n taskFunc: () => Promise<void>,\n ): Promise<void> {\n const paddedTask = chalk.green(task.padEnd(TASK_NAME_MAX_LENGTH));\n\n const spinner = ora({\n prefixText: chalk.green(` ${paddedTask}${chalk.cyan(item)}`),\n spinner: 'arc',\n color: 'green',\n }).start();\n\n try {\n await taskFunc();\n spinner.succeed();\n } catch (error) {\n spinner.fail();\n throw error;\n }\n }\n}\n\nexport async function templatingTask(\n templateDir: string,\n destinationDir: string,\n context: any,\n) {\n const files = await recursive(templateDir).catch(error => {\n throw new Error(`Failed to read template directory: ${error.message}`);\n });\n\n for (const file of files) {\n const destinationFile = file.replace(templateDir, destinationDir);\n await fs.ensureDir(dirname(destinationFile));\n\n if (file.endsWith('.hbs')) {\n await Task.forItem('templating', basename(file), async () => {\n const destination = destinationFile.replace(/\\.hbs$/, '');\n\n const template = await fs.readFile(file);\n const compiled = handlebars.compile(template.toString());\n const contents = compiled(\n { name: basename(destination), ...context },\n {\n helpers: {\n version(name: keyof typeof packageVersions) {\n if (name in packageVersions) {\n return packageVersions[name];\n }\n throw new Error(`No version available for package ${name}`);\n },\n },\n },\n );\n\n await fs.writeFile(destination, contents).catch(error => {\n throw new Error(\n `Failed to create file: ${destination}: ${error.message}`,\n );\n });\n });\n } else {\n await Task.forItem('copying', basename(file), async () => {\n await fs.copyFile(file, destinationFile).catch(error => {\n const destination = destinationFile;\n throw new Error(\n `Failed to copy file to ${destination} : ${error.message}`,\n );\n });\n });\n }\n }\n}\n","/*\n * Copyright 2020 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 fs from 'fs-extra';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport inquirer, { Answers, Question } from 'inquirer';\nimport { exec as execCb } from 'child_process';\nimport { resolve as resolvePath } from 'path';\nimport { findPaths } from '@backstage/cli-common';\nimport os from 'os';\nimport { Task, templatingTask } from './lib/tasks';\n\nconst exec = promisify(execCb);\n\nasync function checkExists(rootDir: string, name: string) {\n await Task.forItem('checking', name, async () => {\n const destination = resolvePath(rootDir, name);\n\n if (await fs.pathExists(destination)) {\n const existing = chalk.cyan(destination.replace(`${rootDir}/`, ''));\n throw new Error(\n `A directory with the same name already exists: ${existing}\\nPlease try again with a different app name`,\n );\n }\n });\n}\n\nasync function createTemporaryAppFolder(tempDir: string) {\n await Task.forItem('creating', 'temporary directory', async () => {\n try {\n await fs.mkdir(tempDir);\n } catch (error) {\n throw new Error(\n `Failed to create temporary app directory: ${error.message}`,\n );\n }\n });\n}\n\nasync function cleanUp(tempDir: string) {\n await Task.forItem('remove', 'temporary directory', async () => {\n await fs.remove(tempDir);\n });\n}\n\nasync function buildApp(appDir: string) {\n const runCmd = async (cmd: string) => {\n await Task.forItem('executing', cmd, async () => {\n process.chdir(appDir);\n\n await exec(cmd).catch(error => {\n process.stdout.write(error.stderr);\n process.stdout.write(error.stdout);\n throw new Error(`Could not execute command ${chalk.cyan(cmd)}`);\n });\n });\n };\n\n await runCmd('yarn install');\n await runCmd('yarn tsc');\n}\n\nasync function moveApp(tempDir: string, destination: string, id: string) {\n await Task.forItem('moving', id, async () => {\n await fs.move(tempDir, destination).catch(error => {\n throw new Error(\n `Failed to move app from ${tempDir} to ${destination}: ${error.message}`,\n );\n });\n });\n}\n\nexport default async (cmd: Command): Promise<void> => {\n /* eslint-disable-next-line no-restricted-syntax */\n const paths = findPaths(__dirname);\n\n const questions: Question[] = [\n {\n type: 'input',\n name: 'name',\n message: chalk.blue('Enter a name for the app [required]'),\n validate: (value: any) => {\n if (!value) {\n return chalk.red('Please enter a name for the app');\n } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {\n return chalk.red(\n 'App name must be lowercase and contain only letters, digits, and dashes.',\n );\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'dbType',\n message: chalk.blue('Select database for the backend [required]'),\n // @ts-ignore\n choices: ['SQLite', 'PostgreSQL'],\n },\n ];\n const answers: Answers = await inquirer.prompt(questions);\n answers.dbTypePG = answers.dbType === 'PostgreSQL';\n answers.dbTypeSqlite = answers.dbType === 'SQLite';\n\n const templateDir = paths.resolveOwn('templates/default-app');\n const tempDir = resolvePath(os.tmpdir(), answers.name);\n const appDir = resolvePath(paths.targetDir, answers.name);\n\n Task.log();\n Task.log('Creating the app...');\n\n try {\n Task.section('Checking if the directory is available');\n await checkExists(paths.targetDir, answers.name);\n\n Task.section('Creating a temporary app directory');\n await createTemporaryAppFolder(tempDir);\n\n Task.section('Preparing files');\n await templatingTask(templateDir, tempDir, answers);\n\n Task.section('Moving to final location');\n await moveApp(tempDir, appDir, answers.name);\n\n if (!cmd.skipInstall) {\n Task.section('Building the app');\n await buildApp(appDir);\n }\n\n Task.log();\n Task.log(\n chalk.green(`🥇 Successfully created ${chalk.cyan(answers.name)}`),\n );\n Task.log();\n Task.section('All set! Now you might want to');\n Task.log(` Run the app: ${chalk.cyan(`cd ${answers.name} && yarn dev`)}`);\n Task.log(\n ' Set up the software catalog: https://backstage.io/docs/features/software-catalog/configuration',\n );\n Task.log(' Add authentication: https://backstage.io/docs/auth/');\n Task.log();\n Task.exit();\n } catch (error) {\n Task.error(error.message);\n\n Task.log('It seems that something went wrong when creating the app 🤔');\n Task.log('We are going to clean up, and then you can try again.');\n\n Task.section('Cleanup');\n await cleanUp(tempDir);\n Task.error('🔥 Failed to create app!');\n Task.exit(1);\n }\n};\n","/*\n * Copyright 2020 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 program from 'commander';\nimport { exitWithError } from './lib/errors';\nimport { version } from '../package.json';\nimport createApp from './createApp';\n\nconst main = (argv: string[]) => {\n program.name('backstage-create-app').version(version);\n\n program\n .description('Creates a new app in a new directory')\n .option(\n '--skip-install',\n 'Skip the install and builds steps after creating the app',\n )\n .action(createApp);\n\n program.parse(argv);\n};\n\nprocess.on('unhandledRejection', rejection => {\n if (rejection instanceof Error) {\n exitWithError(rejection);\n } else {\n exitWithError(new Error(`Unknown rejection: '${rejection}'`));\n }\n});\n\nmain(process.argv);\n"],"names":["chalk","backendCommon","catalogClient","catalogModel","cli","config","coreAppApi","coreComponents","corePluginApi","errors","integrationReact","pluginApiDocs","pluginAppBackend","pluginAuthBackend","pluginCatalog","pluginCatalogReact","pluginCatalogBackend","pluginCatalogImport","pluginCircleci","pluginExplore","pluginGithubActions","pluginLighthouse","pluginOrg","pluginProxyBackend","pluginRollbarBackend","pluginScaffolder","pluginScaffolderBackend","pluginSearch","pluginSearchBackend","pluginSearchBackendNode","pluginTechRadar","pluginTechdocs","pluginTechdocsBackend","pluginUserSettings","testUtils","theme","ora","recursive","fs","dirname","basename","handlebars","promisify","execCb","resolvePath","findPaths","inquirer","os","version"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/lib/errors.ts","../src/lib/versions.ts","../src/lib/tasks.ts","../src/createApp.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright 2020 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 chalk from 'chalk';\n\nexport class CustomError extends Error {\n get name(): string {\n return this.constructor.name;\n }\n}\n\nexport class ExitCodeError extends CustomError {\n readonly code: number;\n\n constructor(code: number, command?: string) {\n if (command) {\n super(`Command '${command}' exited with code ${code}`);\n } else {\n super(`Child exited with code ${code}`);\n }\n this.code = code;\n }\n}\n\nexport function exitWithError(error: Error): never {\n if (error instanceof ExitCodeError) {\n process.stderr.write(`\\n${chalk.red(error.message)}\\n\\n`);\n process.exit(error.code);\n } else {\n process.stderr.write(`\\n${chalk.red(`${error}`)}\\n\\n`);\n process.exit(1);\n }\n}\n","/*\n * Copyright 2020 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\n/* eslint-disable monorepo/no-relative-import */\n\n/*\nThis is a list of all packages used by the template. If dependencies are added or removed,\nthis list should be updated as well.\n\nThe list, and the accompanying peerDependencies entries, are here to ensure correct versioning\nand bumping of this package. Without this list the version would not be bumped unless we\nmanually trigger a release.\n\nThis does not create an actual dependency on these packages and does not bring in any code.\nRelative imports are used rather than package imports to make sure the packages aren't externalized.\nRollup will extract the value of the version field in each package at build time without\nleaving any imports in place.\n*/\n\nimport { version as backendCommon } from '../../../backend-common/package.json';\nimport { version as catalogClient } from '../../../catalog-client/package.json';\nimport { version as catalogModel } from '../../../catalog-model/package.json';\nimport { version as cli } from '../../../cli/package.json';\nimport { version as config } from '../../../config/package.json';\nimport { version as coreAppApi } from '../../../core-app-api/package.json';\nimport { version as coreComponents } from '../../../core-components/package.json';\nimport { version as corePluginApi } from '../../../core-plugin-api/package.json';\nimport { version as errors } from '../../../errors/package.json';\nimport { version as integrationReact } from '../../../integration-react/package.json';\nimport { version as testUtils } from '../../../test-utils/package.json';\nimport { version as theme } from '../../../theme/package.json';\n\nimport { version as pluginApiDocs } from '../../../../plugins/api-docs/package.json';\nimport { version as pluginAppBackend } from '../../../../plugins/app-backend/package.json';\nimport { version as pluginAuthBackend } from '../../../../plugins/auth-backend/package.json';\nimport { version as pluginCatalog } from '../../../../plugins/catalog/package.json';\nimport { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json';\nimport { version as pluginCatalogBackend } from '../../../../plugins/catalog-backend/package.json';\nimport { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json';\nimport { version as pluginCircleci } from '../../../../plugins/circleci/package.json';\nimport { version as pluginExplore } from '../../../../plugins/explore/package.json';\nimport { version as pluginGithubActions } from '../../../../plugins/github-actions/package.json';\nimport { version as pluginLighthouse } from '../../../../plugins/lighthouse/package.json';\nimport { version as pluginOrg } from '../../../../plugins/org/package.json';\nimport { version as pluginProxyBackend } from '../../../../plugins/proxy-backend/package.json';\nimport { version as pluginRollbarBackend } from '../../../../plugins/rollbar-backend/package.json';\nimport { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json';\nimport { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json';\nimport { version as pluginSearch } from '../../../../plugins/search/package.json';\nimport { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json';\nimport { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json';\nimport { version as pluginTechRadar } from '../../../../plugins/tech-radar/package.json';\nimport { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json';\nimport { version as pluginTechdocsBackend } from '../../../../plugins/techdocs-backend/package.json';\nimport { version as pluginUserSettings } from '../../../../plugins/user-settings/package.json';\n\nexport const packageVersions = {\n '@backstage/backend-common': backendCommon,\n '@backstage/catalog-client': catalogClient,\n '@backstage/catalog-model': catalogModel,\n '@backstage/cli': cli,\n '@backstage/config': config,\n '@backstage/core-app-api': coreAppApi,\n '@backstage/core-components': coreComponents,\n '@backstage/core-plugin-api': corePluginApi,\n '@backstage/errors': errors,\n '@backstage/integration-react': integrationReact,\n '@backstage/plugin-api-docs': pluginApiDocs,\n '@backstage/plugin-app-backend': pluginAppBackend,\n '@backstage/plugin-auth-backend': pluginAuthBackend,\n '@backstage/plugin-catalog': pluginCatalog,\n '@backstage/plugin-catalog-react': pluginCatalogReact,\n '@backstage/plugin-catalog-backend': pluginCatalogBackend,\n '@backstage/plugin-catalog-import': pluginCatalogImport,\n '@backstage/plugin-circleci': pluginCircleci,\n '@backstage/plugin-explore': pluginExplore,\n '@backstage/plugin-github-actions': pluginGithubActions,\n '@backstage/plugin-lighthouse': pluginLighthouse,\n '@backstage/plugin-org': pluginOrg,\n '@backstage/plugin-proxy-backend': pluginProxyBackend,\n '@backstage/plugin-rollbar-backend': pluginRollbarBackend,\n '@backstage/plugin-scaffolder': pluginScaffolder,\n '@backstage/plugin-scaffolder-backend': pluginScaffolderBackend,\n '@backstage/plugin-search': pluginSearch,\n '@backstage/plugin-search-backend': pluginSearchBackend,\n '@backstage/plugin-search-backend-node': pluginSearchBackendNode,\n '@backstage/plugin-tech-radar': pluginTechRadar,\n '@backstage/plugin-techdocs': pluginTechdocs,\n '@backstage/plugin-techdocs-backend': pluginTechdocsBackend,\n '@backstage/plugin-user-settings': pluginUserSettings,\n '@backstage/test-utils': testUtils,\n '@backstage/theme': theme,\n};\n","/*\n * Copyright 2020 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 chalk from 'chalk';\nimport fs from 'fs-extra';\nimport handlebars from 'handlebars';\nimport ora from 'ora';\nimport { basename, dirname } from 'path';\nimport recursive from 'recursive-readdir';\nimport { packageVersions } from './versions';\n\nconst TASK_NAME_MAX_LENGTH = 14;\n\nexport class Task {\n static log(name: string = '') {\n process.stdout.write(`${chalk.green(name)}\\n`);\n }\n\n static error(message: string = '') {\n process.stdout.write(`\\n${chalk.red(message)}\\n\\n`);\n }\n\n static section(name: string) {\n const title = chalk.green(`${name}:`);\n process.stdout.write(`\\n ${title}\\n`);\n }\n\n static exit(code: number = 0) {\n process.exit(code);\n }\n\n static async forItem(\n task: string,\n item: string,\n taskFunc: () => Promise<void>,\n ): Promise<void> {\n const paddedTask = chalk.green(task.padEnd(TASK_NAME_MAX_LENGTH));\n\n const spinner = ora({\n prefixText: chalk.green(` ${paddedTask}${chalk.cyan(item)}`),\n spinner: 'arc',\n color: 'green',\n }).start();\n\n try {\n await taskFunc();\n spinner.succeed();\n } catch (error) {\n spinner.fail();\n throw error;\n }\n }\n}\n\nexport async function templatingTask(\n templateDir: string,\n destinationDir: string,\n context: any,\n) {\n const files = await recursive(templateDir).catch(error => {\n throw new Error(`Failed to read template directory: ${error.message}`);\n });\n\n for (const file of files) {\n const destinationFile = file.replace(templateDir, destinationDir);\n await fs.ensureDir(dirname(destinationFile));\n\n if (file.endsWith('.hbs')) {\n await Task.forItem('templating', basename(file), async () => {\n const destination = destinationFile.replace(/\\.hbs$/, '');\n\n const template = await fs.readFile(file);\n const compiled = handlebars.compile(template.toString());\n const contents = compiled(\n { name: basename(destination), ...context },\n {\n helpers: {\n version(name: keyof typeof packageVersions) {\n if (name in packageVersions) {\n return packageVersions[name];\n }\n throw new Error(`No version available for package ${name}`);\n },\n },\n },\n );\n\n await fs.writeFile(destination, contents).catch(error => {\n throw new Error(\n `Failed to create file: ${destination}: ${error.message}`,\n );\n });\n });\n } else {\n await Task.forItem('copying', basename(file), async () => {\n await fs.copyFile(file, destinationFile).catch(error => {\n const destination = destinationFile;\n throw new Error(\n `Failed to copy file to ${destination} : ${error.message}`,\n );\n });\n });\n }\n }\n}\n","/*\n * Copyright 2020 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 fs from 'fs-extra';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport inquirer, { Answers, Question } from 'inquirer';\nimport { exec as execCb } from 'child_process';\nimport { resolve as resolvePath } from 'path';\nimport { findPaths } from '@backstage/cli-common';\nimport os from 'os';\nimport { Task, templatingTask } from './lib/tasks';\n\nconst exec = promisify(execCb);\n\nasync function checkExists(rootDir: string, name: string) {\n await Task.forItem('checking', name, async () => {\n const destination = resolvePath(rootDir, name);\n\n if (await fs.pathExists(destination)) {\n const existing = chalk.cyan(destination.replace(`${rootDir}/`, ''));\n throw new Error(\n `A directory with the same name already exists: ${existing}\\nPlease try again with a different app name`,\n );\n }\n });\n}\n\nasync function createTemporaryAppFolder(tempDir: string) {\n await Task.forItem('creating', 'temporary directory', async () => {\n try {\n await fs.mkdir(tempDir);\n } catch (error) {\n throw new Error(\n `Failed to create temporary app directory: ${error.message}`,\n );\n }\n });\n}\n\nasync function cleanUp(tempDir: string) {\n await Task.forItem('remove', 'temporary directory', async () => {\n await fs.remove(tempDir);\n });\n}\n\nasync function buildApp(appDir: string) {\n const runCmd = async (cmd: string) => {\n await Task.forItem('executing', cmd, async () => {\n process.chdir(appDir);\n\n await exec(cmd).catch(error => {\n process.stdout.write(error.stderr);\n process.stdout.write(error.stdout);\n throw new Error(`Could not execute command ${chalk.cyan(cmd)}`);\n });\n });\n };\n\n await runCmd('yarn install');\n await runCmd('yarn tsc');\n}\n\nasync function moveApp(tempDir: string, destination: string, id: string) {\n await Task.forItem('moving', id, async () => {\n await fs.move(tempDir, destination).catch(error => {\n throw new Error(\n `Failed to move app from ${tempDir} to ${destination}: ${error.message}`,\n );\n });\n });\n}\n\nexport default async (cmd: Command): Promise<void> => {\n /* eslint-disable-next-line no-restricted-syntax */\n const paths = findPaths(__dirname);\n\n const questions: Question[] = [\n {\n type: 'input',\n name: 'name',\n message: chalk.blue('Enter a name for the app [required]'),\n validate: (value: any) => {\n if (!value) {\n return chalk.red('Please enter a name for the app');\n } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {\n return chalk.red(\n 'App name must be lowercase and contain only letters, digits, and dashes.',\n );\n }\n return true;\n },\n },\n {\n type: 'list',\n name: 'dbType',\n message: chalk.blue('Select database for the backend [required]'),\n // @ts-ignore\n choices: ['SQLite', 'PostgreSQL'],\n },\n ];\n const answers: Answers = await inquirer.prompt(questions);\n answers.dbTypePG = answers.dbType === 'PostgreSQL';\n answers.dbTypeSqlite = answers.dbType === 'SQLite';\n\n const templateDir = paths.resolveOwn('templates/default-app');\n const tempDir = resolvePath(os.tmpdir(), answers.name);\n const appDir = resolvePath(paths.targetDir, answers.name);\n\n Task.log();\n Task.log('Creating the app...');\n\n try {\n Task.section('Checking if the directory is available');\n await checkExists(paths.targetDir, answers.name);\n\n Task.section('Creating a temporary app directory');\n await createTemporaryAppFolder(tempDir);\n\n Task.section('Preparing files');\n await templatingTask(templateDir, tempDir, answers);\n\n Task.section('Moving to final location');\n await moveApp(tempDir, appDir, answers.name);\n\n if (!cmd.skipInstall) {\n Task.section('Building the app');\n await buildApp(appDir);\n }\n\n Task.log();\n Task.log(\n chalk.green(`🥇 Successfully created ${chalk.cyan(answers.name)}`),\n );\n Task.log();\n Task.section('All set! Now you might want to');\n Task.log(` Run the app: ${chalk.cyan(`cd ${answers.name} && yarn dev`)}`);\n Task.log(\n ' Set up the software catalog: https://backstage.io/docs/features/software-catalog/configuration',\n );\n Task.log(' Add authentication: https://backstage.io/docs/auth/');\n Task.log();\n Task.exit();\n } catch (error) {\n Task.error(error.message);\n\n Task.log('It seems that something went wrong when creating the app 🤔');\n Task.log('We are going to clean up, and then you can try again.');\n\n Task.section('Cleanup');\n await cleanUp(tempDir);\n Task.error('🔥 Failed to create app!');\n Task.exit(1);\n }\n};\n","/*\n * Copyright 2020 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\n/**\n * A CLI that helps you create your own Backstage app\n *\n * @packageDocumentation\n */\n\nimport program from 'commander';\nimport { exitWithError } from './lib/errors';\nimport { version } from '../package.json';\nimport createApp from './createApp';\n\nconst main = (argv: string[]) => {\n program.name('backstage-create-app').version(version);\n\n program\n .description('Creates a new app in a new directory')\n .option(\n '--skip-install',\n 'Skip the install and builds steps after creating the app',\n )\n .action(createApp);\n\n program.parse(argv);\n};\n\nprocess.on('unhandledRejection', rejection => {\n if (rejection instanceof Error) {\n exitWithError(rejection);\n } else {\n exitWithError(new Error(`Unknown rejection: '${rejection}'`));\n }\n});\n\nmain(process.argv);\n"],"names":["chalk","backendCommon","catalogClient","catalogModel","cli","config","coreAppApi","coreComponents","corePluginApi","errors","integrationReact","pluginApiDocs","pluginAppBackend","pluginAuthBackend","pluginCatalog","pluginCatalogReact","pluginCatalogBackend","pluginCatalogImport","pluginCircleci","pluginExplore","pluginGithubActions","pluginLighthouse","pluginOrg","pluginProxyBackend","pluginRollbarBackend","pluginScaffolder","pluginScaffolderBackend","pluginSearch","pluginSearchBackend","pluginSearchBackendNode","pluginTechRadar","pluginTechdocs","pluginTechdocsBackend","pluginUserSettings","testUtils","theme","ora","recursive","fs","dirname","basename","handlebars","promisify","execCb","resolvePath","findPaths","inquirer","os","version"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/create-app",
3
- "description": "Create app package for Backstage",
4
- "version": "0.3.37",
3
+ "description": "A CLI that helps you create your own Backstage app",
4
+ "version": "0.3.41",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -27,7 +27,7 @@
27
27
  "start": "nodemon --"
28
28
  },
29
29
  "dependencies": {
30
- "@backstage/cli-common": "^0.1.2",
30
+ "@backstage/cli-common": "^0.1.3",
31
31
  "chalk": "^4.0.0",
32
32
  "commander": "^6.1.0",
33
33
  "fs-extra": "9.1.0",
@@ -86,5 +86,5 @@
86
86
  "dist",
87
87
  "templates"
88
88
  ],
89
- "gitHead": "95f4f667ceb03d65d3195d5695b357269ba72347"
89
+ "gitHead": "4dc47ebe3c30e9bdba9c2239aed9ece1a4d479a0"
90
90
  }
@@ -16,11 +16,13 @@ import { TechRadarPage } from '@backstage/plugin-tech-radar';
16
16
  import {
17
17
  DefaultTechDocsHome,
18
18
  TechDocsIndexPage,
19
+ techdocsPlugin,
19
20
  TechDocsReaderPage,
20
21
  } from '@backstage/plugin-techdocs';
21
22
  import { UserSettingsPage } from '@backstage/plugin-user-settings';
22
23
  import { apis } from './apis';
23
24
  import { entityPage } from './components/catalog/EntityPage';
25
+ import { searchPage } from './components/search/SearchPage';
24
26
  import { Root } from './components/Root';
25
27
 
26
28
  import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';
@@ -31,6 +33,7 @@ const app = createApp({
31
33
  bindRoutes({ bind }) {
32
34
  bind(catalogPlugin.externalRoutes, {
33
35
  createComponent: scaffolderPlugin.routes.root,
36
+ viewTechDoc: techdocsPlugin.routes.docRoot,
34
37
  });
35
38
  bind(apiDocsPlugin.externalRoutes, {
36
39
  createComponent: scaffolderPlugin.routes.root,
@@ -68,7 +71,9 @@ const routes = (
68
71
  element={<TechRadarPage width={1500} height={800} />}
69
72
  />
70
73
  <Route path="/catalog-import" element={<CatalogImportPage />} />
71
- <Route path="/search" element={<SearchPage />} />
74
+ <Route path="/search" element={<SearchPage />}>
75
+ {searchPage}
76
+ </Route>
72
77
  <Route path="/settings" element={<UserSettingsPage />} />
73
78
  </FlatRoutes>
74
79
  );
@@ -82,8 +82,8 @@ const cicdContent = (
82
82
  </EntitySwitch>
83
83
  );
84
84
 
85
- const overviewContent = (
86
- <Grid container spacing={3} alignItems="stretch">
85
+ const entityWarningContent = (
86
+ <>
87
87
  <EntitySwitch>
88
88
  <EntitySwitch.Case if={isOrphan}>
89
89
  <Grid item xs={12}>
@@ -99,7 +99,12 @@ const overviewContent = (
99
99
  </Grid>
100
100
  </EntitySwitch.Case>
101
101
  </EntitySwitch>
102
+ </>
103
+ );
102
104
 
105
+ const overviewContent = (
106
+ <Grid container spacing={3} alignItems="stretch">
107
+ {entityWarningContent}
103
108
  <Grid item md={6}>
104
109
  <EntityAboutCard variant="gridItem" />
105
110
  </Grid>
@@ -214,9 +219,13 @@ const apiPage = (
214
219
  <EntityLayout>
215
220
  <EntityLayout.Route path="/" title="Overview">
216
221
  <Grid container spacing={3}>
222
+ {entityWarningContent}
217
223
  <Grid item md={6}>
218
224
  <EntityAboutCard />
219
225
  </Grid>
226
+ <Grid item md={4} xs={12}>
227
+ <EntityLinksCard />
228
+ </Grid>
220
229
  <Grid container item md={12}>
221
230
  <Grid item md={6}>
222
231
  <EntityProvidingComponentsCard />
@@ -242,6 +251,7 @@ const userPage = (
242
251
  <EntityLayout>
243
252
  <EntityLayout.Route path="/" title="Overview">
244
253
  <Grid container spacing={3}>
254
+ {entityWarningContent}
245
255
  <Grid item xs={12} md={6}>
246
256
  <EntityUserProfileCard variant="gridItem" />
247
257
  </Grid>
@@ -257,6 +267,7 @@ const groupPage = (
257
267
  <EntityLayout>
258
268
  <EntityLayout.Route path="/" title="Overview">
259
269
  <Grid container spacing={3}>
270
+ {entityWarningContent}
260
271
  <Grid item xs={12} md={6}>
261
272
  <EntityGroupProfileCard variant="gridItem" />
262
273
  </Grid>
@@ -275,6 +286,7 @@ const systemPage = (
275
286
  <EntityLayout>
276
287
  <EntityLayout.Route path="/" title="Overview">
277
288
  <Grid container spacing={3} alignItems="stretch">
289
+ {entityWarningContent}
278
290
  <Grid item md={6}>
279
291
  <EntityAboutCard variant="gridItem" />
280
292
  </Grid>
@@ -299,6 +311,7 @@ const domainPage = (
299
311
  <EntityLayout>
300
312
  <EntityLayout.Route path="/" title="Overview">
301
313
  <Grid container spacing={3} alignItems="stretch">
314
+ {entityWarningContent}
302
315
  <Grid item md={6}>
303
316
  <EntityAboutCard variant="gridItem" />
304
317
  </Grid>
@@ -1,7 +1,4 @@
1
- import {
2
- DockerContainerRunner,
3
- SingleHostDiscovery,
4
- } from '@backstage/backend-common';
1
+ import { DockerContainerRunner } from '@backstage/backend-common';
5
2
  import { CatalogClient } from '@backstage/catalog-client';
6
3
  import { createRouter } from '@backstage/plugin-scaffolder-backend';
7
4
  import Docker from 'dockerode';
@@ -13,11 +10,10 @@ export default async function createPlugin({
13
10
  config,
14
11
  database,
15
12
  reader,
13
+ discovery,
16
14
  }: PluginEnvironment): Promise<Router> {
17
15
  const dockerClient = new Docker();
18
16
  const containerRunner = new DockerContainerRunner({ dockerClient });
19
-
20
- const discovery = SingleHostDiscovery.fromConfig(config);
21
17
  const catalogClient = new CatalogClient({ discoveryApi: discovery });
22
18
 
23
19
  return await createRouter({
@@ -10,6 +10,7 @@ import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
10
10
  export default async function createPlugin({
11
11
  logger,
12
12
  discovery,
13
+ config,
13
14
  }: PluginEnvironment) {
14
15
  // Initialize a connection to a search engine.
15
16
  const searchEngine = new LunrSearchEngine({ logger });
@@ -19,7 +20,7 @@ export default async function createPlugin({
19
20
  // particular collator gathers entities from the software catalog.
20
21
  indexBuilder.addCollator({
21
22
  defaultRefreshIntervalSeconds: 600,
22
- collator: new DefaultCatalogCollator({ discovery }),
23
+ collator: DefaultCatalogCollator.fromConfig(config, { discovery }),
23
24
  });
24
25
 
25
26
  // The scheduler controls when documents are gathered from collators and sent