@techdocs/cli 1.11.5-next.1 → 1.12.0

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.
Files changed (102) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/commands/generate/generate.cjs.js +32 -2
  3. package/dist/commands/generate/generate.cjs.js.map +1 -1
  4. package/dist/commands/index.cjs.js +9 -1
  5. package/dist/commands/index.cjs.js.map +1 -1
  6. package/dist/commands/publish/publish.cjs.js +47 -0
  7. package/dist/commands/publish/publish.cjs.js.map +1 -1
  8. package/dist/embedded-app/.config-schema.json +51 -46
  9. package/dist/embedded-app/index.html +1 -1
  10. package/dist/embedded-app/index.html.tmpl +1 -1
  11. package/dist/embedded-app/static/123.91ba1b809deb.chunk.js +2 -0
  12. package/dist/embedded-app/static/123.91ba1b809deb.chunk.js.map +1 -0
  13. package/dist/embedded-app/static/1659.a99e4eb674e0.chunk.js +2 -0
  14. package/dist/embedded-app/static/1659.a99e4eb674e0.chunk.js.map +1 -0
  15. package/dist/embedded-app/static/1749.99ba95728e00.chunk.js +2 -0
  16. package/dist/embedded-app/static/1749.99ba95728e00.chunk.js.map +1 -0
  17. package/dist/embedded-app/static/1994.7736057c2e9f.chunk.js +2 -0
  18. package/dist/embedded-app/static/1994.7736057c2e9f.chunk.js.map +1 -0
  19. package/dist/embedded-app/static/{2055.fd3ccf91ac47.chunk.js → 2055.d938e6121e5f.chunk.js} +4 -4
  20. package/dist/embedded-app/static/2055.d938e6121e5f.chunk.js.map +1 -0
  21. package/dist/embedded-app/static/{2295.e8be8ba6c18d.chunk.js → 2295.aaedbca4c1c5.chunk.js} +2 -2
  22. package/dist/embedded-app/static/2295.aaedbca4c1c5.chunk.js.map +1 -0
  23. package/dist/embedded-app/static/2360.806f2e1ab212.chunk.js +2 -0
  24. package/dist/embedded-app/static/2360.806f2e1ab212.chunk.js.map +1 -0
  25. package/dist/embedded-app/static/3554.78dd0c182f6c.chunk.js +2 -0
  26. package/dist/embedded-app/static/3554.78dd0c182f6c.chunk.js.map +1 -0
  27. package/dist/embedded-app/static/4587.d1220800a7d6.chunk.js +2 -0
  28. package/dist/embedded-app/static/4587.d1220800a7d6.chunk.js.map +1 -0
  29. package/dist/embedded-app/static/4591.d741c025cb8a.chunk.js +2 -0
  30. package/dist/embedded-app/static/4591.d741c025cb8a.chunk.js.map +1 -0
  31. package/dist/embedded-app/static/4609.b1c67dc7cac2.chunk.js +531 -0
  32. package/dist/embedded-app/static/4609.b1c67dc7cac2.chunk.js.map +1 -0
  33. package/dist/embedded-app/static/4648.cd5b8df48435.chunk.js +2 -0
  34. package/dist/embedded-app/static/4648.cd5b8df48435.chunk.js.map +1 -0
  35. package/dist/embedded-app/static/6138.f15d6245c80d.chunk.js +2 -0
  36. package/dist/embedded-app/static/6138.f15d6245c80d.chunk.js.map +1 -0
  37. package/dist/embedded-app/static/6206.3e7f13e11c59.chunk.js +2 -0
  38. package/dist/embedded-app/static/6206.3e7f13e11c59.chunk.js.map +1 -0
  39. package/dist/embedded-app/static/6949.beeb90ede97f.chunk.js +4 -0
  40. package/dist/embedded-app/static/6949.beeb90ede97f.chunk.js.map +1 -0
  41. package/dist/embedded-app/static/7203.8b3d94b34b16.chunk.js +2 -0
  42. package/dist/embedded-app/static/7203.8b3d94b34b16.chunk.js.map +1 -0
  43. package/dist/embedded-app/static/8877.ab3d98868650.chunk.js +2 -0
  44. package/dist/embedded-app/static/8877.ab3d98868650.chunk.js.map +1 -0
  45. package/dist/embedded-app/static/9050.bd63e0a33f06.chunk.js +2 -0
  46. package/dist/embedded-app/static/9050.bd63e0a33f06.chunk.js.map +1 -0
  47. package/dist/embedded-app/static/9230.422824f655e0.chunk.js +2 -0
  48. package/dist/embedded-app/static/9230.422824f655e0.chunk.js.map +1 -0
  49. package/dist/embedded-app/static/main.9b48363c4ffa.js +2 -0
  50. package/dist/embedded-app/static/main.9b48363c4ffa.js.map +1 -0
  51. package/dist/embedded-app/static/module-remix-run.32d1d7665115.js +2 -0
  52. package/dist/embedded-app/static/module-remix-run.32d1d7665115.js.map +1 -0
  53. package/dist/embedded-app/static/{runtime.c8854f4ed6f8.js → runtime.720cb48cd7ae.js} +2 -2
  54. package/dist/embedded-app/static/{runtime.c8854f4ed6f8.js.map → runtime.720cb48cd7ae.js.map} +1 -1
  55. package/dist/embedded-app/static/vendor.470d3e8ecef1.js +2 -0
  56. package/dist/embedded-app/static/vendor.470d3e8ecef1.js.map +1 -0
  57. package/dist/lib/etag.cjs.js +40 -0
  58. package/dist/lib/etag.cjs.js.map +1 -0
  59. package/dist/package.json.cjs.js +1 -1
  60. package/package.json +8 -7
  61. package/dist/embedded-app/static/123.449f4a83fd2b.chunk.js +0 -2
  62. package/dist/embedded-app/static/123.449f4a83fd2b.chunk.js.map +0 -1
  63. package/dist/embedded-app/static/1659.41bf35e59592.chunk.js +0 -2
  64. package/dist/embedded-app/static/1659.41bf35e59592.chunk.js.map +0 -1
  65. package/dist/embedded-app/static/1749.75c83d8a41f6.chunk.js +0 -2
  66. package/dist/embedded-app/static/1749.75c83d8a41f6.chunk.js.map +0 -1
  67. package/dist/embedded-app/static/1994.78042a47b6c6.chunk.js +0 -2
  68. package/dist/embedded-app/static/1994.78042a47b6c6.chunk.js.map +0 -1
  69. package/dist/embedded-app/static/2055.fd3ccf91ac47.chunk.js.map +0 -1
  70. package/dist/embedded-app/static/2295.e8be8ba6c18d.chunk.js.map +0 -1
  71. package/dist/embedded-app/static/2360.82e9c38bff17.chunk.js +0 -2
  72. package/dist/embedded-app/static/2360.82e9c38bff17.chunk.js.map +0 -1
  73. package/dist/embedded-app/static/3554.bb882f8e4aea.chunk.js +0 -2
  74. package/dist/embedded-app/static/3554.bb882f8e4aea.chunk.js.map +0 -1
  75. package/dist/embedded-app/static/4587.96f03715ec4f.chunk.js +0 -2
  76. package/dist/embedded-app/static/4587.96f03715ec4f.chunk.js.map +0 -1
  77. package/dist/embedded-app/static/4591.5563e3a7aea4.chunk.js +0 -2
  78. package/dist/embedded-app/static/4591.5563e3a7aea4.chunk.js.map +0 -1
  79. package/dist/embedded-app/static/4609.152f14ef4904.chunk.js +0 -531
  80. package/dist/embedded-app/static/4609.152f14ef4904.chunk.js.map +0 -1
  81. package/dist/embedded-app/static/4648.c047b78345c6.chunk.js +0 -2
  82. package/dist/embedded-app/static/4648.c047b78345c6.chunk.js.map +0 -1
  83. package/dist/embedded-app/static/6138.113ed7a1d8cd.chunk.js +0 -2
  84. package/dist/embedded-app/static/6138.113ed7a1d8cd.chunk.js.map +0 -1
  85. package/dist/embedded-app/static/6206.b2713857572e.chunk.js +0 -2
  86. package/dist/embedded-app/static/6206.b2713857572e.chunk.js.map +0 -1
  87. package/dist/embedded-app/static/6949.62c7fa0aab7f.chunk.js +0 -4
  88. package/dist/embedded-app/static/6949.62c7fa0aab7f.chunk.js.map +0 -1
  89. package/dist/embedded-app/static/7203.6e3ffa800885.chunk.js +0 -2
  90. package/dist/embedded-app/static/7203.6e3ffa800885.chunk.js.map +0 -1
  91. package/dist/embedded-app/static/8877.58093d2c2ba0.chunk.js +0 -2
  92. package/dist/embedded-app/static/8877.58093d2c2ba0.chunk.js.map +0 -1
  93. package/dist/embedded-app/static/9050.0c0d51ee0fd8.chunk.js +0 -2
  94. package/dist/embedded-app/static/9050.0c0d51ee0fd8.chunk.js.map +0 -1
  95. package/dist/embedded-app/static/9230.ba752de28896.chunk.js +0 -2
  96. package/dist/embedded-app/static/9230.ba752de28896.chunk.js.map +0 -1
  97. package/dist/embedded-app/static/main.82ddbc06e504.js +0 -2
  98. package/dist/embedded-app/static/main.82ddbc06e504.js.map +0 -1
  99. package/dist/embedded-app/static/module-remix-run.0c80eb31316a.js +0 -2
  100. package/dist/embedded-app/static/module-remix-run.0c80eb31316a.js.map +0 -1
  101. package/dist/embedded-app/static/vendor.3bc2778face5.js +0 -2
  102. package/dist/embedded-app/static/vendor.3bc2778face5.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/4609.152f14ef4904.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/getAjv.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/createCatalogModelLayer.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/util.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/validateMetaSchema.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/zod.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/reduceKindSchema.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/validateKindRootSchemaSemantics.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareRelation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateRelation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/types.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/createCatalogModelLayerBuilder.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addRelationPair.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateRelationPair.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/kinds/relations.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/EmptyState/EmptyStateImage.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/EmptyState/EmptyState.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/FavoriteToggle/FavoriteToggle.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/LinkButton/LinkButton.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/ClosedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/static/OpenedDropdown.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Select/Select.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/SupportButton/SupportButton.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Filters.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/TableLoadingBody.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/Table.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/Breadcrumbs/Breadcrumbs.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/Content/Content.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/ContentHeader/ContentHeader.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/Header/Header.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/HeaderLabel/HeaderLabel.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/Page/Page.tsx","webpack://techdocs-cli-embedded-app/../core-plugin-api/src/routing/useRouteRefParams.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/ButtonLink/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/ButtonLink/ButtonLink.module.css?c85f","webpack://techdocs-cli-embedded-app/../ui/src/components/ButtonLink/ButtonLink.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/Card.module.css?7524","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/Card.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Container/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Container/Container.module.css?2792","webpack://techdocs-cli-embedded-app/../ui/src/components/Container/Container.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/HeaderNav.module.css?6c03","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/HeaderNavDefinition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/HeaderNavIndicators.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/HeaderNav.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/Header.module.css?58b2","webpack://techdocs-cli-embedded-app/../ui/src/components/Header/Header.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/apis/EntityPresentationApi/entityPresentationSnapshot.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogAutocomplete/CatalogAutocomplete.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/VirtualizedListbox.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFetchEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useQueryEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useOwnedEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useAllEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/UserListPicker/useStarredEntitiesCount.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/filters.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityListProvider.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useStarredEntities.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/utils/filters.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/utils/getEntityRelations.ts","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/api.ts","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/context/SearchContext.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs-react/src/component.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/plugin.ts","webpack://techdocs-cli-embedded-app/../core-plugin-api/src/plugin/Plugin.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/EntityPageDocs.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/search/hooks/useTechDocsLocation.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/Router.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/SearchAutocomplete/SearchAutocomplete.module.css?2378","webpack://techdocs-cli-embedded-app/../ui/src/components/SearchAutocomplete/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/SearchAutocomplete/SearchAutocomplete.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderSearch.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderHeader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderEntityCard.module.css?87f2","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderEntityCard.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderContent.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderLayout.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/alpha/components/TechDocsReaderPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/helpers.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/DocsTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/OffsetPaginatedDocsTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/CursorPaginatedDocsTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/EntityListDocsTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/actions.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/Table/SubvalueCell.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/columns.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/Tables/helpers.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/DefaultTechDocsHome.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/TechDocsIndexPage.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/layout/Page/PageWithHeader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/TechDocsPageWrapper.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/home/components/TechDocsPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/renderReactElement.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/hooks/links.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/utils.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/hooks/metatags.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/hooks/attributes.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/layout.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/palette.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/rules.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/variables.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/reset.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/animations.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/rules/extensions.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/transformer.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/addBaseUrl.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/rewriteDocLinks.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsRedirectNotification/TechDocsRedirectNotification.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/copyToClipboard.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/onCssReady.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/hooks/useTechDocsReaderContentData.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/transformer.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/styles/transformer.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/html/hooks/iframes.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/addSidebarToggle.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/removeMkdocsHeader.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/simplifyMkdocsFooter.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/handleMetaRedirects.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/scrollIntoNavigation.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/addLinkClickListener.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/transformers/addNavLinkKeyboardToggle.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/hooks/useTechDocsReaderHeaderData.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/hooks/useTechDocsSearch.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/auth-react/src/components/CookieAuthRefreshProvider/CookieAuthRefreshProvider.tsx","webpack://techdocs-cli-embedded-app/../../plugins/auth-react/src/hooks/useCookieAuthRefresh/useCookieAuthRefresh.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPage/useExternalRedirect.ts","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.tsx","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/translation.ts","webpack://techdocs-cli-embedded-app/../../plugins/search-react/src/components/SearchBar/SearchBar.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/search/components/TechDocsSearch.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/useReaderState.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderProvider.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/LogViewer/LogViewer.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsBuildLogs.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsNotFound.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsStateIndicator.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 Ajv from 'ajv';\nimport ajvErrors from 'ajv-errors';\n\n/**\n * Gets a singleton instance of Ajv.\n */\nexport const getAjv = (() => {\n let instance: Ajv | undefined = undefined;\n\n return () => {\n if (!instance) {\n instance = new Ajv({\n allowUnionTypes: true,\n allErrors: true,\n validateSchema: true,\n });\n ajvErrors(instance);\n }\n return instance;\n };\n})();\n","/*\n * Copyright 2026 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 CatalogModelLayerBuilder,\n createCatalogModelLayerBuilder,\n} from './createCatalogModelLayerBuilder';\nimport { CatalogModelLayer } from './types';\n\n/**\n * Creates a catalog model layer using a builder pattern.\n *\n * @alpha\n * @remarks\n *\n * Plugins can create such catalog model layers to declare various\n * contributions to the overall catalog model, and registering them with the\n * catalog which then forms a complete picture out of them.\n */\nexport function createCatalogModelLayer(options: {\n /**\n * The unique ID of the model layer.\n *\n * @remarks\n * @example `example.com/MyCustomKind`\n *\n * This identifier is used for purposes of deduplication and tracking. It is\n * expected to be stable and descriptive. Prefer prefixing the ID with a\n * matching domain name. The backstage.io domain name is reserved for use by\n * the Backstage project itself.\n */\n layerId: string;\n builder: (model: CatalogModelLayerBuilder) => void;\n}): CatalogModelLayer {\n const b = createCatalogModelLayerBuilder({\n layerId: options.layerId,\n });\n options.builder(b);\n return b.build();\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\n\n/**\n * Asserts that the value is a JSON object shallowly.\n */\nexport function isJsonObject(value?: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Asserts that the value is a JSON object recursively containing only JSON safe\n * values and no circular references.\n */\nexport function isJsonObjectDeep(value: unknown): value is JsonObject {\n if (!isJsonObject(value)) {\n return false;\n }\n const seen = new Set<unknown>();\n return Object.values(value).every(v => isJsonValueDeep(v, seen));\n}\n\nfunction isJsonValueDeep(value: unknown, seen: Set<unknown>): boolean {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n if (typeof value !== 'object') {\n return false;\n }\n if (seen.has(value)) {\n return false;\n }\n seen.add(value);\n if (Array.isArray(value)) {\n return value.every(v => isJsonValueDeep(v, seen));\n }\n if (isJsonObject(value)) {\n return Object.values(value).every(v => isJsonValueDeep(v, seen));\n }\n return false;\n}\n","/*\n * Copyright 2026 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 { type SchemaObject } from 'ajv';\nimport { isJsonObject } from './util';\nimport { InputError } from '@backstage/errors';\nimport { getAjv } from './getAjv';\n\n/**\n * Validates that the schema is valid according to known JSON Schema meta\n * schemas - does not perform any semantic validation beyond that.\n */\nexport function validateMetaSchema(schema: unknown): schema is SchemaObject {\n if (!isJsonObject(schema) || typeof schema.then === 'function') {\n throw new InputError('Invalid JSON schema: must be an object');\n }\n\n const ajv = getAjv();\n try {\n const result = ajv.validateSchema(schema);\n if (typeof result !== 'boolean') {\n // Should not happen; the function is expected to return a promise only\n // for async schemas, but since that's not enforced at the typescript\n // level we add the extra check just to be sure\n throw new InputError('Expected synchronous validation result');\n }\n } catch (error) {\n throw new InputError(`Invalid JSON schema: ${error}`);\n }\n\n // The full set of errors is typically too complex to report; just pick the\n // first one.\n const error = ajv.errors?.[0];\n if (error) {\n let message = error.message;\n if (Array.isArray(error?.params?.allowedValues)) {\n message += `, expected one of: ${error.params.allowedValues.join(', ')}`;\n }\n throw new InputError(\n `Invalid JSON schema, error at path ${error.instancePath}: ${message}`,\n );\n }\n\n return true;\n}\n","/*\n * Copyright 2026 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 { isError } from '@backstage/errors';\nimport { JsonObject } from '@backstage/types';\nimport { z } from 'zod/v3';\nimport { isJsonObjectDeep } from './util';\nimport { validateMetaSchema } from './validateMetaSchema';\n\nexport const jsonObjectSchema = z\n .record(z.string(), z.unknown())\n .refine((x): x is JsonObject => isJsonObjectDeep(x), {\n message: 'Invalid JSON schema',\n });\n\nexport const jsonSchemaSchema = z\n .record(z.string(), z.unknown())\n .superRefine((x, ctx): x is JsonObject => {\n try {\n return validateMetaSchema(x);\n } catch (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: isError(error) ? error.message : 'Invalid JSON schema',\n });\n return false;\n }\n });\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Declare the existence of a well-known annotation and its properties.\n */\nexport const opDeclareAnnotationV1Schema = z.strictObject({\n op: z.literal('declareAnnotation.v1'),\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this annotation.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the annotation.\n */\n description: z.string(),\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opDeclareAnnotationV1Schema} */\nexport type OpDeclareAnnotationV1 = z.infer<typeof opDeclareAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareAnnotationV1}.\n */\nexport function createDeclareAnnotationOp(\n input: Omit<OpDeclareAnnotationV1, 'op'> & { op?: never },\n): OpDeclareAnnotationV1 {\n return opDeclareAnnotationV1Schema.parse({\n ...input,\n op: 'declareAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain kind.\n */\nexport const opDeclareKindV1Schema = z.strictObject({\n op: z.literal('declareKind.v1'),\n\n /**\n * The kind to declare, e.g. \"Component\".\n */\n kind: z.string(),\n /**\n * The apiVersion group of the kind, e.g. \"backstage.io\".\n */\n group: z.string(),\n\n /**\n * Properties that apply for this kind\n */\n properties: z.strictObject({\n /**\n * The singular form of the human-readable kind, e.g. \"component\".\n */\n singular: z.string(),\n /**\n * The plural form of the human-readable kind, e.g. \"components\".\n */\n plural: z.string(),\n /**\n * Short description of the kind.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareKindV1Schema} */\nexport type OpDeclareKindV1 = z.infer<typeof opDeclareKindV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareKindV1}.\n */\nexport function createDeclareKindOp(\n input: Omit<OpDeclareKindV1, 'op'> & { op?: never },\n): OpDeclareKindV1 {\n return opDeclareKindV1Schema.parse({ ...input, op: 'declareKind.v1' });\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { z } from 'zod/v3';\nimport { CatalogModelKindRootSchema } from './validateKindRootSchemaSemantics';\n\n/**\n * The expected shape of the standard full kind schemas, which use an allOf\n * with a $ref to Entity and a second element with the kind-specific schema.\n */\nconst fullKindSchema = z\n .object({\n allOf: z.tuple([\n z.object({ $ref: z.literal('Entity') }),\n z\n .object({\n type: z.literal('object'),\n properties: z\n .object({\n apiVersion: z.record(z.string(), z.unknown()).optional(),\n kind: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough(),\n })\n .passthrough(),\n ]),\n })\n .passthrough();\n\n/**\n * Reduces a full kind JSON schema to the form expected by the catalog model\n * layer system. The full schemas use an allOf with a $ref to Entity and\n * kind/apiVersion constraints that are not needed in the reduced form.\n *\n * If the schema does not match the expected shape, it is returned unchanged.\n */\nexport function reduceKindSchema(\n schema: JsonObject,\n): CatalogModelKindRootSchema {\n const parsed = fullKindSchema.safeParse(schema);\n if (!parsed.success) {\n return schema as CatalogModelKindRootSchema;\n }\n\n const { allOf, ...rest } = parsed.data;\n const { type, properties: allProperties, ...kindRest } = allOf[1];\n const { apiVersion, kind, ...properties } = allProperties;\n\n return {\n ...rest,\n type,\n ...kindRest,\n properties,\n } as CatalogModelKindRootSchema;\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { isJsonObject, isJsonObjectDeep } from './util';\n\nconst FORBIDDEN_SCHEMA_ROOT_FIELDS = [\n 'kind',\n 'apiVersion',\n 'metadata',\n '$ref',\n] as const;\nconst FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS = [\n 'allOf',\n 'oneOf',\n 'anyOf',\n 'if',\n 'else',\n 'then',\n 'not',\n '$ref',\n] as const;\n\n/**\n * When declaring the JSON schema model for a kind, this is the type that you\n * should abide by.\n *\n * @alpha\n * @remarks\n *\n * It forbids some patterns that would make the schema hard or impossible to\n * inspect / merge properly.\n */\nexport interface CatalogModelKindRootSchema extends JsonObject {\n type: 'object';\n\n // NOTE: These should match the FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS list above\n allOf?: never;\n anyOf?: never;\n oneOf?: never;\n if?: never;\n then?: never;\n else?: never;\n not?: never;\n $ref?: never;\n\n properties?:\n | undefined\n | {\n // NOTE: These should match the FORBIDDEN_SCHEMA_ROOT_FIELDS list above\n kind?: never;\n apiVersion?: never;\n metadata?: never;\n $ref?: never;\n\n [key: string]:\n | undefined\n | {\n // NOTE: These should match the FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS list above\n allOf?: never;\n anyOf?: never;\n oneOf?: never;\n if?: never;\n then?: never;\n else?: never;\n not?: never;\n $ref?: never;\n\n [key: string]: JsonValue | undefined;\n };\n };\n\n [key: string]: JsonValue | undefined;\n}\n\n/**\n * Validates that the semantics of a schema describing a kind follows semantic\n * rules.\n *\n * @remarks\n *\n * It's expected that the input is a valid JSON Schema, as in having been\n * validated by `validateMetaSchema` already.\n *\n * The schema must not try to explicitly declare certain readonly root fields,\n * and neither the root nor the top level keys of fields may use certain\n * structural keywords that makes the schema hard or impossible to inspect /\n * merge properly.\n *\n * @param schema - The schema to validate.\n */\nexport function validateKindRootSchemaSemantics(\n schema: unknown,\n): schema is CatalogModelKindRootSchema {\n if (!isJsonObjectDeep(schema)) {\n throw new InputError('Schema must be an object');\n }\n\n for (const field of FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS) {\n if (field in schema) {\n throw new InputError(\n `Schema must not use \"${field}\" keyword in the root`,\n );\n }\n }\n\n const rootProperties = schema.properties;\n if (!isJsonObject(rootProperties)) {\n throw new InputError(\n 'Schema must have a \"properties\" field that is an object',\n );\n }\n\n for (const field of FORBIDDEN_SCHEMA_ROOT_FIELDS) {\n if (field in rootProperties) {\n throw new InputError(\n `Schema must not try to declare the reserved root field \"${field}\"`,\n );\n }\n }\n\n for (const [fieldName, fieldSchema] of Object.entries(rootProperties)) {\n if (!isJsonObject(fieldSchema)) {\n throw new InputError(\n `Schema for root field \"${fieldName}\" must be an object`,\n );\n }\n for (const field of FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS) {\n if (field in fieldSchema) {\n throw new InputError(\n `Schema for root field \"${fieldName}\" must not use \"${field}\" keyword`,\n );\n }\n }\n }\n\n return true;\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\nconst relationFieldSchema = z.strictObject({\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: z.strictObject({\n /**\n * A dot separated path on the common catalog form, e.g. `spec.owner`.\n */\n path: z.string(),\n }),\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: z.string(),\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind: z.string().optional(),\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace.\n */\n defaultNamespace: z.enum(['default', 'inherit']).optional(),\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified,\n * all kinds are allowed.\n */\n allowedKinds: z.array(z.string()).optional(),\n});\n\n/**\n * Make a declaration about the version of a certain kind.\n */\nexport const opDeclareKindVersionV1Schema = z.strictObject({\n op: z.literal('declareKindVersion.v1'),\n\n /**\n * The kind that this version belongs to.\n */\n kind: z.string(),\n /**\n * The specific version name, e.g. \"v1alpha1\". This and the kind group form\n * the full apiVersion.\n */\n name: z.string(),\n /**\n * The spec type that this version applies to, if any.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that has\n * no type given at all, or to those where the type is not among the set of\n * any other known declared spec types.\n */\n specType: z.string().optional(),\n\n /**\n * The properties that apply to this version.\n */\n properties: z.strictObject({\n /**\n * A short description of this particular version (and type, where applicable).\n */\n description: z.string().optional(),\n\n /**\n * The fields that shall be used to generate relations, if any.\n */\n relationFields: z.array(relationFieldSchema).optional(),\n\n /**\n * The JSON schema of the version.\n */\n schema: z.strictObject({\n jsonSchema: jsonSchemaSchema,\n }),\n }),\n});\n\n/** {@inheritDoc opDeclareKindVersionV1Schema} */\nexport type OpDeclareKindVersionV1 = z.infer<\n typeof opDeclareKindVersionV1Schema\n>;\n\n/**\n * Creates a validated {@link OpDeclareKindVersionV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareKindVersionV1}.\n */\nexport function createDeclareKindVersionOp(\n input: Omit<OpDeclareKindVersionV1, 'op'> & { op?: never },\n): OpDeclareKindVersionV1 {\n return opDeclareKindVersionV1Schema.parse({\n ...input,\n op: 'declareKindVersion.v1',\n });\n}\n","/*\n * Copyright 2026 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 { reduceKindSchema } from '../jsonSchema/reduceKindSchema';\nimport { validateKindRootSchemaSemantics } from '../jsonSchema/validateKindRootSchemaSemantics';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareKindVersionOp } from '../operations/declareKindVersion';\nimport type { CatalogModelKindVersionDefinition } from './addKind';\n\n/**\n * The definition for adding one or more versions to an already-declared kind.\n *\n * @alpha\n */\nexport interface CatalogModelAddKindVersionDefinition {\n /**\n * The kind to add versions to, e.g. \"API\".\n */\n kind: string;\n\n /**\n * The versions to add.\n */\n versions: CatalogModelKindVersionDefinition[];\n}\n\nexport function opsFromCatalogModelAddKindVersion(\n definition: CatalogModelAddKindVersionDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n for (const version of definition.versions) {\n const jsonSchema = reduceKindSchema(version.schema.jsonSchema);\n validateMetaSchema(jsonSchema);\n validateKindRootSchemaSemantics(jsonSchema);\n const names = Array.isArray(version.name) ? version.name : [version.name];\n for (const name of names) {\n const specTypes = version.specType\n ? [version.specType].flat()\n : [undefined];\n for (const specType of specTypes) {\n ops.push(\n createDeclareKindVersionOp({\n kind: definition.kind,\n name,\n specType: specType,\n properties: {\n description: version.description,\n relationFields: version.relationFields,\n schema: {\n jsonSchema: jsonSchema as any,\n },\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Declare the existence of a well-known label and its properties.\n */\nexport const opDeclareLabelV1Schema = z.strictObject({\n op: z.literal('declareLabel.v1'),\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this label.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the label.\n */\n description: z.string(),\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opDeclareLabelV1Schema} */\nexport type OpDeclareLabelV1 = z.infer<typeof opDeclareLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareLabelV1}.\n */\nexport function createDeclareLabelOp(\n input: Omit<OpDeclareLabelV1, 'op'> & { op?: never },\n): OpDeclareLabelV1 {\n return opDeclareLabelV1Schema.parse({\n ...input,\n op: 'declareLabel.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain relation type between a\n * given pair of kinds.\n *\n * @remarks\n *\n * Note that this is NOT the same as declaring that a certain field is a\n * relation type - it declares that IF a relation was generated between two\n * kinds for any reason, then these properties apply to it.\n */\nexport const opDeclareRelationV1Schema = z.strictObject({\n op: z.literal('declareRelation.v1'),\n /**\n * The kind that this relation originates from, e.g. \"Component\".\n */\n fromKind: z.string(),\n /**\n * The technical type of the relation, e.g. \"ownedBy\".\n */\n type: z.string(),\n /**\n * The kind that this relation points to, e.g. \"Group\".\n */\n toKind: z.string(),\n\n /**\n * The properties that apply to this relation.\n */\n properties: z.strictObject({\n /**\n * The technical type of the reverse relation, e.g. \"ownerOf\".\n */\n reverseType: z.string(),\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: z.string(),\n /**\n * A human-readable description of the relation.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareRelationV1Schema} */\nexport type OpDeclareRelationV1 = z.infer<typeof opDeclareRelationV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareRelationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareRelationV1}.\n */\nexport function createDeclareRelationOp(\n input: Omit<OpDeclareRelationV1, 'op'> & { op?: never },\n): OpDeclareRelationV1 {\n return opDeclareRelationV1Schema.parse({\n ...input,\n op: 'declareRelation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove an annotation from the model.\n */\nexport const opRemoveAnnotationV1Schema = z.strictObject({\n op: z.literal('removeAnnotation.v1'),\n\n /**\n * The name of the annotation to remove, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveAnnotationV1Schema} */\nexport type OpRemoveAnnotationV1 = z.infer<typeof opRemoveAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveAnnotationV1}.\n */\nexport function createRemoveAnnotationOp(\n input: Omit<OpRemoveAnnotationV1, 'op'> & { op?: never },\n): OpRemoveAnnotationV1 {\n return opRemoveAnnotationV1Schema.parse({\n ...input,\n op: 'removeAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a kind entirely from the model.\n */\nexport const opRemoveKindV1Schema = z.strictObject({\n op: z.literal('removeKind.v1'),\n\n /**\n * The kind to remove, e.g. \"Component\".\n */\n kind: z.string(),\n});\n\n/** {@inheritDoc opRemoveKindV1Schema} */\nexport type OpRemoveKindV1 = z.infer<typeof opRemoveKindV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveKindV1}.\n */\nexport function createRemoveKindOp(\n input: Omit<OpRemoveKindV1, 'op'> & { op?: never },\n): OpRemoveKindV1 {\n return opRemoveKindV1Schema.parse({ ...input, op: 'removeKind.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a label from the model.\n */\nexport const opRemoveLabelV1Schema = z.strictObject({\n op: z.literal('removeLabel.v1'),\n\n /**\n * The name of the label to remove, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveLabelV1Schema} */\nexport type OpRemoveLabelV1 = z.infer<typeof opRemoveLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveLabelV1}.\n */\nexport function createRemoveLabelOp(\n input: Omit<OpRemoveLabelV1, 'op'> & { op?: never },\n): OpRemoveLabelV1 {\n return opRemoveLabelV1Schema.parse({ ...input, op: 'removeLabel.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a tag from the model.\n */\nexport const opRemoveTagV1Schema = z.strictObject({\n op: z.literal('removeTag.v1'),\n\n /**\n * The name of the tag to remove, e.g. \"java\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveTagV1Schema} */\nexport type OpRemoveTagV1 = z.infer<typeof opRemoveTagV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveTagV1}.\n */\nexport function createRemoveTagOp(\n input: Omit<OpRemoveTagV1, 'op'> & { op?: never },\n): OpRemoveTagV1 {\n return opRemoveTagV1Schema.parse({ ...input, op: 'removeTag.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Declare the existence of a well-known tag and its properties.\n */\nexport const opDeclareTagV1Schema = z.strictObject({\n op: z.literal('declareTag.v1'),\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this tag.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the tag.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareTagV1Schema} */\nexport type OpDeclareTagV1 = z.infer<typeof opDeclareTagV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareTagV1}.\n */\nexport function createDeclareTagOp(\n input: Omit<OpDeclareTagV1, 'op'> & { op?: never },\n): OpDeclareTagV1 {\n return opDeclareTagV1Schema.parse({\n ...input,\n op: 'declareTag.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Update the properties of an existing annotation.\n */\nexport const opUpdateAnnotationV1Schema = z.strictObject({\n op: z.literal('updateAnnotation.v1'),\n\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this annotation.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the annotation.\n */\n description: z.string().optional(),\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateAnnotationV1Schema} */\nexport type OpUpdateAnnotationV1 = z.infer<typeof opUpdateAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateAnnotationV1}.\n */\nexport function createUpdateAnnotationOp(\n input: Omit<OpUpdateAnnotationV1, 'op'> & { op?: never },\n): OpUpdateAnnotationV1 {\n return opUpdateAnnotationV1Schema.parse({\n ...input,\n op: 'updateAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain kind.\n */\nexport const opUpdateKindV1Schema = z.strictObject({\n op: z.literal('updateKind.v1'),\n\n /**\n * The kind to update, e.g. \"Component\".\n */\n kind: z.string(),\n\n /**\n * Updated properties that apply for this kind\n */\n properties: z.strictObject({\n /**\n * The singular form of the human-readable kind, e.g. \"component\".\n */\n singular: z.string().optional(),\n /**\n * The plural form of the human-readable kind, e.g. \"components\".\n */\n plural: z.string().optional(),\n /**\n * Short description of the kind.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateKindV1Schema} */\nexport type OpUpdateKindV1 = z.infer<typeof opUpdateKindV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateKindV1}.\n */\nexport function createUpdateKindOp(\n input: Omit<OpUpdateKindV1, 'op'> & { op?: never },\n): OpUpdateKindV1 {\n return opUpdateKindV1Schema.parse({ ...input, op: 'updateKind.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\nconst relationFieldSchema = z.strictObject({\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: z.strictObject({\n /**\n * A dot separated path on the common catalog form, e.g. `spec.owner`.\n */\n path: z.string(),\n }),\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: z.string(),\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind: z.string().optional(),\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace.\n */\n defaultNamespace: z.enum(['default', 'inherit']).optional(),\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified,\n * all kinds are allowed.\n */\n allowedKinds: z.array(z.string()).optional(),\n});\n\n/**\n * Make an update to a pre-existing version of a certain kind.\n */\nexport const opUpdateKindVersionV1Schema = z.strictObject({\n op: z.literal('updateKindVersion.v1'),\n\n /**\n * The kind that this version belongs to.\n */\n kind: z.string(),\n /**\n * The specific version name, e.g. \"v1alpha1\". This and the kind group form\n * the full apiVersion.\n */\n name: z.string(),\n /**\n * The spec type that this version applies to, if any.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that has\n * no type given at all, or to those where the type is not among the set of\n * any other known declared spec types.\n */\n specType: z.string().optional(),\n\n /**\n * The properties that apply to this version update.\n */\n properties: z.strictObject({\n /**\n * A short description of this particular version (and type, where\n * applicable). Specify this if you want to override the default value.\n */\n description: z.string().optional(),\n\n /**\n * The fields that shall be used to generate relations, if any. Specify this\n * if you want to override the default value.\n */\n relationFields: z.array(relationFieldSchema).optional(),\n\n /**\n * The JSON schema of the version. Specify this if you want to override the\n * default value.\n *\n * @remarks\n *\n * This schema gets deep merged with the default one for this version. It\n * can therefore be used for both amending and changing existing fields.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateKindVersionV1Schema} */\nexport type OpUpdateKindVersionV1 = z.infer<typeof opUpdateKindVersionV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateKindVersionV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateKindVersionV1}.\n */\nexport function createUpdateKindVersionOp(\n input: Omit<OpUpdateKindVersionV1, 'op'> & { op?: never },\n): OpUpdateKindVersionV1 {\n return opUpdateKindVersionV1Schema.parse({\n ...input,\n op: 'updateKindVersion.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Update the properties of an existing label.\n */\nexport const opUpdateLabelV1Schema = z.strictObject({\n op: z.literal('updateLabel.v1'),\n\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this label.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the label.\n */\n description: z.string().optional(),\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateLabelV1Schema} */\nexport type OpUpdateLabelV1 = z.infer<typeof opUpdateLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateLabelV1}.\n */\nexport function createUpdateLabelOp(\n input: Omit<OpUpdateLabelV1, 'op'> & { op?: never },\n): OpUpdateLabelV1 {\n return opUpdateLabelV1Schema.parse({\n ...input,\n op: 'updateLabel.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Update the properties of a certain relation type between a given pair of\n * kinds.\n *\n * @remarks\n *\n * Note that this is NOT the same as updating the properties of a certain field\n * that is a relation type - it updates the properties of a relation that was\n * generated between two kinds for any reason.\n */\nexport const opUpdateRelationV1Schema = z.strictObject({\n op: z.literal('updateRelation.v1'),\n\n /**\n * The kind that this relation originates from, e.g. \"Component\".\n */\n fromKind: z.string(),\n /**\n * The technical type of the relation, e.g. \"ownedBy\".\n */\n type: z.string(),\n /**\n * The kind that this relation points to, e.g. \"Group\".\n */\n toKind: z.string(),\n\n /**\n * The properties that apply to this relation.\n */\n properties: z.strictObject({\n /**\n * The technical type of the reverse relation, e.g. \"ownerOf\".\n */\n reverseType: z.string().optional(),\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the relation.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateRelationV1Schema} */\nexport type OpUpdateRelationV1 = z.infer<typeof opUpdateRelationV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateRelationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateRelationV1}.\n */\nexport function createUpdateRelationOp(\n input: Omit<OpUpdateRelationV1, 'op'> & { op?: never },\n): OpUpdateRelationV1 {\n return opUpdateRelationV1Schema.parse({\n ...input,\n op: 'updateRelation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Update the properties of an existing tag.\n */\nexport const opUpdateTagV1Schema = z.strictObject({\n op: z.literal('updateTag.v1'),\n\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this tag.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the tag.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateTagV1Schema} */\nexport type OpUpdateTagV1 = z.infer<typeof opUpdateTagV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateTagV1}.\n */\nexport function createUpdateTagOp(\n input: Omit<OpUpdateTagV1, 'op'> & { op?: never },\n): OpUpdateTagV1 {\n return opUpdateTagV1Schema.parse({ ...input, op: 'updateTag.v1' });\n}\n","/*\n * Copyright 2026 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 { OpaqueType } from '@internal/opaque';\nimport { CatalogModelOp } from './operations';\nimport { JsonObject } from '@backstage/types';\n\n// #region CatalogModelLayer\n\n/**\n * An opaque type that represents a set of catalog model layers.\n *\n * @alpha\n */\nexport interface CatalogModelLayer {\n readonly $$type: '@backstage/CatalogModelLayer';\n /**\n * The unique ID of the model layer.\n *\n * @remarks\n * @example `catalog.backstage.io/kind-api`\n *\n * This identifier is used for purposes of deduplication and tracking. It is\n * expected to be stable and descriptive. Prefer prefixing the ID with a\n * matching domain name. The backstage.io domain name is reserved for use by\n * the Backstage project itself.\n */\n readonly layerId: string;\n}\n\n/**\n * The opaque type that represents a catalog model layer.\n *\n * @internal\n * @remarks\n *\n * Model layers are essentially an array of operations. Several such model\n * layers are merged together to form a final outcome.\n */\nexport const OpaqueCatalogModelLayer = OpaqueType.create<{\n public: CatalogModelLayer;\n versions: {\n readonly version: 'v1';\n readonly layerId: string;\n readonly ops: Array<CatalogModelOp>;\n };\n}>({\n type: '@backstage/CatalogModelLayer',\n versions: ['v1'],\n});\n\n// #endregion\n\n// #region CatalogModel\n\n/**\n * A compiled catalog model.\n *\n * @alpha\n */\nexport interface CatalogModel {\n /**\n * Lists all kinds in the model.\n */\n listKinds(): CatalogModelKindSummary[];\n\n /**\n * Lists all relations in the model.\n */\n listRelations(): CatalogModelRelationSummary[];\n\n /**\n * Returns summaries of the shared metadata fields in the model, including\n * all declared annotations, labels, and tags.\n */\n getMetadata(): {\n annotations: CatalogModelAnnotationSummary[];\n labels: CatalogModelLabelSummary[];\n tags: CatalogModelTagSummary[];\n };\n\n /**\n * Look up a kind in the model.\n *\n * @returns The kind if found, or `undefined` if no matching kind exists.\n * @throws TypeError if the kind exists in the model, but not for this apiVersion or type.\n */\n getKind(options: {\n kind: string;\n apiVersion: string;\n spec?: { type?: string };\n }): CatalogModelKind | undefined;\n\n /**\n * Look up all relations that originate from a given kind.\n *\n * @param kind - The kind name, e.g. \"Component\".\n * @returns The relations originating from the kind, or `undefined` if the\n * kind is not known.\n */\n getRelations(options: { kind: string }): CatalogModelRelation[] | undefined;\n}\n\n// #endregion\n\n// #region CatalogModelKind\n\n/**\n * A compiled catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelKind {\n /**\n * A human-readable description of the kind.\n */\n description: string;\n\n /**\n * The API version(s) of the kind that this schema applies to, e.g.\n * \"backstage.io/v1alpha1\".\n */\n apiVersions: string[];\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * The relation fields declared for this kind, with full dot-separated paths\n * into the entity (e.g. \"spec.owner\").\n */\n relationFields: Array<{\n /**\n * The full dot-separated path to the field in the entity, e.g. \"spec.owner\".\n */\n path: string;\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: string;\n /**\n * The default kind for parsing shorthand entity refs.\n */\n defaultKind?: string;\n /**\n * The default namespace for parsing shorthand entity refs.\n */\n defaultNamespace?: 'inherit' | 'default';\n /**\n * The kinds that are allowed as targets for this relation field.\n */\n allowedKinds?: string[];\n }>;\n\n /**\n * The JSON schema of the kind.\n *\n * @remarks\n *\n * This can be used for validation of entities. Note that it is up to the\n * caller to ensure that the kind and apiVersion match what you are validating\n * against.\n */\n jsonSchema: JsonObject;\n}\n\n// #endregion\n\n// #region CatalogModelKindSummary\n\n/**\n * A summary of a catalog model kind, without version-specific details such as\n * schemas and relation fields.\n *\n * @alpha\n */\nexport interface CatalogModelKindSummary {\n /**\n * A human-readable description of the kind.\n */\n description: string;\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * The available versions and spec types for this kind.\n *\n * @remarks\n *\n * Each entry represents a unique apiVersion/specType combination that can be\n * passed to {@link CatalogModel.getKind} to retrieve the full kind details.\n */\n versions: Array<{\n /**\n * The API version, e.g. \"backstage.io/v1alpha1\".\n */\n apiVersion: string;\n /**\n * The spec type, if any, e.g. \"service\". Undefined means the default\n * (untyped) version.\n */\n specType?: string;\n }>;\n}\n\n// #endregion\n\n// #region CatalogModelRelation\n\n/**\n * A compiled catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelation {\n /**\n * The kinds that this relation can originate from.\n */\n fromKind: string[];\n /**\n * The kinds that this relation can point to.\n */\n toKind: string[];\n /**\n * A human-readable description of the relation.\n */\n description: string;\n /**\n * The forward direction of this relation.\n */\n forward: {\n type: string;\n title: string;\n };\n /**\n * The reverse direction of this relation.\n */\n reverse: {\n type: string;\n title: string;\n };\n}\n\n// #endregion\n\n// #region CatalogModelAnnotationSummary\n\n/**\n * A summary of a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelAnnotationSummary {\n /**\n * The annotation key, e.g. \"backstage.io/managed-by-location\".\n */\n name: string;\n /**\n * A short human-readable title for the annotation.\n */\n title?: string;\n /**\n * A human-readable description of the annotation.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelLabelSummary\n\n/**\n * A summary of a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelLabelSummary {\n /**\n * The label key, e.g. \"backstage.io/orphan\".\n */\n name: string;\n /**\n * A short human-readable title for the label.\n */\n title?: string;\n /**\n * A human-readable description of the label.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelTagSummary\n\n/**\n * A summary of a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelTagSummary {\n /**\n * The tag value, e.g. \"java\".\n */\n name: string;\n /**\n * A short human-readable title for the tag.\n */\n title?: string;\n /**\n * A human-readable description of the tag.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelRelationSummary\n\n/**\n * A summary of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelationSummary {\n /**\n * The kinds that this relation can originate from.\n */\n fromKind: string[];\n /**\n * The kinds that this relation can point to.\n */\n toKind: string[];\n /**\n * A human-readable description of the relation.\n */\n description: string;\n /**\n * The forward direction of this relation.\n */\n forward: {\n type: string;\n title: string;\n };\n /**\n * The reverse direction of this relation.\n */\n reverse: {\n type: string;\n title: string;\n };\n}\n\n// #endregion\n","/*\n * Copyright 2026 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 type CatalogModelAnnotationDefinition,\n opsFromCatalogModelAnnotation,\n} from './modelActions/addAnnotation';\nimport {\n type CatalogModelKindDefinition,\n opsFromCatalogModelKind,\n} from './modelActions/addKind';\nimport {\n type CatalogModelAddKindVersionDefinition,\n opsFromCatalogModelAddKindVersion,\n} from './modelActions/addKindVersion';\nimport {\n type CatalogModelLabelDefinition,\n opsFromCatalogModelLabel,\n} from './modelActions/addLabel';\nimport {\n type CatalogModelRelationPairDefinition,\n opsFromCatalogModelRelationPair,\n} from './modelActions/addRelationPair';\nimport {\n type CatalogModelRemoveAnnotationDefinition,\n opsFromCatalogModelRemoveAnnotation,\n} from './modelActions/removeAnnotation';\nimport {\n type CatalogModelRemoveKindDefinition,\n opsFromCatalogModelRemoveKind,\n} from './modelActions/removeKind';\nimport {\n type CatalogModelRemoveLabelDefinition,\n opsFromCatalogModelRemoveLabel,\n} from './modelActions/removeLabel';\nimport {\n type CatalogModelRemoveTagDefinition,\n opsFromCatalogModelRemoveTag,\n} from './modelActions/removeTag';\nimport {\n type CatalogModelTagDefinition,\n opsFromCatalogModelTag,\n} from './modelActions/addTag';\nimport {\n type CatalogModelUpdateAnnotationDefinition,\n opsFromCatalogModelUpdateAnnotation,\n} from './modelActions/updateAnnotation';\nimport {\n CatalogModelUpdateKindDefinition,\n opsFromCatalogModelUpdateKind,\n} from './modelActions/updateKind';\nimport {\n type CatalogModelUpdateLabelDefinition,\n opsFromCatalogModelUpdateLabel,\n} from './modelActions/updateLabel';\nimport {\n CatalogModelUpdateRelationPairDefinition,\n opsFromCatalogModelUpdateRelationPair,\n} from './modelActions/updateRelationPair';\nimport {\n type CatalogModelUpdateTagDefinition,\n opsFromCatalogModelUpdateTag,\n} from './modelActions/updateTag';\nimport { CatalogModelOp } from './operations';\nimport { CatalogModelLayer, OpaqueCatalogModelLayer } from './types';\n\n/**\n * A builder for catalog model layers.\n *\n * @alpha\n *\n * Plugins can use this builder to declare various contributions to the overall\n * catalog model, and registering the outcome with the catalog which then forms\n * a complete picture out of them.\n */\nexport interface CatalogModelLayerBuilder {\n /**\n * Adds a new kind to the model.\n */\n addKind(kind: CatalogModelKindDefinition): void;\n /**\n * Adds one or more versions to an already-declared kind.\n */\n addKindVersion(definition: CatalogModelAddKindVersionDefinition): void;\n /**\n * Updates an existing kind in the model.\n */\n updateKind(kind: CatalogModelUpdateKindDefinition): void;\n /**\n * Removes a kind entirely from the model.\n */\n removeKind(kind: CatalogModelRemoveKindDefinition): void;\n\n /**\n * Adds a new relation pair to the model.\n */\n addRelationPair(relation: CatalogModelRelationPairDefinition): void;\n /**\n * Updates an existing relation pair in the model.\n */\n updateRelationPair(relation: CatalogModelUpdateRelationPairDefinition): void;\n\n /**\n * Adds a new annotation to the model.\n */\n addAnnotation(annotation: CatalogModelAnnotationDefinition): void;\n /**\n * Updates an existing annotation in the model.\n */\n updateAnnotation(annotation: CatalogModelUpdateAnnotationDefinition): void;\n /**\n * Removes an annotation from the model.\n */\n removeAnnotation(annotation: CatalogModelRemoveAnnotationDefinition): void;\n\n /**\n * Adds a new label to the model.\n */\n addLabel(label: CatalogModelLabelDefinition): void;\n /**\n * Updates an existing label in the model.\n */\n updateLabel(label: CatalogModelUpdateLabelDefinition): void;\n /**\n * Removes a label from the model.\n */\n removeLabel(label: CatalogModelRemoveLabelDefinition): void;\n\n /**\n * Adds a new tag to the model.\n */\n addTag(tag: CatalogModelTagDefinition): void;\n /**\n * Updates an existing tag in the model.\n */\n updateTag(tag: CatalogModelUpdateTagDefinition): void;\n /**\n * Removes a tag from the model.\n */\n removeTag(tag: CatalogModelRemoveTagDefinition): void;\n\n /**\n * Imports all operations from another catalog model layer into this one.\n */\n import(layer: CatalogModelLayer): void;\n}\n\n/**\n * The default implementation of the catalog model layer builder.\n */\nexport class DefaultCatalogModelLayerBuilder\n implements CatalogModelLayerBuilder\n{\n readonly #layerId: string;\n readonly #ops: CatalogModelOp[];\n\n constructor(options: { layerId: string }) {\n this.#layerId = options.layerId;\n this.#ops = [];\n }\n\n addKind(kind: CatalogModelKindDefinition): void {\n const ops = opsFromCatalogModelKind(kind);\n this.#ops.push(...ops);\n }\n\n addKindVersion(definition: CatalogModelAddKindVersionDefinition): void {\n const ops = opsFromCatalogModelAddKindVersion(definition);\n this.#ops.push(...ops);\n }\n\n updateKind(kind: CatalogModelUpdateKindDefinition): void {\n const ops = opsFromCatalogModelUpdateKind(kind);\n this.#ops.push(...ops);\n }\n\n removeKind(kind: CatalogModelRemoveKindDefinition): void {\n const ops = opsFromCatalogModelRemoveKind(kind);\n this.#ops.push(...ops);\n }\n\n addRelationPair(relation: CatalogModelRelationPairDefinition): void {\n const ops = opsFromCatalogModelRelationPair(relation);\n this.#ops.push(...ops);\n }\n\n updateRelationPair(relation: CatalogModelUpdateRelationPairDefinition): void {\n const ops = opsFromCatalogModelUpdateRelationPair(relation);\n this.#ops.push(...ops);\n }\n\n addAnnotation(annotation: CatalogModelAnnotationDefinition): void {\n const ops = opsFromCatalogModelAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n updateAnnotation(annotation: CatalogModelUpdateAnnotationDefinition): void {\n const ops = opsFromCatalogModelUpdateAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n removeAnnotation(annotation: CatalogModelRemoveAnnotationDefinition): void {\n const ops = opsFromCatalogModelRemoveAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n addLabel(label: CatalogModelLabelDefinition): void {\n const ops = opsFromCatalogModelLabel(label);\n this.#ops.push(...ops);\n }\n\n updateLabel(label: CatalogModelUpdateLabelDefinition): void {\n const ops = opsFromCatalogModelUpdateLabel(label);\n this.#ops.push(...ops);\n }\n\n removeLabel(label: CatalogModelRemoveLabelDefinition): void {\n const ops = opsFromCatalogModelRemoveLabel(label);\n this.#ops.push(...ops);\n }\n\n addTag(tag: CatalogModelTagDefinition): void {\n const ops = opsFromCatalogModelTag(tag);\n this.#ops.push(...ops);\n }\n\n updateTag(tag: CatalogModelUpdateTagDefinition): void {\n const ops = opsFromCatalogModelUpdateTag(tag);\n this.#ops.push(...ops);\n }\n\n removeTag(tag: CatalogModelRemoveTagDefinition): void {\n const ops = opsFromCatalogModelRemoveTag(tag);\n this.#ops.push(...ops);\n }\n\n import(layer: CatalogModelLayer): void {\n const internal = OpaqueCatalogModelLayer.toInternal(layer);\n this.#ops.push(...internal.ops);\n }\n\n build(): CatalogModelLayer {\n return OpaqueCatalogModelLayer.createInstance('v1', {\n layerId: this.#layerId,\n ops: this.#ops.slice(),\n });\n }\n}\n\n/**\n * Creates a builder for a catalog model layer.\n *\n * @alpha\n * @remarks\n *\n * Plugins can use the resulting builder to declare various contributions to the\n * overall catalog model, and registering it with the catalog which then forms a\n * complete picture out of them.\n */\nexport function createCatalogModelLayerBuilder(options: {\n layerId: string;\n}): CatalogModelLayerBuilder & { build(): CatalogModelLayer } {\n return new DefaultCatalogModelLayerBuilder(options);\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareKindOp } from '../operations/declareKind';\nimport { opsFromCatalogModelAddKindVersion } from './addKindVersion';\n\n/**\n * The definition of a catalog model kind, roughly resembling a JSON Schema.\n *\n * @alpha\n */\nexport interface CatalogModelKindDefinition {\n /**\n * The apiVersion group of the kind, e.g. \"backstage.io\".\n */\n group: string;\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * A short description of the kind.\n *\n * @remarks\n *\n * For kinds that have wide applicability over for example several different\n * spec types, this description should be a generic one and the types\n * themselves can be more precise.\n */\n description: string;\n\n /**\n * Declare one or more versions of the kind's actual schema shape.\n */\n versions?: CatalogModelKindVersionDefinition[];\n}\n\n/**\n * The definition of one or more specific versions of a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelKindVersionDefinition {\n /**\n * The specific version name or names, e.g. \"v1alpha1\" or\n * [\"v1alpha1\", \"v1beta1\"]. The kind group and the version name form the\n * full apiVersion, e.g. \"backstage.io/v1alpha1\".\n */\n name: string | string[];\n\n /**\n * The spec type or types that this version applies to.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that\n * has no type given at all, or to those where the type is not among the set\n * of any other known declared spec types.\n *\n * TODO: Should this be more like `matcher: { [path: string]: string }`, or\n * even a full JSON Schema that can be used in an \"if\"?\n */\n specType?: string | string[];\n\n /**\n * A short description of this particular version (and type, where applicable).\n */\n description?: string;\n\n /**\n * The fields that shall be used to generate relations, if any.\n *\n * TODO: Should this be not an array, to be more easily mergeable? Or should\n * we just have a custom merge strategy for them\n */\n relationFields?: CatalogModelKindRelationFieldDefinition[];\n\n schema: {\n jsonSchema: JsonObject;\n };\n}\n\n/**\n * @alpha\n */\nexport interface CatalogModelKindRelationFieldDefinition {\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: { path: string };\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: string;\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind?: string;\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace. If no\n * default namespace is specified, the namespace of the entity itself is used.\n */\n defaultNamespace?: 'default' | 'inherit';\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified, all\n * kinds are.\n */\n allowedKinds?: string[];\n}\n\nexport function opsFromCatalogModelKind(\n kind: CatalogModelKindDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n ops.push(\n createDeclareKindOp({\n kind: kind.names.kind,\n group: kind.group,\n properties: {\n singular: kind.names.singular,\n plural: kind.names.plural,\n description: kind.description,\n },\n }),\n );\n\n ops.push(\n ...opsFromCatalogModelAddKindVersion({\n kind: kind.names.kind,\n versions: kind.versions ?? [],\n }),\n );\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { reduceKindSchema } from '../jsonSchema/reduceKindSchema';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateKindOp } from '../operations/updateKind';\nimport { createUpdateKindVersionOp } from '../operations/updateKindVersion';\nimport { CatalogModelKindRelationFieldDefinition } from './addKind';\n\n/**\n * The definition of updates to a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateKindDefinition {\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\". Specify this if you\n * want to override the default value.\n */\n singular?: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\". Specify this if you\n * want to override the default value.\n */\n plural?: string;\n };\n\n /**\n * A short description of the kind. Specify this if you want to override the\n * default value.\n */\n description?: string;\n\n /**\n * Update one or more versions of the kind's actual schema shape.\n */\n versions?: CatalogModelUpdateKindVersionDefinition[];\n}\n\n/**\n * The definition of updates to a specific version of a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateKindVersionDefinition {\n /**\n * The specific version name or names to update, e.g. \"v1alpha1\" or\n * [\"v1alpha1\", \"v1beta1\"].\n */\n name: string | string[];\n\n /**\n * The spec type or types that this version update applies to.\n */\n specType?: string | string[];\n\n /**\n * A short description of this particular version (and type, where\n * applicable). Specify this if you want to override the default value.\n */\n description?: string;\n\n /**\n * The fields that shall be used to generate relations, if any. Specify this\n * if you want to override the default value.\n */\n relationFields?: CatalogModelKindRelationFieldDefinition[];\n\n /**\n * The JSON schema to deep merge with the existing schema for this version.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateKind(\n kind: CatalogModelUpdateKindDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n if (kind.names.singular || kind.names.plural || kind.description) {\n ops.push(\n createUpdateKindOp({\n kind: kind.names.kind,\n properties: {\n singular: kind.names.singular,\n plural: kind.names.plural,\n description: kind.description,\n },\n }),\n );\n }\n\n for (const version of kind.versions ?? []) {\n const jsonSchema = version.schema\n ? reduceKindSchema(version.schema.jsonSchema)\n : undefined;\n if (jsonSchema) {\n validateMetaSchema(jsonSchema);\n }\n const names = Array.isArray(version.name) ? version.name : [version.name];\n for (const name of names) {\n const specTypes = version.specType?.length\n ? [version.specType].flat()\n : [undefined];\n for (const specType of specTypes) {\n ops.push(\n createUpdateKindVersionOp({\n kind: kind.names.kind,\n name,\n specType: specType,\n properties: {\n description: version.description,\n relationFields: version.relationFields,\n schema: jsonSchema\n ? { jsonSchema: jsonSchema as any }\n : undefined,\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveKindOp } from '../operations/removeKind';\n\n/**\n * The definition of a kind removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveKindDefinition {\n /**\n * The kind to remove, e.g. \"Component\".\n */\n kind: string;\n}\n\nexport function opsFromCatalogModelRemoveKind(\n definition: CatalogModelRemoveKindDefinition,\n): CatalogModelOp[] {\n return [createRemoveKindOp({ kind: definition.kind })];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createDeclareRelationOp } from '../operations/declareRelation';\n\n/**\n * The definition of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelationPairDefinition {\n /**\n * The kind(s) that this relation originates from, e.g. \"Component\" or\n * [\"Component\", \"Resource\"].\n */\n fromKind: string | string[];\n\n /**\n * The kind(s) that this relation points to, e.g. \"Group\" or\n * [\"Group\", \"User\"].\n */\n toKind: string | string[];\n\n /**\n * A human-readable description of the relation.\n */\n description: string;\n\n /**\n * The names for the forward direction (from the current entity toward\n * the one being referenced).\n */\n forward: {\n /**\n * The technical type of the relation, e.g. \"ownedBy\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: string;\n };\n\n /**\n * The names for the reverse direction (from the one being referenced\n * toward the current entity).\n */\n reverse: {\n /**\n * The technical type of the relation, e.g. \"ownerOf\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owner of\".\n */\n title: string;\n };\n}\n\nexport function opsFromCatalogModelRelationPair(\n relationPair: CatalogModelRelationPairDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n // Duplicate across kinds, and both directions\n for (const firstKind of [relationPair.fromKind].flat()) {\n for (const secondKind of [relationPair.toKind].flat()) {\n ops.push(\n createDeclareRelationOp({\n fromKind: firstKind,\n type: relationPair.forward.type,\n toKind: secondKind,\n properties: {\n reverseType: relationPair.reverse.type,\n title: relationPair.forward.title,\n description: relationPair.description,\n },\n }),\n );\n ops.push(\n createDeclareRelationOp({\n fromKind: secondKind,\n type: relationPair.reverse.type,\n toKind: firstKind,\n properties: {\n reverseType: relationPair.forward.type,\n title: relationPair.reverse.title,\n description: relationPair.description,\n },\n }),\n );\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createUpdateRelationOp } from '../operations/updateRelation';\n\n/**\n * The definition of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateRelationPairDefinition {\n /**\n * The kind(s) that this relation originates from, e.g. \"Component\" or\n * [\"Component\", \"Resource\"].\n */\n fromKind: string | string[];\n\n /**\n * The kind(s) that this relation points to, e.g. \"Group\" or\n * [\"Group\", \"User\"].\n */\n toKind: string | string[];\n\n /**\n * A human-readable description of the relation. Specify this if you want\n * to override the default value.\n */\n description?: string;\n\n /**\n * The names for the forward direction (from the current entity toward the one\n * being referenced).\n */\n forward: {\n /**\n * The technical type of the relation, e.g. \"ownedBy\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n * Specify this if you want to override the default value.\n */\n title?: string;\n };\n\n /**\n * The names for the reverse direction (from the one being referenced toward\n * the current entity).\n */\n reverse: {\n /**\n * The technical type of the relation, e.g. \"ownerOf\". Specify this if you\n * want to override the default value.\n */\n type?: string;\n /**\n * A human-readable title for the relation type, e.g. \"owner of\".\n * Specify this if you want to override the default value.\n */\n title?: string;\n };\n}\n\nexport function opsFromCatalogModelUpdateRelationPair(\n relationPair: CatalogModelUpdateRelationPairDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n // Duplicate across kinds, and both directions\n for (const firstKind of [relationPair.fromKind].flat()) {\n for (const secondKind of [relationPair.toKind].flat()) {\n ops.push(\n createUpdateRelationOp({\n fromKind: firstKind,\n type: relationPair.forward.type,\n toKind: secondKind,\n properties: {\n reverseType: relationPair.reverse.type,\n title: relationPair.forward.title,\n description: relationPair.description,\n },\n }),\n );\n if (relationPair.reverse.type) {\n ops.push(\n createUpdateRelationOp({\n fromKind: secondKind,\n type: relationPair.reverse.type,\n toKind: firstKind,\n properties: {\n reverseType: relationPair.forward.type,\n title: relationPair.reverse.title,\n description: relationPair.description,\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareAnnotationOp } from '../operations/declareAnnotation';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelAnnotationDefinition {\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the annotation.\n */\n description: string;\n\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelAnnotation(\n annotation: CatalogModelAnnotationDefinition,\n): CatalogModelOp[] {\n if (annotation.schema?.jsonSchema) {\n validateMetaSchema(annotation.schema.jsonSchema);\n if (annotation.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Annotation \"${annotation.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createDeclareAnnotationOp({\n name: annotation.name,\n properties: {\n title: annotation.title,\n description: annotation.description,\n schema: annotation.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateAnnotationOp } from '../operations/updateAnnotation';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of updates to a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateAnnotationDefinition {\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the annotation.\n */\n description?: string;\n\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateAnnotation(\n annotation: CatalogModelUpdateAnnotationDefinition,\n): CatalogModelOp[] {\n if (annotation.schema) {\n validateMetaSchema(annotation.schema.jsonSchema);\n if (annotation.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Annotation \"${annotation.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createUpdateAnnotationOp({\n name: annotation.name,\n properties: {\n title: annotation.title,\n description: annotation.description,\n schema: annotation.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveAnnotationOp } from '../operations/removeAnnotation';\n\n/**\n * The definition of an annotation removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveAnnotationDefinition {\n /**\n * The name of the annotation to remove, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveAnnotation(\n definition: CatalogModelRemoveAnnotationDefinition,\n): CatalogModelOp[] {\n return [createRemoveAnnotationOp({ name: definition.name })];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareLabelOp } from '../operations/declareLabel';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelLabelDefinition {\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the label.\n */\n description: string;\n\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelLabel(\n label: CatalogModelLabelDefinition,\n): CatalogModelOp[] {\n if (label.schema?.jsonSchema) {\n validateMetaSchema(label.schema.jsonSchema);\n if (label.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Label \"${label.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createDeclareLabelOp({\n name: label.name,\n properties: {\n title: label.title,\n description: label.description,\n schema: label.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateLabelOp } from '../operations/updateLabel';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of updates to a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateLabelDefinition {\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the label.\n */\n description?: string;\n\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateLabel(\n label: CatalogModelUpdateLabelDefinition,\n): CatalogModelOp[] {\n if (label.schema) {\n validateMetaSchema(label.schema.jsonSchema);\n if (label.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Label \"${label.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createUpdateLabelOp({\n name: label.name,\n properties: {\n title: label.title,\n description: label.description,\n schema: label.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveLabelOp } from '../operations/removeLabel';\n\n/**\n * The definition of a label removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveLabelDefinition {\n /**\n * The name of the label to remove, e.g. \"backstage.io/source-location\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveLabel(\n definition: CatalogModelRemoveLabelDefinition,\n): CatalogModelOp[] {\n return [createRemoveLabelOp({ name: definition.name })];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createDeclareTagOp } from '../operations/declareTag';\n\n/**\n * The definition of a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelTagDefinition {\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the tag.\n */\n description: string;\n}\n\nexport function opsFromCatalogModelTag(\n tag: CatalogModelTagDefinition,\n): CatalogModelOp[] {\n return [\n createDeclareTagOp({\n name: tag.name,\n properties: {\n title: tag.title,\n description: tag.description,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createUpdateTagOp } from '../operations/updateTag';\n\n/**\n * The definition of updates to a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateTagDefinition {\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the tag.\n */\n description?: string;\n}\n\nexport function opsFromCatalogModelUpdateTag(\n tag: CatalogModelUpdateTagDefinition,\n): CatalogModelOp[] {\n return [\n createUpdateTagOp({\n name: tag.name,\n properties: {\n title: tag.title,\n description: tag.description,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveTagOp } from '../operations/removeTag';\n\n/**\n * The definition of a tag removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveTagDefinition {\n /**\n * The name of the tag to remove, e.g. \"java\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveTag(\n definition: CatalogModelRemoveTagDefinition,\n): CatalogModelOp[] {\n return [createRemoveTagOp({ name: definition.name })];\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 { createCatalogModelLayer } from '../model/createCatalogModelLayer';\n\n/*\nNaming rules for relations in priority order:\n\n1. Use at most two words. One main verb and a specifier, e.g. \"ownerOf\"\n2. Reading out \"<source-kind> <type> <target-kind>\" should make sense in English.\n3. Maintain symmetry between pairs, e.g. \"ownedBy\" and \"ownerOf\" rather than \"owns\".\n*/\n\n/**\n * An ownership relation where the owner is usually an organizational\n * entity (user or group), and the other entity can be anything. Reversed\n * direction of {@link RELATION_OWNER_OF}.\n *\n * @public\n */\nexport const RELATION_OWNED_BY = 'ownedBy';\n\n/**\n * A relationship from an owner to the owned entity. Reversed direction of\n * {@link RELATION_OWNED_BY}.\n *\n * @public\n */\nexport const RELATION_OWNER_OF = 'ownerOf';\n\n/**\n * A relation with an API entity, typically from a component. Reversed direction of\n * {@link RELATION_API_CONSUMED_BY}.\n *\n * @public\n */\nexport const RELATION_CONSUMES_API = 'consumesApi';\n\n/**\n * A relation of an API being consumed, typically by a component. Reversed direction of\n * {@link RELATION_CONSUMES_API}.\n *\n * @public\n */\nexport const RELATION_API_CONSUMED_BY = 'apiConsumedBy';\n\n/**\n * A relation from an API provider entity (typically a component) to the API. Reversed direction of\n * {@link RELATION_API_PROVIDED_BY}.\n *\n * @public\n */\nexport const RELATION_PROVIDES_API = 'providesApi';\n\n/**\n * A relation from an API to its provider entity (typically a component). Reversed direction of\n * {@link RELATION_PROVIDES_API}.\n *\n * @public\n */\nexport const RELATION_API_PROVIDED_BY = 'apiProvidedBy';\n\n/**\n * A relation denoting a dependency on another entity. Reversed direction of\n * {@link RELATION_DEPENDENCY_OF}.\n *\n * @public\n */\nexport const RELATION_DEPENDS_ON = 'dependsOn';\n\n/**\n * A relation denoting a reverse dependency by another entity. Reversed direction of\n * {@link RELATION_DEPENDS_ON}.\n *\n * @public\n */\nexport const RELATION_DEPENDENCY_OF = 'dependencyOf';\n\n/**\n * A parent/child relation to build up a tree, used for example to describe\n * the organizational structure between groups. Reversed direction of\n * {@link RELATION_CHILD_OF}.\n *\n * @public\n */\nexport const RELATION_PARENT_OF = 'parentOf';\n\n/**\n * A relation from a child to a parent entity, used for example to describe\n * the organizational structure between groups. Reversed direction of\n * {@link RELATION_PARENT_OF}.\n *\n * @public\n */\nexport const RELATION_CHILD_OF = 'childOf';\n\n/**\n * A membership relation, typically for users in a group. Reversed direction of\n * {@link RELATION_HAS_MEMBER}.\n *\n * @public\n */\nexport const RELATION_MEMBER_OF = 'memberOf';\n\n/**\n * A relation from a group to its member, typically a user in a group. Reversed direction of\n * {@link RELATION_MEMBER_OF}.\n *\n * @public\n */\nexport const RELATION_HAS_MEMBER = 'hasMember';\n\n/**\n * A part/whole relation, typically for components in a system and systems\n * in a domain. Reversed direction of {@link RELATION_HAS_PART}.\n *\n * @public\n */\nexport const RELATION_PART_OF = 'partOf';\n\n/**\n * A relation from a containing entity to a contained entity. Reversed direction of\n * {@link RELATION_PART_OF}.\n *\n * @public\n */\nexport const RELATION_HAS_PART = 'hasPart';\n\n/**\n * Extends the catalog model with the well-known Backstage relation pairs.\n */\nexport const wellKnownRelationsModel = createCatalogModelLayer({\n layerId: 'catalog.backstage.io/well-known-relations',\n builder: model => {\n model.addRelationPair({\n fromKind: [\n 'API',\n 'Component',\n 'Domain',\n 'Group',\n 'Location',\n 'Resource',\n 'System',\n 'User',\n ],\n toKind: ['Group', 'User'],\n description:\n 'An ownership relation where the owner is usually an organizational entity (user or group), and the other entity can be anything.',\n forward: { type: 'ownedBy', title: 'owned by' },\n reverse: { type: 'ownerOf', title: 'owner of' },\n });\n\n model.addRelationPair({\n fromKind: 'Component',\n toKind: 'API',\n description:\n 'A relation from a component to an API it provides for consumption by others.',\n forward: { type: 'providesApi', title: 'provides API' },\n reverse: { type: 'apiProvidedBy', title: 'API provided by' },\n });\n\n model.addRelationPair({\n fromKind: 'Component',\n toKind: 'API',\n description: 'A relation from a component to an API it consumes.',\n forward: { type: 'consumesApi', title: 'consumes API' },\n reverse: { type: 'apiConsumedBy', title: 'API consumed by' },\n });\n\n model.addRelationPair({\n fromKind: ['Component', 'Resource'],\n toKind: ['Component', 'Resource'],\n description:\n 'A dependency relation expressing that an entity needs another entity to function.',\n forward: { type: 'dependsOn', title: 'depends on' },\n reverse: { type: 'dependencyOf', title: 'dependency of' },\n });\n\n model.addRelationPair({\n fromKind: 'Group',\n toKind: 'Group',\n description:\n 'A parent/child relation to build up a tree, used for example to describe the organizational structure between groups.',\n forward: { type: 'parentOf', title: 'parent of' },\n reverse: { type: 'childOf', title: 'child of' },\n });\n\n model.addRelationPair({\n fromKind: 'User',\n toKind: 'Group',\n description: 'A membership relation, typically for users in a group.',\n forward: { type: 'memberOf', title: 'member of' },\n reverse: { type: 'hasMember', title: 'has member' },\n });\n\n model.addRelationPair({\n fromKind: ['Component', 'API', 'Resource'],\n toKind: ['Component', 'System'],\n description:\n 'A part/whole relation where a component, API, or resource belongs to a system or a component is a subcomponent of another.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\n });\n\n model.addRelationPair({\n fromKind: 'System',\n toKind: 'Domain',\n description: 'A part/whole relation where a system belongs to a domain.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\n });\n\n model.addRelationPair({\n fromKind: 'Domain',\n toKind: 'Domain',\n description:\n 'A part/whole relation where a domain is a subdomain of another domain.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\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 missingAnnotation from './assets/missingAnnotation.svg';\nimport noInformation from './assets/noInformation.svg';\nimport createComponent from './assets/createComponent.svg';\nimport noBuild from './assets/noBuild.svg';\nimport { makeStyles } from '@material-ui/core/styles';\n\ntype Props = {\n missing: 'field' | 'info' | 'content' | 'data';\n};\n\n/** @public */\nexport type EmptyStateImageClassKey = 'generalImg';\n\nconst useStyles = makeStyles(\n {\n generalImg: {\n width: '95%',\n zIndex: 2,\n position: 'relative',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, 15%)',\n },\n },\n { name: 'BackstageEmptyStateImage' },\n);\n\n/** @public */\nexport const EmptyStateImage = ({ missing }: Props) => {\n const classes = useStyles();\n switch (missing) {\n case 'field':\n return (\n <img\n src={missingAnnotation}\n className={classes.generalImg}\n alt=\"annotation is missing\"\n />\n );\n case 'info':\n return (\n <img\n src={noInformation}\n alt=\"no Information\"\n className={classes.generalImg}\n />\n );\n case 'content':\n return (\n <img\n src={createComponent}\n alt=\"create Component\"\n className={classes.generalImg}\n />\n );\n case 'data':\n return (\n <img src={noBuild} alt=\"no Build\" className={classes.generalImg} />\n );\n default:\n return null;\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 Grid from '@material-ui/core/Grid';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { EmptyStateImage } from './EmptyStateImage';\n\n/** @public */\nexport type EmptyStateClassKey = 'root' | 'action' | 'imageContainer';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2, 0, 0, 0),\n },\n action: {\n marginTop: theme.spacing(2),\n },\n imageContainer: {\n position: 'relative',\n },\n }),\n { name: 'BackstageEmptyState' },\n);\n\ntype Props = {\n title: string;\n description?: string | JSX.Element;\n missing: 'field' | 'info' | 'content' | 'data' | { customImage: JSX.Element };\n action?: JSX.Element;\n};\n\n/**\n * Various placeholder views for empty state pages\n *\n * @public\n *\n */\nexport function EmptyState(props: Props) {\n const { title, description, missing, action } = props;\n const classes = useStyles();\n return (\n <Grid\n container\n direction=\"row\"\n justifyContent=\"space-around\"\n alignItems=\"flex-start\"\n className={classes.root}\n spacing={2}\n >\n <Grid item xs={12} md={6}>\n <Grid container direction=\"column\">\n <Grid item xs>\n <Typography variant=\"h5\">{title}</Typography>\n </Grid>\n <Grid item xs>\n <Typography variant=\"body1\">{description}</Typography>\n </Grid>\n <Grid item xs className={classes.action}>\n {action}\n </Grid>\n </Grid>\n </Grid>\n <Grid item xs={12} md={6} className={classes.imageContainer}>\n {typeof missing === 'string' ? (\n <EmptyStateImage missing={missing} />\n ) : (\n missing.customImage\n )}\n </Grid>\n </Grid>\n );\n}\n","/*\n * Copyright 2024 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 */\nimport { ComponentProps } from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { StarIcon, UnstarredIcon } from '../../icons';\n\nconst useStyles = makeStyles<Theme>(\n () => ({\n icon: {\n color: '#f3ba37',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n iconBorder: {\n color: 'inherit',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n }),\n { name: 'BackstageFavoriteToggleIcon' },\n);\n\n/**\n * @public\n */\nexport type FavoriteToggleIconClassKey = 'icon' | 'iconBorder';\n\n/**\n * Icon used in FavoriteToggle component.\n *\n * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable}\n *\n * @public\n */\nexport function FavoriteToggleIcon(props: { isFavorite: boolean }) {\n const { isFavorite } = props;\n const classes = useStyles();\n\n return (\n <Typography\n component=\"span\"\n className={isFavorite ? classes.icon : classes.iconBorder}\n >\n {isFavorite ? <StarIcon /> : <UnstarredIcon />}\n </Typography>\n );\n}\n\n/**\n * Props for the {@link FavoriteToggle} component.\n *\n * @public\n */\nexport type FavoriteToggleProps = ComponentProps<typeof IconButton> & {\n id: string;\n title: string;\n isFavorite: boolean;\n onToggle: (value: boolean) => void;\n};\n\n/**\n * Toggle encapsulating logic for marking something as favorite,\n * primarily used in various instances of entity lists and cards but can be used elsewhere.\n *\n * This component can only be used in as a controlled toggle and does not keep internal state.\n *\n * @public\n */\nexport function FavoriteToggle(props: FavoriteToggleProps) {\n const {\n id,\n title,\n isFavorite: value,\n onToggle: onChange,\n ...iconButtonProps\n } = props;\n return (\n <Tooltip id={id} title={title}>\n <IconButton\n aria-label={title}\n id={id}\n onClick={() => onChange(!value)}\n color=\"inherit\"\n {...iconButtonProps}\n >\n <FavoriteToggleIcon isFavorite={value} />\n </IconButton>\n </Tooltip>\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 MaterialButton, {\n ButtonProps as MaterialButtonProps,\n} from '@material-ui/core/Button';\nimport { forwardRef } from 'react';\nimport { UnstyledLink, LinkProps } from '../Link/Link';\n\n/**\n * Properties for {@link LinkButton}\n *\n * @public\n * @remarks\n *\n * See {@link https://v4.mui.com/api/button/#props | Material UI Button Props} for all properties\n */\nexport type LinkButtonProps = MaterialButtonProps &\n Omit<LinkProps, 'variant' | 'color'>;\n\n/**\n * This wrapper is here to reset the color of the Link and make typescript happy.\n */\nconst LinkWrapper = forwardRef<any, LinkProps>((props, ref) => (\n <UnstyledLink ref={ref} {...props} color=\"initial\" />\n));\n\n/**\n * Thin wrapper on top of material-ui's {@link https://v4.mui.com/components/buttons/ | Button} component\n *\n * @public\n * @remarks\n */\nexport const LinkButton = forwardRef<any, LinkButtonProps>((props, ref) => (\n <MaterialButton ref={ref} component={LinkWrapper} {...props} />\n)) as (props: LinkButtonProps) => JSX.Element;\n\n/**\n * @public\n * @deprecated use LinkButton instead\n */\nexport const Button = LinkButton;\n\n/**\n * @public\n * @deprecated use LinkButtonProps instead\n */\nexport type ButtonProps = LinkButtonProps;\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 */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\n/** @public */\nexport type ClosedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageClosedDropdown' },\n);\n\nconst ClosedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7.5 8L6 9.5L12.0703 15.5703L18.1406 9.5L16.6406 8L12.0703 12.5703L7.5 8Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default ClosedDropdown;\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 */\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\nexport type OpenedDropdownClassKey = 'icon';\n\nconst useStyles = makeStyles(\n theme =>\n createStyles({\n icon: {\n position: 'absolute',\n right: theme.spacing(0.5),\n pointerEvents: 'none',\n color: '#616161',\n },\n }),\n { name: 'BackstageOpenedDropdown' },\n);\n\nconst OpenedDropdown = () => {\n const classes = useStyles();\n return (\n <SvgIcon\n className={classes.icon}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M16.5 16L18 14.5L11.9297 8.42969L5.85938 14.5L7.35938 16L11.9297 11.4297L16.5 16Z\"\n fill=\"currentColor\"\n />\n </SvgIcon>\n );\n};\n\nexport default OpenedDropdown;\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 */\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Chip from '@material-ui/core/Chip';\nimport FormControl from '@material-ui/core/FormControl';\nimport InputBase from '@material-ui/core/InputBase';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Select from '@material-ui/core/Select';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { ChangeEvent, useEffect, useState } from 'react';\n\nimport ClosedDropdown from './static/ClosedDropdown';\nimport OpenedDropdown from './static/OpenedDropdown';\n\n/** @public */\nexport type SelectInputBaseClassKey = 'root' | 'input';\n\nconst BootstrapInput = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {\n 'label + &': {\n marginTop: theme.spacing(3),\n },\n '&.Mui-focused > div[role=button]': {\n borderColor: theme.palette.primary.main,\n },\n },\n input: {\n borderRadius: theme.shape.borderRadius,\n position: 'relative',\n backgroundColor: theme.palette.background.paper,\n border: '1px solid #ced4da',\n fontSize: theme.typography.body1.fontSize,\n padding: theme.spacing(1.25, 3.25, 1.25, 1.5),\n transition: theme.transitions.create(['border-color', 'box-shadow']),\n '&:focus': {\n background: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n },\n },\n }),\n { name: 'BackstageSelectInputBase' },\n)(InputBase);\n\n/** @public */\nexport type SelectClassKey =\n | 'formControl'\n | 'label'\n | 'chips'\n | 'chip'\n | 'checkbox'\n | 'root';\n\nconst useStyles = makeStyles(\n (theme: Theme) =>\n createStyles({\n formControl: {\n margin: theme.spacing(1, 0),\n },\n label: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n formLabel: {\n transform: 'initial',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '&.Mui-focused': {\n color: theme.palette.text.primary,\n },\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n },\n chip: {\n margin: 2,\n },\n checkbox: {},\n\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n }),\n { name: 'BackstageSelect' },\n);\n\n/** @public */\nexport type SelectItem = {\n label: string;\n value: string | number;\n};\n\n/** @public */\nexport type SelectedItems = string | string[] | number | number[];\n\nexport type SelectProps = {\n multiple?: boolean;\n items: SelectItem[];\n label: string;\n placeholder?: string;\n selected?: SelectedItems;\n onChange: (arg: SelectedItems) => void;\n triggerReset?: boolean;\n native?: boolean;\n disabled?: boolean;\n margin?: 'dense' | 'none';\n 'data-testid'?: string;\n};\n\n/** @public */\nexport function SelectComponent(props: SelectProps) {\n const {\n multiple,\n items,\n label,\n placeholder,\n selected,\n onChange,\n triggerReset,\n native = false,\n disabled = false,\n margin,\n 'data-testid': dataTestId = 'select',\n } = props;\n const classes = useStyles();\n const [value, setValue] = useState<SelectedItems>(\n selected || (multiple ? [] : ''),\n );\n const [isOpen, setOpen] = useState(false);\n\n useEffect(() => {\n setValue(multiple ? [] : '');\n }, [triggerReset, multiple]);\n\n useEffect(() => {\n setValue(selected || (multiple ? [] : ''));\n }, [selected, multiple]);\n\n const handleChange = (event: ChangeEvent<{ value: unknown }>) => {\n setValue(event.target.value as SelectedItems);\n onChange(event.target.value as SelectedItems);\n };\n\n const handleOpen = (event: ChangeEvent<any>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n setOpen(previous => {\n if (multiple && !(event.target instanceof HTMLElement)) {\n return true;\n }\n return !previous;\n });\n };\n\n const handleClose = () => {\n setOpen(false);\n };\n\n const handleDelete = (selectedValue: string | number) => () => {\n const newValue = (value as any[]).filter(chip => chip !== selectedValue);\n setValue(newValue);\n onChange(newValue);\n };\n\n return (\n <Box className={classes.root}>\n <FormControl className={classes.formControl}>\n <InputLabel className={classes.formLabel}>{label}</InputLabel>\n <Select\n aria-label={label}\n value={value}\n native={native}\n disabled={disabled}\n data-testid={dataTestId}\n displayEmpty\n multiple={multiple}\n margin={margin}\n onChange={handleChange}\n open={isOpen}\n onOpen={handleOpen}\n onClose={handleClose}\n input={<BootstrapInput />}\n label={label}\n renderValue={s =>\n multiple && (value as any[]).length !== 0 ? (\n <Box className={classes.chips}>\n {(s as string[]).map(selectedValue => {\n const item = items.find(el => el.value === selectedValue);\n return item ? (\n <Chip\n data-testid=\"chip\"\n key={item?.value}\n label={item?.label}\n clickable\n deleteIcon={\n <CancelIcon\n data-testid=\"cancel-icon\"\n onMouseDown={event => event.stopPropagation()}\n />\n }\n onDelete={handleDelete(selectedValue)}\n className={classes.chip}\n />\n ) : (\n false\n );\n })}\n </Box>\n ) : (\n <Typography>\n {(value as any[]).length === 0\n ? placeholder || ''\n : items.find(el => el.value === s)?.label}\n </Typography>\n )\n }\n IconComponent={() =>\n !isOpen ? <ClosedDropdown /> : <OpenedDropdown />\n }\n MenuProps={{\n anchorOrigin: {\n vertical: 'bottom',\n horizontal: 'left',\n },\n transformOrigin: {\n vertical: 'top',\n horizontal: 'left',\n },\n getContentAnchorEl: null,\n }}\n >\n {!!placeholder && !multiple && (\n <MenuItem value={[]}>{placeholder}</MenuItem>\n )}\n {native\n ? items &&\n items.map(item => (\n <option value={item.value} key={item.value}>\n {item.label}\n </option>\n ))\n : items &&\n items.map(item => (\n <MenuItem key={item.value} value={item.value}>\n {multiple && (\n <Checkbox\n color=\"primary\"\n checked={(value as any[]).includes(item.value) || false}\n className={classes.checkbox}\n />\n )}\n {item.label}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\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 { configApiRef, useApi, useApp } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MenuList from '@material-ui/core/MenuList';\nimport Popover from '@material-ui/core/Popover';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { ReactNode, Children, MouseEventHandler, useState } from 'react';\nimport { SupportItem, SupportItemLink, useSupportConfig } from '../../hooks';\nimport { HelpIcon } from '../../icons';\nimport { Link } from '../Link';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\ntype SupportButtonProps = {\n title?: string;\n items?: SupportItem[];\n children?: ReactNode;\n};\n\nexport type SupportButtonClassKey = 'popoverList';\n\nconst useStyles = makeStyles(\n {\n popoverList: {\n minWidth: 260,\n maxWidth: 400,\n },\n menuItem: {\n whiteSpace: 'normal',\n },\n },\n { name: 'BackstageSupportButton' },\n);\n\nconst SupportIcon = ({ icon }: { icon: string | undefined }) => {\n const app = useApp();\n const Icon = icon ? app.getSystemIcon(icon) ?? HelpIcon : HelpIcon;\n return <Icon />;\n};\n\nconst SupportLink = ({ link }: { link: SupportItemLink }) => (\n <Link to={link.url}>{link.title ?? link.url}</Link>\n);\n\nconst SupportListItem = ({ item }: { item: SupportItem }) => {\n return (\n <MenuItem button={false}>\n <ListItemIcon>\n <SupportIcon icon={item.icon} />\n </ListItemIcon>\n <ListItemText\n primary={item.title}\n secondary={item.links?.reduce<React.ReactNode[]>(\n (prev, link, idx) => [\n ...prev,\n idx > 0 && <br key={idx} />,\n <SupportLink link={link} key={link.url} />,\n ],\n [],\n )}\n />\n </MenuItem>\n );\n};\n\nexport function SupportButton(props: SupportButtonProps) {\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const { title, items, children } = props;\n const { items: configItems } = useSupportConfig();\n\n const [popoverOpen, setPopoverOpen] = useState(false);\n const [anchorEl, setAnchorEl] = useState<Element | null>(null);\n const classes = useStyles();\n const supportConfig = useApi(configApiRef).getOptionalConfig('app.support');\n const isSmallScreen = useMediaQuery<Theme>(theme =>\n theme.breakpoints.down('sm'),\n );\n\n const onClickHandler: MouseEventHandler = event => {\n setAnchorEl(event.currentTarget);\n setPopoverOpen(true);\n };\n\n const popoverCloseHandler = () => {\n setPopoverOpen(false);\n };\n\n if (!supportConfig) {\n return null;\n }\n\n return (\n <>\n <Box display=\"flex\" ml={1}>\n {isSmallScreen ? (\n <IconButton\n color=\"primary\"\n size=\"small\"\n onClick={onClickHandler}\n data-testid=\"support-button\"\n aria-label=\"Support\"\n >\n <HelpIcon />\n </IconButton>\n ) : (\n <Button\n data-testid=\"support-button\"\n aria-label=\"Support\"\n color=\"primary\"\n onClick={onClickHandler}\n startIcon={<HelpIcon />}\n >\n {t('supportButton.title')}\n </Button>\n )}\n </Box>\n <Popover\n data-testid=\"support-button-popover\"\n open={popoverOpen}\n anchorEl={anchorEl}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'right',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'right',\n }}\n onClose={popoverCloseHandler}\n >\n <MenuList\n className={classes.popoverList}\n autoFocusItem={Boolean(anchorEl)}\n >\n {title && (\n <MenuItem\n button={false}\n alignItems=\"flex-start\"\n className={classes.menuItem}\n >\n <Typography variant=\"subtitle1\">{title}</Typography>\n </MenuItem>\n )}\n {Children.map(children, (child, i) => (\n <MenuItem\n button={false}\n alignItems=\"flex-start\"\n key={`child-${i}`}\n className={classes.menuItem}\n >\n {child}\n </MenuItem>\n ))}\n {(items ?? configItems).map((item, i) => (\n <SupportListItem item={item} key={`item-${i}`} />\n ))}\n </MenuList>\n <DialogActions>\n <Button\n color=\"primary\"\n onClick={popoverCloseHandler}\n aria-label=\"Close\"\n >\n {t('supportButton.close')}\n </Button>\n </DialogActions>\n </Popover>\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 Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useEffect, useState } from 'react';\n\nimport { Select } from '../Select';\nimport { SelectProps } from '../Select/Select';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport type TableFiltersClassKey =\n | 'root'\n | 'value'\n | 'header'\n /**\n * @deprecated Use `'header'` instead. This was a typo in the original class key.\n */\n | 'heder'\n | 'filters';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n width: '315px',\n display: 'flex',\n flexDirection: 'column',\n marginRight: theme.spacing(3),\n },\n value: {\n fontWeight: 'bold',\n fontSize: 18,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n height: theme.spacing(7.5),\n justifyContent: 'space-between',\n borderBottom: `1px solid ${theme.palette.grey[500]}`,\n },\n // Intentionally empty: the deprecated `heder` class is still applied to\n // the same element as `header` so legacy theme overrides on\n // `BackstageTableFilters.heder` continue to work. Keeping this rule empty\n // (rather than duplicating `header`'s styles) avoids clobbering overrides\n // on the canonical `header` key — JSS injects rules in key order, so an\n // empty `heder` defined after `header` has no properties to override.\n heder: {},\n filters: {\n display: 'flex',\n flexDirection: 'column',\n '& > *': {\n marginTop: theme.spacing(2),\n },\n },\n }),\n { name: 'BackstageTableFilters' },\n);\n\nexport type Without<T, K> = Pick<T, Exclude<keyof T, K>>;\n\nexport type Filter = {\n type: 'select' | 'multiple-select';\n element: Without<SelectProps, 'onChange'>;\n};\n\nexport type SelectedFilters = {\n [key: string]: string | string[];\n};\n\ntype Props = {\n filters: Filter[];\n selectedFilters?: SelectedFilters;\n onChangeFilters: (arg: any) => any;\n};\n\nexport const Filters = (props: Props) => {\n const classes = useFilterStyles();\n\n const { onChangeFilters } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const [selectedFilters, setSelectedFilters] = useState<SelectedFilters>({\n ...props.selectedFilters,\n });\n const [reset, triggerReset] = useState(false);\n\n // Trigger re-rendering\n const handleClick = () => {\n setSelectedFilters({});\n triggerReset(el => !el);\n };\n\n useEffect(() => {\n onChangeFilters(selectedFilters);\n }, [selectedFilters, onChangeFilters]);\n\n // As material table doesn't provide a way to add a column filter tab we will make our own filter logic\n return (\n <Box className={classes.root}>\n <Box className={`${classes.header} ${classes.heder}`}>\n <Box className={classes.value}>{t('table.filter.title')}</Box>\n <Button color=\"primary\" onClick={handleClick}>\n {t('table.filter.clearAll')}\n </Button>\n </Box>\n <Box className={classes.filters}>\n {!!props.filters?.length &&\n props.filters.map(filter => (\n <Select\n triggerReset={reset}\n key={filter.element.label}\n {...(filter.element as SelectProps)}\n selected={selectedFilters[filter.element.label]}\n onChange={el =>\n setSelectedFilters({\n ...selectedFilters,\n [filter.element.label]: el as any,\n })\n }\n />\n ))}\n </Box>\n </Box>\n );\n};\n","/*\n * Copyright 2023 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 Box from '@material-ui/core/Box';\nimport CircularProgress from '@material-ui/core/CircularProgress';\n\n/**\n * @internal\n */\nexport function TableLoadingBody(props: { colSpan?: number }) {\n return (\n <tbody data-testid=\"loading-indicator\">\n <tr>\n <td colSpan={props.colSpan}>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n minHeight: '15rem',\n }}\n >\n <CircularProgress size=\"5rem\" />\n </Box>\n </td>\n </tr>\n </tbody>\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 {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport MTable, {\n Column,\n Icons,\n MaterialTableProps,\n MTableBody,\n MTableHeader,\n MTableToolbar,\n Options,\n} from '@material-table/core';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport {\n makeStyles,\n Theme,\n useTheme,\n withStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport AddBox from '@material-ui/icons/AddBox';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport Check from '@material-ui/icons/Check';\nimport ChevronLeft from '@material-ui/icons/ChevronLeft';\nimport ChevronRight from '@material-ui/icons/ChevronRight';\nimport Clear from '@material-ui/icons/Clear';\nimport DeleteOutline from '@material-ui/icons/DeleteOutline';\nimport Edit from '@material-ui/icons/Edit';\nimport FilterList from '@material-ui/icons/FilterList';\nimport Search from '@material-ui/icons/Search';\nimport FirstPage from '@material-ui/icons/FirstPage';\nimport LastPage from '@material-ui/icons/LastPage';\nimport Remove from '@material-ui/icons/Remove';\nimport SaveAlt from '@material-ui/icons/SaveAlt';\nimport ViewColumn from '@material-ui/icons/ViewColumn';\nimport { isEqual, transform } from 'lodash';\nimport {\n CSSProperties,\n forwardRef,\n MutableRefObject,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { SelectProps } from '../Select/Select';\nimport { Filter, Filters, SelectedFilters, Without } from './Filters';\nimport { TableLoadingBody } from './TableLoadingBody';\n\n// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51\nconst tableIcons: Icons = {\n Add: forwardRef<SVGSVGElement>((props, ref) => (\n <AddBox {...props} ref={ref} />\n )),\n Check: forwardRef<SVGSVGElement>((props, ref) => (\n <Check {...props} ref={ref} />\n )),\n Clear: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Delete: forwardRef<SVGSVGElement>((props, ref) => (\n <DeleteOutline {...props} ref={ref} />\n )),\n DetailPanel: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n Edit: forwardRef<SVGSVGElement>((props, ref) => (\n <Edit {...props} ref={ref} />\n )),\n Export: forwardRef<SVGSVGElement>((props, ref) => (\n <SaveAlt {...props} ref={ref} />\n )),\n Filter: forwardRef<SVGSVGElement>((props, ref) => (\n <FilterList {...props} ref={ref} />\n )),\n FirstPage: forwardRef<SVGSVGElement>((props, ref) => (\n <FirstPage {...props} ref={ref} />\n )),\n LastPage: forwardRef<SVGSVGElement>((props, ref) => (\n <LastPage {...props} ref={ref} />\n )),\n NextPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronRight {...props} ref={ref} />\n )),\n PreviousPage: forwardRef<SVGSVGElement>((props, ref) => (\n <ChevronLeft {...props} ref={ref} />\n )),\n ResetSearch: forwardRef<SVGSVGElement>((props, ref) => (\n <Clear {...props} ref={ref} />\n )),\n Search: forwardRef<SVGSVGElement>((props, ref) => (\n <Search {...props} ref={ref} />\n )),\n SortArrow: forwardRef<SVGSVGElement>((props, ref) => (\n <ArrowUpward {...props} ref={ref} />\n )),\n ThirdStateCheck: forwardRef<SVGSVGElement>((props, ref) => (\n <Remove {...props} ref={ref} />\n )),\n ViewColumn: forwardRef<SVGSVGElement>((props, ref) => (\n <ViewColumn {...props} ref={ref} />\n )),\n};\n\n// TODO: Material table might already have such a function internally that we can use?\nfunction extractValueByField(data: any, field: string): any | undefined {\n const path = field.split('.');\n let value = data[path[0]];\n\n for (let i = 1; i < path.length; ++i) {\n if (value === undefined) {\n return value;\n }\n\n const f = path[i];\n value = value[f];\n }\n\n return value;\n}\n\nexport type TableHeaderClassKey = 'header';\n\nconst StyledMTableHeader = withStyles(\n theme => ({\n header: {\n padding: theme.spacing(1, 2, 1, 2.5),\n borderTop: `1px solid ${theme.palette.grey.A100}`,\n borderBottom: `1px solid ${theme.palette.grey.A100}`,\n // withStyles hasn't a generic overload for theme\n fontWeight: theme.typography.fontWeightBold,\n position: 'static',\n wordBreak: 'normal',\n textTransform: 'uppercase',\n },\n }),\n { name: 'BackstageTableHeader' },\n)(MTableHeader);\n\nexport type TableToolbarClassKey = 'root' | 'title' | 'searchField';\n\nconst StyledMTableToolbar = withStyles(\n theme => ({\n root: {\n padding: theme.spacing(3, 0, 2.5, 2.5),\n },\n title: {\n '& > h6': {\n fontWeight: theme.typography.fontWeightBold,\n },\n },\n searchField: {\n paddingRight: theme.spacing(2),\n },\n }),\n { name: 'BackstageTableToolbar' },\n)(MTableToolbar);\n\n/** @public */\nexport type FiltersContainerClassKey = 'root' | 'filterControls' | 'title';\n\nconst useFilterStyles = makeStyles(\n theme => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n },\n filterControls: {\n display: 'flex',\n alignItems: 'center',\n },\n title: {\n fontWeight: theme.typography.fontWeightBold,\n fontSize: 18,\n whiteSpace: 'nowrap',\n },\n }),\n { name: 'BackstageTableFiltersContainer' },\n);\n\nexport type TableClassKey = 'root';\n\nconst useTableStyles = makeStyles(\n () => ({\n root: {\n display: 'flex',\n alignItems: 'start',\n },\n }),\n { name: 'BackstageTable' },\n);\n\nfunction convertColumns<T extends object>(\n columns: TableColumn<T>[],\n theme: Theme,\n): TableColumn<T>[] {\n return columns.map(column => {\n const headerStyle: CSSProperties = column.headerStyle ?? {};\n\n let cellStyle = column.cellStyle || {};\n\n if (column.highlight) {\n headerStyle.color = theme.palette.textContrast;\n\n if (typeof cellStyle === 'object') {\n (cellStyle as CSSProperties).fontWeight =\n theme.typography.fontWeightBold;\n } else {\n const cellStyleFn = cellStyle as (\n data: any,\n rowData: T,\n column?: Column<T>,\n ) => CSSProperties;\n cellStyle = (data, rowData, rowColumn) => {\n const style = cellStyleFn(data, rowData, rowColumn);\n return { ...style, fontWeight: theme.typography.fontWeightBold };\n };\n }\n }\n\n return {\n ...column,\n headerStyle,\n cellStyle,\n };\n });\n}\n\nfunction removeDefaultValues(state: any, defaultState: any): any {\n return transform(state, (result, value, key) => {\n if (!isEqual(value, defaultState[key])) {\n result[key] = value;\n }\n });\n}\n\nconst defaultInitialState = {\n search: '',\n filtersOpen: false,\n filters: {},\n};\n\nexport interface TableColumn<T extends object = {}> extends Column<T> {\n highlight?: boolean;\n width?: string;\n}\n\nexport type TableFilter = {\n column: string;\n type: 'select' | 'multiple-select';\n};\n\nexport type TableState = {\n search?: string;\n filtersOpen?: boolean;\n filters?: SelectedFilters;\n};\n\nexport interface TableProps<T extends object = {}>\n extends MaterialTableProps<T> {\n columns: TableColumn<T>[];\n subtitle?: string;\n filters?: TableFilter[];\n initialState?: TableState;\n emptyContent?: ReactNode;\n isLoading?: boolean;\n onStateChange?: (state: TableState) => any;\n}\n\nexport interface TableOptions<T extends object = {}> extends Options<T> {}\n\nexport function TableToolbar(toolbarProps: {\n toolbarRef: MutableRefObject<any>;\n setSearch: (value: string) => void;\n onSearchChanged: (value: string) => void;\n toggleFilters: () => void;\n hasFilters: boolean;\n selectedFiltersLength: number;\n}) {\n const {\n toolbarRef,\n setSearch,\n hasFilters,\n selectedFiltersLength,\n toggleFilters,\n } = toolbarProps;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const filtersClasses = useFilterStyles();\n const onSearchChanged = useCallback(\n (searchText: string) => {\n toolbarProps.onSearchChanged(searchText);\n setSearch(searchText);\n },\n [toolbarProps, setSearch],\n );\n\n if (hasFilters) {\n return (\n <Box className={filtersClasses.root}>\n <Box className={filtersClasses.filterControls}>\n <IconButton onClick={toggleFilters} aria-label=\"filter list\">\n <FilterList />\n </IconButton>\n <Typography className={filtersClasses.title}>\n {t('table.filter.title')} ({selectedFiltersLength})\n </Typography>\n </Box>\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n </Box>\n );\n }\n\n return (\n <StyledMTableToolbar\n {...toolbarProps}\n ref={toolbarRef}\n onSearchChanged={onSearchChanged}\n />\n );\n}\n\n/**\n * @public\n */\nexport function Table<T extends object = {}>(props: TableProps<T>) {\n const {\n data,\n columns,\n emptyContent,\n options,\n title,\n subtitle,\n localization,\n filters,\n initialState,\n onStateChange,\n components,\n isLoading: loading,\n style,\n ...restProps\n } = props;\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const tableClasses = useTableStyles();\n\n const theme = useTheme();\n\n const calculatedInitialState = { ...defaultInitialState, ...initialState };\n\n const [filtersOpen, setFiltersOpen] = useState(\n calculatedInitialState.filtersOpen,\n );\n const toggleFilters = useCallback(\n () => setFiltersOpen(v => !v),\n [setFiltersOpen],\n );\n\n const [selectedFilters, setSelectedFilters] = useState(\n calculatedInitialState.filters,\n );\n\n const [search, setSearch] = useState(calculatedInitialState.search);\n\n useEffect(() => {\n if (onStateChange) {\n const state = removeDefaultValues(\n {\n search,\n filtersOpen,\n filters: selectedFilters,\n },\n defaultInitialState,\n );\n\n onStateChange(state);\n }\n }, [search, filtersOpen, selectedFilters, onStateChange]);\n\n const getFieldByTitle = useCallback(\n (titleValue: string | keyof T) =>\n columns.find(el => el.title === titleValue)?.field,\n [columns],\n );\n\n const tableData = useMemo(() => {\n if (typeof data === 'function' || !selectedFilters) {\n return data;\n }\n\n const selectedFiltersArray = Object.values(selectedFilters);\n if (data && selectedFiltersArray.flat().length) {\n const newData = (data as any[]).filter(\n el =>\n !!Object.entries(selectedFilters)\n .filter(([, value]) => !!(value as { length?: number }).length)\n .every(([key, filterValue]) => {\n const fieldValue = extractValueByField(\n el,\n getFieldByTitle(key) as string,\n );\n\n if (Array.isArray(fieldValue) && Array.isArray(filterValue)) {\n return fieldValue.some(v => filterValue.includes(v));\n } else if (Array.isArray(fieldValue)) {\n return fieldValue.includes(filterValue);\n } else if (Array.isArray(filterValue)) {\n return filterValue.includes(fieldValue);\n }\n\n return fieldValue === filterValue;\n }),\n );\n return newData;\n }\n return data;\n }, [data, selectedFilters, getFieldByTitle]);\n\n const selectedFiltersLength = Object.values(selectedFilters).flat().length;\n\n const hasFilters = !!filters?.length;\n const Toolbar = useCallback(\n (toolbarProps: any /* no type for this in material-table */) => {\n return (\n <TableToolbar\n setSearch={setSearch}\n hasFilters={hasFilters}\n selectedFiltersLength={selectedFiltersLength}\n toggleFilters={toggleFilters}\n {...toolbarProps}\n />\n );\n },\n [toggleFilters, hasFilters, selectedFiltersLength, setSearch],\n );\n\n const hasNoRows = typeof data !== 'function' && data.length === 0;\n const columnCount = columns.length;\n const Body = useMemo(\n () => makeBody({ hasNoRows, emptyContent, columnCount, loading }),\n [hasNoRows, emptyContent, columnCount, loading],\n );\n\n return (\n <Box className={tableClasses.root}>\n {filtersOpen && data && typeof data !== 'function' && filters?.length && (\n <Filters\n filters={constructFilters(filters, data as any[], columns, t)}\n selectedFilters={selectedFilters}\n onChangeFilters={setSelectedFilters}\n />\n )}\n <MTable<T>\n components={{\n Header: StyledMTableHeader,\n Body,\n Toolbar,\n ...components,\n }}\n options={options}\n columns={convertColumns(columns, theme)}\n icons={tableIcons}\n title={\n <>\n <Typography variant=\"h5\" component=\"h2\">\n {title}\n </Typography>\n {subtitle && (\n <Typography color=\"textSecondary\" variant=\"body1\">\n {subtitle}\n </Typography>\n )}\n </>\n }\n data={tableData}\n style={{ width: '100%', ...style }}\n localization={{\n ...localization,\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n ...localization?.body,\n },\n pagination: {\n firstTooltip: t('table.pagination.firstTooltip'),\n labelDisplayedRows: t('table.pagination.labelDisplayedRows'),\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n lastTooltip: t('table.pagination.lastTooltip'),\n nextTooltip: t('table.pagination.nextTooltip'),\n previousTooltip: t('table.pagination.previousTooltip'),\n ...localization?.pagination,\n },\n header: {\n actions: t('table.header.actions'),\n ...localization?.header,\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.search'),\n searchTooltip: t('table.toolbar.search'),\n ...localization?.toolbar,\n },\n }}\n {...restProps}\n />\n </Box>\n );\n}\n\nTable.icons = Object.freeze(tableIcons);\n\nfunction makeBody({\n columnCount,\n emptyContent,\n hasNoRows,\n loading,\n}: {\n hasNoRows: boolean;\n emptyContent: ReactNode;\n columnCount: number;\n loading?: boolean;\n}) {\n return (bodyProps: any /* no type for this in material-table */) => {\n if (loading) {\n return <TableLoadingBody colSpan={columnCount} />;\n }\n\n if (emptyContent && hasNoRows) {\n return (\n <tbody>\n <tr>\n <td colSpan={columnCount}>{emptyContent}</td>\n </tr>\n </tbody>\n );\n }\n\n return <MTableBody {...bodyProps} />;\n };\n}\n\nfunction constructFilters<T extends object>(\n filterConfig: TableFilter[],\n dataValue: any[] | undefined,\n columns: TableColumn<T>[],\n t: TranslationFunction<typeof coreComponentsTranslationRef.T>,\n): Filter[] {\n const extractDistinctValues = (field: string | keyof T): Set<any> => {\n const distinctValues = new Set<any>();\n const addValue = (value: any) => {\n if (value !== undefined && value !== null) {\n distinctValues.add(value);\n }\n };\n\n if (dataValue) {\n dataValue.forEach(el => {\n const value = extractValueByField(\n el,\n columns.find(c => c.title === field)?.field as string,\n );\n\n if (Array.isArray(value)) {\n (value as []).forEach(addValue);\n } else {\n addValue(value);\n }\n });\n }\n\n return distinctValues;\n };\n\n const constructSelect = (\n filter: TableFilter,\n ): Without<SelectProps, 'onChange'> => {\n return {\n placeholder: t('table.filter.placeholder'),\n label: filter.column,\n multiple: filter.type === 'multiple-select',\n items: [...extractDistinctValues(filter.column)].sort().map(value => ({\n label: value,\n value,\n })),\n };\n };\n\n return filterConfig.map(filter => ({\n type: filter.type,\n element: constructSelect(filter),\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 Box from '@material-ui/core/Box';\nimport MaterialBreadcrumbs from '@material-ui/core/Breadcrumbs';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport Popover from '@material-ui/core/Popover';\nimport { withStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport {\n MouseEvent,\n useState,\n Children,\n ComponentProps,\n Fragment,\n} from 'react';\n\ntype Props = ComponentProps<typeof MaterialBreadcrumbs>;\n\n/** @public */\nexport type BreadcrumbsClickableTextClassKey = 'root';\n\nconst ClickableText = withStyles(\n {\n root: {\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n },\n { name: 'BackstageBreadcrumbsClickableText' },\n)(Typography);\n\n/** @public */\nexport type BreadcrumbsStyledBoxClassKey = 'root';\n\nconst StyledBox = withStyles(\n {\n root: {\n textDecoration: 'underline',\n color: 'inherit',\n },\n },\n { name: 'BackstageBreadcrumbsStyledBox' },\n)(Box);\n\n/** @public */\nexport type BreadcrumbsCurrentPageClassKey = 'root';\n\nconst BreadcrumbsCurrentPage = withStyles(\n {\n root: {\n fontStyle: 'italic',\n },\n },\n { name: 'BreadcrumbsCurrentPage' },\n)(Box);\n\n/**\n * Breadcrumbs component to show navigation hierarchical structure\n *\n * @public\n *\n */\nexport function Breadcrumbs(props: Props) {\n const { children, ...restProps } = props;\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n\n const childrenArray = Children.toArray(children);\n\n const [firstPage, secondPage, ...expandablePages] = childrenArray;\n const currentPage = expandablePages.length\n ? expandablePages.pop()\n : childrenArray[childrenArray.length - 1];\n const hasHiddenBreadcrumbs = childrenArray.length > 3;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n const open = Boolean(anchorEl);\n return (\n <Fragment>\n <MaterialBreadcrumbs aria-label=\"breadcrumb\" {...restProps}>\n {childrenArray.length > 1 && <StyledBox clone>{firstPage}</StyledBox>}\n {childrenArray.length > 2 && <StyledBox clone>{secondPage}</StyledBox>}\n {hasHiddenBreadcrumbs && (\n <ClickableText onClick={handleClick}>...</ClickableText>\n )}\n <BreadcrumbsCurrentPage>{currentPage}</BreadcrumbsCurrentPage>\n </MaterialBreadcrumbs>\n <Popover\n open={open}\n anchorEl={anchorEl}\n onClose={handleClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n }}\n >\n <List>\n {expandablePages.map((pageLink, index) => (\n <ListItem key={index} button>\n <StyledBox clone>{pageLink}</StyledBox>\n </ListItem>\n ))}\n </List>\n </Popover>\n </Fragment>\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 { makeStyles, Theme } from '@material-ui/core/styles';\nimport classNames from 'classnames';\nimport { PropsWithChildren } from 'react';\n\n/** @public */\nexport type BackstageContentClassKey = 'root' | 'stretch' | 'noPadding';\n\nconst useStyles = makeStyles(\n (theme: Theme) => ({\n root: {\n gridArea: 'pageContent',\n minWidth: 0,\n paddingTop: theme.spacing(3),\n paddingBottom: theme.spacing(3),\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(2),\n [theme.breakpoints.up('sm')]: {\n paddingLeft: theme.spacing(3),\n paddingRight: theme.spacing(3),\n },\n },\n stretch: {\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n },\n noPadding: {\n padding: 0,\n },\n }),\n { name: 'BackstageContent' },\n);\n\ntype Props = {\n stretch?: boolean;\n noPadding?: boolean;\n className?: string;\n};\n\n/**\n * The main content part inside a {@link Page}.\n *\n * @public\n *\n */\n\nexport function Content(props: PropsWithChildren<Props>) {\n const { className, stretch, noPadding, children, ...restProps } = props;\n\n const classes = useStyles();\n return (\n <article\n {...restProps}\n className={classNames(classes.root, className, {\n [classes.stretch]: stretch,\n [classes.noPadding]: noPadding,\n })}\n >\n {children}\n </article>\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 */\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { PropsWithChildren, ReactNode } from 'react';\nimport { Helmet } from 'react-helmet';\n\n/**\n * TODO: favoriteable capability\n */\n\n/** @public */\nexport type ContentHeaderClassKey =\n | 'container'\n | 'leftItemsBox'\n | 'rightItemsBox'\n | 'description'\n | 'title';\n\nconst useStyles = (props: ContentHeaderProps) =>\n makeStyles(\n theme => ({\n container: {\n width: '100%',\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n alignItems: 'center',\n marginBottom: theme.spacing(2),\n textAlign: props.textAlign,\n },\n leftItemsBox: {\n flex: '1 1 auto',\n minWidth: 0,\n overflow: 'visible',\n },\n rightItemsBox: {\n flex: '0 1 auto',\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'center',\n marginLeft: theme.spacing(1),\n minWidth: 0,\n overflow: 'visible',\n },\n description: {},\n title: {\n display: 'inline-flex',\n marginBottom: 0,\n },\n }),\n { name: 'BackstageContentHeader' },\n );\n\ntype ContentHeaderTitleProps = {\n title?: string;\n className?: string;\n};\n\nconst ContentHeaderTitle = ({ title, className }: ContentHeaderTitleProps) => (\n <Typography\n variant=\"h4\"\n component=\"h2\"\n className={className}\n data-testid=\"header-title\"\n >\n {title}\n </Typography>\n);\n\ntype ContentHeaderDescriptionProps = {\n description?: string;\n className?: string;\n};\n\nconst ContentHeaderDescription = ({\n description,\n className,\n}: ContentHeaderDescriptionProps) =>\n description ? (\n <Typography\n variant=\"body2\"\n className={className}\n data-testid=\"header-description\"\n >\n {description}\n </Typography>\n ) : null;\n\ntype ContentHeaderProps = {\n title?: ContentHeaderTitleProps['title'];\n titleComponent?: ReactNode;\n description?: ContentHeaderDescriptionProps['description'];\n descriptionComponent?: ReactNode;\n textAlign?: 'left' | 'right' | 'center';\n};\n\n/**\n * A header at the top inside a {@link Content}.\n *\n * @public\n *\n */\n\nexport function ContentHeader(props: PropsWithChildren<ContentHeaderProps>) {\n const {\n description,\n title,\n titleComponent: TitleComponent = undefined,\n children,\n descriptionComponent: DescriptionComponent = undefined,\n textAlign = 'left',\n } = props;\n const classes = useStyles({ textAlign })();\n\n const renderedTitle = TitleComponent ? (\n TitleComponent\n ) : (\n <ContentHeaderTitle title={title} className={classes.title} />\n );\n\n const renderedDescription = DescriptionComponent ? (\n DescriptionComponent\n ) : (\n <ContentHeaderDescription\n description={description}\n className={classes.description}\n />\n );\n\n return (\n <>\n <Helmet title={title} />\n <Box className={classes.container}>\n <Box className={classes.leftItemsBox}>\n {renderedTitle}\n {renderedDescription}\n </Box>\n <Box className={classes.rightItemsBox}>{children}</Box>\n </Box>\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 { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport Grid from '@material-ui/core/Grid';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { CSSProperties, PropsWithChildren, ReactNode } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { Link } from '../../components/Link';\nimport { Breadcrumbs } from '../Breadcrumbs';\nimport { useContent } from '../Sidebar';\n\n/** @public */\nexport type HeaderClassKey =\n | 'header'\n | 'leftItemsBox'\n | 'rightItemsBox'\n | 'title'\n | 'subtitle'\n | 'type'\n | 'breadcrumb'\n | 'breadcrumbType'\n | 'breadcrumbTitle';\n\nconst useStyles = makeStyles(\n theme => ({\n header: {\n gridArea: 'pageHeader',\n padding: theme.spacing(3),\n width: '100%',\n boxShadow: theme.shadows[4],\n position: 'relative',\n zIndex: 100,\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n backgroundImage: theme.page.backgroundImage,\n backgroundPosition: 'center',\n backgroundSize: 'cover',\n [theme.breakpoints.down('sm')]: {\n flexWrap: 'wrap',\n },\n },\n leftItemsBox: {\n maxWidth: '100%',\n flexGrow: 1,\n },\n rightItemsBox: {\n width: 'auto',\n alignItems: 'center',\n },\n title: {\n color: theme.page.fontColor,\n wordBreak: 'break-word',\n fontSize: theme.typography.h3.fontSize,\n marginBottom: 0,\n },\n subtitle: {\n color: theme.page.fontColor,\n opacity: 0.8,\n display: 'inline-block', // prevents margin collapse of adjacent siblings\n marginTop: theme.spacing(1),\n maxWidth: '75ch',\n },\n type: {\n textTransform: 'uppercase',\n fontSize: 11,\n opacity: 0.8,\n marginBottom: theme.spacing(1),\n color: theme.page.fontColor,\n },\n breadcrumb: {\n color: theme.page.fontColor,\n },\n breadcrumbType: {\n fontSize: 'inherit',\n opacity: 0.7,\n marginRight: -theme.spacing(0.3),\n marginBottom: theme.spacing(0.3),\n },\n breadcrumbTitle: {\n fontSize: 'inherit',\n marginLeft: -theme.spacing(0.3),\n marginBottom: theme.spacing(0.3),\n },\n }),\n { name: 'BackstageHeader' },\n);\n\ntype HeaderStyles = ReturnType<typeof useStyles>;\n\ntype Props = {\n component?: ReactNode;\n pageTitleOverride?: string;\n style?: CSSProperties;\n subtitle?: ReactNode;\n title: ReactNode;\n tooltip?: string;\n type?: string;\n typeLink?: string;\n};\n\ntype TypeFragmentProps = {\n classes: HeaderStyles;\n pageTitle: string | ReactNode;\n type?: Props['type'];\n typeLink?: Props['typeLink'];\n};\n\ntype TitleFragmentProps = {\n classes: HeaderStyles;\n pageTitle: string | ReactNode;\n tooltip?: Props['tooltip'];\n};\n\ntype SubtitleFragmentProps = {\n classes: HeaderStyles;\n subtitle?: Props['subtitle'];\n};\n\nconst TypeFragment = ({\n type,\n typeLink,\n classes,\n pageTitle,\n}: TypeFragmentProps) => {\n if (!type) {\n return null;\n }\n\n if (!typeLink) {\n return <Typography className={classes.type}>{type}</Typography>;\n }\n\n return (\n <Breadcrumbs className={classes.breadcrumb}>\n <Link to={typeLink}>{type}</Link>\n <Typography>{pageTitle}</Typography>\n </Breadcrumbs>\n );\n};\n\nconst TitleFragment = ({ pageTitle, classes, tooltip }: TitleFragmentProps) => {\n const { contentRef } = useContent();\n\n const FinalTitle = (\n <Typography\n ref={contentRef}\n tabIndex={-1}\n className={classes.title}\n variant=\"h1\"\n >\n {pageTitle}\n </Typography>\n );\n\n if (!tooltip) {\n return FinalTitle;\n }\n\n return (\n <Tooltip title={tooltip} placement=\"top-start\">\n {FinalTitle}\n </Tooltip>\n );\n};\n\nconst SubtitleFragment = ({ classes, subtitle }: SubtitleFragmentProps) => {\n if (!subtitle) {\n return null;\n }\n\n if (typeof subtitle !== 'string') {\n return <>{subtitle}</>;\n }\n\n return (\n <Typography\n className={classes.subtitle}\n variant=\"subtitle2\"\n component=\"span\"\n >\n {subtitle}\n </Typography>\n );\n};\n/**\n * Backstage main header with abstract color background in multiple variants\n *\n * @public\n *\n */\nexport function Header(props: PropsWithChildren<Props>) {\n const {\n children,\n pageTitleOverride,\n style,\n subtitle,\n title,\n tooltip,\n type,\n typeLink,\n } = props;\n const classes = useStyles();\n const configApi = useApi(configApiRef);\n const appTitle = configApi.getOptionalString('app.title') || 'Backstage';\n const documentTitle = pageTitleOverride || title;\n const pageTitle = title || pageTitleOverride;\n const titleTemplate = `${documentTitle} | %s | ${appTitle}`;\n const defaultTitle = `${documentTitle} | ${appTitle}`;\n\n return (\n <>\n <Helmet titleTemplate={titleTemplate} defaultTitle={defaultTitle} />\n <header\n style={style}\n className={classes.header}\n data-backstage-core-header=\"\"\n >\n <Box className={classes.leftItemsBox}>\n <TypeFragment\n classes={classes}\n type={type}\n typeLink={typeLink}\n pageTitle={pageTitle}\n />\n <TitleFragment\n classes={classes}\n pageTitle={pageTitle}\n tooltip={tooltip}\n />\n <SubtitleFragment classes={classes} subtitle={subtitle} />\n </Box>\n <Grid container className={classes.rightItemsBox} spacing={4}>\n {children}\n </Grid>\n </header>\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 Grid from '@material-ui/core/Grid';\nimport { alpha, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { ReactNode, PropsWithChildren } from 'react';\nimport { Link } from '../../components/Link';\n\n/** @public */\nexport type HeaderLabelClassKey = 'root' | 'label' | 'value';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n textAlign: 'left',\n },\n label: {\n color: theme.page.fontColor,\n fontWeight: theme.typography.fontWeightBold,\n letterSpacing: 0,\n fontSize: theme.typography.fontSize,\n marginBottom: theme.spacing(1) / 2,\n lineHeight: 1,\n },\n value: {\n color: alpha(theme.page.fontColor, 0.8),\n fontSize: theme.typography.fontSize,\n lineHeight: 1,\n },\n }),\n { name: 'BackstageHeaderLabel' },\n);\n\ntype HeaderLabelContentProps = PropsWithChildren<{\n value: ReactNode;\n className: string;\n typographyRootComponent?: keyof JSX.IntrinsicElements;\n}>;\n\nconst HeaderLabelContent = ({\n value,\n className,\n typographyRootComponent,\n}: HeaderLabelContentProps) => {\n return (\n <Typography\n component={\n typographyRootComponent ?? (typeof value === 'string' ? 'p' : 'span')\n }\n className={className}\n >\n {value}\n </Typography>\n );\n};\n\ntype HeaderLabelProps = {\n label: string;\n value?: HeaderLabelContentProps['value'];\n contentTypograpyRootComponent?: HeaderLabelContentProps['typographyRootComponent'];\n url?: string;\n};\n\n/**\n * Additional label to main {@link Header}\n *\n * @public\n *\n */\nexport function HeaderLabel(props: HeaderLabelProps) {\n const { label, value, url, contentTypograpyRootComponent } = props;\n const classes = useStyles();\n const content = (\n <HeaderLabelContent\n className={classes.value}\n value={value || '<Unknown>'}\n typographyRootComponent={contentTypograpyRootComponent}\n />\n );\n return (\n <Grid item>\n <Typography component=\"span\" className={classes.root}>\n <Typography className={classes.label}>{label}</Typography>\n {url ? <Link to={url}>{content}</Link> : content}\n </Typography>\n </Grid>\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 { ReactNode } from 'react';\nimport { makeStyles, Theme, ThemeProvider } from '@material-ui/core/styles';\nimport classNames from 'classnames';\n\nexport type PageClassKey = 'root';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n display: 'grid',\n gridTemplateAreas:\n \"'pageHeader pageHeader pageHeader' 'pageSubheader pageSubheader pageSubheader' 'pageNav pageContent pageSidebar'\",\n gridTemplateRows: 'max-content auto 1fr',\n gridTemplateColumns: 'auto 1fr auto',\n overflowY: 'auto',\n height: '100vh',\n [theme.breakpoints.down('xs')]: {\n height: '100%',\n },\n '@media print': {\n display: 'block',\n height: 'auto',\n overflowY: 'inherit',\n },\n },\n }),\n { name: 'BackstagePage' },\n);\n\ntype Props = {\n themeId: string;\n className?: string;\n children?: ReactNode;\n};\n\nexport function Page(props: Props) {\n const { themeId, className, children } = props;\n const classes = useStyles();\n return (\n <ThemeProvider\n theme={(baseTheme: Theme) => ({\n ...baseTheme,\n page: baseTheme.getPageTheme({ themeId }),\n })}\n >\n <main\n className={classNames(classes.root, className)}\n data-backstage-core-page=\"\"\n >\n {children}\n </main>\n </ThemeProvider>\n );\n}\n","/*\n * Copyright 2021 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 { useParams } from 'react-router-dom';\nimport { RouteRef, AnyParams, SubRouteRef } from './types';\n\n/**\n * React hook for retrieving dynamic params from the current URL.\n * @param _routeRef - Ref of the current route.\n * @public\n */\nexport function useRouteRefParams<Params extends AnyParams>(\n _routeRef: RouteRef<Params> | SubRouteRef<Params>,\n): Params {\n return useParams() as Params;\n}\n","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type { ButtonLinkOwnProps } from './types';\nimport styles from './ButtonLink.module.css';\n\n/**\n * Component definition for ButtonLink\n * @public\n */\nexport const ButtonLinkDefinition = defineComponent<ButtonLinkOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ButtonLink',\n content: 'bui-ButtonLinkContent',\n },\n bg: 'consumer',\n analytics: true,\n navigation: { type: 'anchor' },\n propDefs: {\n noTrack: {},\n size: { dataAttribute: true, default: 'small' },\n variant: { dataAttribute: true, default: 'primary' },\n iconStart: {},\n iconEnd: {},\n children: {},\n className: {},\n },\n});\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-ButtonLink\":\"NVumjJIcc4YzsPM1\",\"bui-ButtonLinkContent\":\"eJ5wbzSvC_Y7eHDP\"};","/*\n * Copyright 2024 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 { forwardRef, Ref } from 'react';\nimport { Link as RALink } from 'react-aria-components';\nimport type { ButtonLinkProps } from './types';\nimport {\n useDefinition,\n type UseDefinitionResult,\n} from '../../hooks/useDefinition';\nimport { ButtonLinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\nimport {\n getReactAriaAnchorProps,\n type AnchorNavigation,\n} from '../../navigation/useNavigation';\n\ntype ButtonLinkViewProps = {\n definitionResult: UseDefinitionResult<\n typeof ButtonLinkDefinition,\n ButtonLinkProps\n >;\n navigation: AnchorNavigation;\n forwardedRef: Ref<HTMLAnchorElement>;\n};\n\nfunction ButtonLinkView({\n definitionResult,\n navigation,\n forwardedRef,\n}: ButtonLinkViewProps) {\n const { ownProps, restProps, dataAttributes, analytics } = definitionResult;\n const { classes, iconStart, iconEnd, children } = ownProps;\n const navigationProps = restProps.isDisabled\n ? { href: undefined, routerOptions: undefined, render: undefined }\n : getReactAriaAnchorProps(navigation, restProps);\n\n const handlePress: typeof restProps.onPress = e => {\n restProps.onPress?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <RALink\n className={classes.root}\n ref={forwardedRef}\n {...dataAttributes}\n {...restProps}\n {...navigationProps}\n onPress={handlePress}\n >\n <span className={classes.content}>\n {iconStart}\n {children}\n {iconEnd}\n </span>\n </RALink>\n );\n}\n\n/**\n * A button-styled anchor element for navigation, supporting optional start and end icon slots and analytics event tracking.\n *\n * @public\n */\nexport const ButtonLink = forwardRef(\n (props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {\n const definitionResult = useDefinition(ButtonLinkDefinition, props);\n const Navigation = definitionResult.navigation;\n\n return (\n <Navigation\n props={definitionResult.restProps}\n view={ButtonLinkView}\n viewProps={{ definitionResult, forwardedRef: ref }}\n />\n );\n },\n);\n\nButtonLink.displayName = 'ButtonLink';\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-Card\":\"vwbKbDh04mMaiBi3\",\"bui-CardHeader\":\"XFUmGkj6WID_JnEz\",\"bui-CardBody\":\"bDKBEHaUGVdvGxpS\",\"bui-CardFooter\":\"htqU_uAkxL89C8of\",\"bui-CardTrigger\":\"YH9iVtgxrw5b0cYJ\",\"bui-card-body-shadow\":\"bJ7HlUi_25Q2Dxr7\"};","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type {\n CardOwnProps,\n CardHeaderOwnProps,\n CardBodyOwnProps,\n CardFooterOwnProps,\n} from './types';\nimport styles from './Card.module.css';\n\n/**\n * Component definition for Card\n * @public\n */\nexport const CardDefinition = defineComponent<CardOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Card',\n trigger: 'bui-CardTrigger',\n },\n propDefs: {\n children: {},\n className: {},\n onPress: {},\n href: {},\n label: {},\n target: {},\n rel: {},\n download: {},\n style: {},\n },\n utilityProps: ['grow', 'shrink', 'basis'],\n});\n\n/**\n * Component definition for CardHeader\n * @public\n */\nexport const CardHeaderDefinition = defineComponent<CardHeaderOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardHeader',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n\n/**\n * Component definition for CardBody\n * @public\n */\nexport const CardBodyDefinition = defineComponent<CardBodyOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardBody',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n\n/**\n * Component definition for CardFooter\n * @public\n */\nexport const CardFooterDefinition = defineComponent<CardFooterOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardFooter',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n","/*\n * Copyright 2024 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 { forwardRef, useCallback, useRef } from 'react';\nimport { Button as RAButton } from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n CardDefinition,\n CardHeaderDefinition,\n CardBodyDefinition,\n CardFooterDefinition,\n} from './definition';\nimport type {\n CardProps,\n CardHeaderProps,\n CardBodyProps,\n CardFooterProps,\n} from './types';\nimport { Box } from '../Box/Box';\nimport { Link } from '../Link';\n\nconst INTERACTIVE_ELEMENT_SELECTOR =\n 'a[href],button,input,select,textarea,[role=\"button\"],[role=\"link\"],[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Card component.\n *\n * @public\n */\nexport const Card = forwardRef<HTMLDivElement, CardProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, utilityStyle } = useDefinition(\n CardDefinition,\n props,\n );\n const {\n classes,\n children,\n onPress,\n href,\n label,\n target: linkTarget,\n rel,\n download,\n } = ownProps;\n const isInteractive = !!(onPress || href);\n\n const triggerRef = useRef<HTMLAnchorElement | HTMLButtonElement>(null);\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (!isInteractive || !triggerRef.current) return;\n\n // Don't delegate if the click target is the trigger itself\n if (triggerRef.current.contains(e.target as Node)) return;\n\n // Don't delegate if the user clicked a nested interactive element\n const targetNode = e.target as Node | null;\n const targetElement =\n targetNode instanceof Element ? targetNode : targetNode?.parentElement;\n if (targetElement?.closest(INTERACTIVE_ELEMENT_SELECTOR)) return;\n\n // Don't delegate if the user is selecting text\n if (window.getSelection()?.toString()) return;\n\n triggerRef.current.dispatchEvent(\n new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n altKey: e.altKey,\n }),\n );\n },\n [isInteractive],\n );\n\n return (\n <Box\n as=\"article\"\n bg=\"neutral\"\n ref={ref}\n className={classes.root}\n data-interactive={isInteractive || undefined}\n {...dataAttributes}\n {...restProps}\n onClick={isInteractive ? handleClick : undefined}\n style={{ ...utilityStyle, ...ownProps.style }}\n >\n {href && (\n <Link\n ref={triggerRef as React.Ref<HTMLAnchorElement>}\n className={classes.trigger}\n href={href}\n target={linkTarget}\n rel={rel}\n download={download}\n aria-label={label}\n />\n )}\n {onPress && !href && (\n <RAButton\n ref={triggerRef as React.Ref<HTMLButtonElement>}\n className={classes.trigger}\n onPress={onPress}\n aria-label={label}\n />\n )}\n {children}\n </Box>\n );\n});\n\nCard.displayName = 'Card';\n\n/**\n * CardHeader component.\n *\n * @public\n */\nexport const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardHeaderDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardHeader.displayName = 'CardHeader';\n\n/**\n * CardBody component.\n *\n * @public\n */\nexport const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardBodyDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardBody.displayName = 'CardBody';\n\n/**\n * CardFooter component.\n *\n * @public\n */\nexport const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardFooterDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardFooter.displayName = 'CardFooter';\n","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type { ContainerOwnProps } from './types';\nimport styles from './Container.module.css';\n\n/**\n * Component definition for Container\n * @public\n */\nexport const ContainerDefinition = defineComponent<ContainerOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Container',\n },\n propDefs: {\n children: {},\n className: {},\n style: {},\n },\n utilityProps: ['my', 'mt', 'mb', 'py', 'pt', 'pb', 'display'],\n});\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-Container\":\"j9YF9y0JMsI4PdI6\"};","/*\n * Copyright 2024 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 { forwardRef } from 'react';\nimport type { ContainerProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ContainerDefinition } from './definition';\n\n/**\n * A centered layout wrapper that constrains content to a maximum width and provides consistent page-level padding.\n *\n * @public\n */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(\n (props, ref) => {\n const { ownProps, restProps, utilityStyle } = useDefinition(\n ContainerDefinition,\n props,\n );\n const { classes, children, style } = ownProps;\n\n return (\n <div\n ref={ref}\n className={classes.root}\n style={{ ...utilityStyle, ...style }}\n {...restProps}\n >\n {children}\n </div>\n );\n },\n);\n\nContainer.displayName = 'Container';\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-HeaderNav\":\"Se1MR2xlkoYuuKzh\",\"bui-HeaderNavList\":\"vv3j5mY2O0cI5ygv\",\"bui-HeaderNavItem\":\"c6iehTLRy0kKCOcK\",\"bui-HeaderNavGroup\":\"UXkc2kZp0RMXPoJG\",\"bui-HeaderNavActive\":\"q5ojXgJ30ggFPnjw\",\"bui-HeaderNavHovered\":\"DfuW_HHgCkAZgy8z\"};","/*\n * Copyright 2026 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 { defineComponent } from '../../hooks/useDefinition';\nimport type { HeaderNavTabItem, HeaderNavLinkProps } from './types';\nimport styles from './HeaderNav.module.css';\n\n/** @public */\nexport const HeaderNavDefinition = defineComponent<{\n tabs: HeaderNavTabItem[];\n activeTabId?: string | null;\n children?: React.ReactNode;\n className?: string;\n}>()({\n styles,\n classNames: {\n root: 'bui-HeaderNav',\n list: 'bui-HeaderNavList',\n active: 'bui-HeaderNavActive',\n hovered: 'bui-HeaderNavHovered',\n },\n propDefs: {\n tabs: {},\n activeTabId: {},\n children: {},\n className: {},\n },\n});\n\n/** @public */\nexport const HeaderNavItemDefinition = defineComponent<HeaderNavLinkProps>()({\n styles,\n classNames: {\n root: 'bui-HeaderNavItem',\n },\n analytics: true,\n navigation: { type: 'anchor' },\n propDefs: {\n noTrack: {},\n id: {},\n label: {},\n href: {},\n active: {},\n registerRef: {},\n onHighlight: {},\n className: {},\n },\n});\n\n/** @public */\nexport const HeaderNavGroupDefinition = defineComponent<{\n className?: string;\n}>()({\n styles,\n classNames: {\n root: 'bui-HeaderNavGroup',\n },\n propDefs: {\n className: {},\n },\n});\n","/*\n * Copyright 2026 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 { useCallback, useEffect, useRef } from 'react';\n\ninterface HeaderNavIndicatorsProps {\n navRef: React.RefObject<HTMLElement | null>;\n itemRefs: React.MutableRefObject<Map<string, HTMLElement>>;\n activeKey: string | undefined;\n highlightedKey: string | null;\n classes: {\n active: string;\n hovered: string;\n };\n}\n\nexport function HeaderNavIndicators(props: HeaderNavIndicatorsProps) {\n const { navRef, itemRefs, activeKey, highlightedKey, classes } = props;\n const prevActiveKey = useRef<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n const resetTimer = useRef<number | null>(null);\n\n const updateCSSVariables = useCallback(() => {\n const container = navRef.current;\n if (!container) return;\n\n const containerRect = container.getBoundingClientRect();\n\n // Active indicator\n if (activeKey) {\n const el = itemRefs.current.get(activeKey);\n if (el) {\n const rect = el.getBoundingClientRect();\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n\n if (prevActiveKey.current === null) {\n container.style.setProperty('--active-transition-duration', '0s');\n requestAnimationFrame(() => {\n container.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n });\n } else {\n container.style.setProperty('--active-transition-duration', '0.25s');\n }\n\n container.style.setProperty('--active-tab-left', `${relativeLeft}px`);\n container.style.setProperty('--active-tab-width', `${rect.width}px`);\n container.style.setProperty('--active-tab-height', `${rect.height}px`);\n container.style.setProperty('--active-tab-top', `${relativeTop}px`);\n container.style.setProperty('--active-tab-opacity', '1');\n prevActiveKey.current = activeKey;\n }\n } else {\n container.style.setProperty('--active-tab-opacity', '0');\n prevActiveKey.current = null;\n }\n\n // Highlight indicator (follows whichever interaction happened last — hover or focus)\n if (highlightedKey) {\n if (resetTimer.current !== null) {\n cancelAnimationFrame(resetTimer.current);\n resetTimer.current = null;\n }\n const el = itemRefs.current.get(highlightedKey);\n if (el) {\n const rect = el.getBoundingClientRect();\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n\n if (prevHoveredKey.current === null) {\n container.style.setProperty('--hovered-transition-duration', '0s');\n requestAnimationFrame(() => {\n container.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n });\n } else {\n container.style.setProperty('--hovered-transition-duration', '0.2s');\n }\n\n container.style.setProperty('--hovered-tab-left', `${relativeLeft}px`);\n container.style.setProperty('--hovered-tab-top', `${relativeTop}px`);\n container.style.setProperty('--hovered-tab-width', `${rect.width}px`);\n container.style.setProperty('--hovered-tab-height', `${rect.height}px`);\n container.style.setProperty('--hovered-tab-opacity', '1');\n prevHoveredKey.current = highlightedKey;\n }\n } else {\n container.style.setProperty('--hovered-tab-opacity', '0');\n resetTimer.current = requestAnimationFrame(() => {\n prevHoveredKey.current = null;\n resetTimer.current = null;\n });\n }\n }, [activeKey, highlightedKey, navRef, itemRefs]);\n\n useEffect(() => {\n updateCSSVariables();\n }, [updateCSSVariables]);\n\n useEffect(() => {\n const handleResize = () => updateCSSVariables();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [updateCSSVariables]);\n\n return (\n <>\n <div className={classes.active} />\n <div className={classes.hovered} />\n </>\n );\n}\n","/*\n * Copyright 2026 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 { useCallback, useMemo, useRef, useState } from 'react';\nimport { mergeProps, useFocusVisible, useHover, useLink } from 'react-aria';\nimport {\n matchRoutes,\n resolvePath,\n type NavigateOptions,\n} from 'react-router-dom';\nimport { Button as RAButton } from 'react-aria-components';\nimport { RiArrowDownSLine } from '@remixicon/react';\nimport {\n useDefinition,\n type UseDefinitionResult,\n} from '../../hooks/useDefinition';\nimport {\n HeaderNavDefinition,\n HeaderNavItemDefinition,\n HeaderNavGroupDefinition,\n} from './HeaderNavDefinition';\nimport { HeaderNavIndicators } from './HeaderNavIndicators';\nimport { MenuTrigger, Menu, MenuItem } from '../Menu';\nimport type {\n HeaderNavLinkProps,\n HeaderNavTabGroup,\n HeaderNavTabItem,\n} from './types';\nimport { useRoutingIntegration } from '../../navigation/useRouting';\nimport type { AnchorNavigation } from '../../navigation/useNavigation';\n\nfunction isTabGroup(tab: HeaderNavTabItem): tab is HeaderNavTabGroup {\n return 'items' in tab;\n}\n\ntype HeaderNavLinkViewProps = {\n definitionResult: UseDefinitionResult<\n typeof HeaderNavItemDefinition,\n HeaderNavLinkProps\n >;\n navigation: AnchorNavigation;\n};\n\nfunction HeaderNavLinkView({\n definitionResult,\n navigation,\n}: HeaderNavLinkViewProps) {\n const { ownProps, analytics } = definitionResult;\n const { id, label, active, registerRef, onHighlight } = ownProps;\n const { href } = ownProps;\n\n const linkRef = useRef<HTMLAnchorElement>(null);\n let ariaHref = href;\n let routerOptions: NavigateOptions | undefined;\n if (navigation.type === 'router') {\n ariaHref = navigation.ariaHref;\n routerOptions = navigation.routerOptions;\n } else if (navigation.type === 'native') {\n ariaHref = navigation.ariaHref;\n }\n const { linkProps } = useLink(\n {\n href: ariaHref,\n routerOptions,\n },\n linkRef,\n );\n const { hoverProps } = useHover({\n onHoverStart: () => onHighlight(id),\n onHoverEnd: () => onHighlight(null),\n });\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n analytics.captureEvent('click', label, {\n attributes: { to: href },\n });\n };\n const { href: _href, ...anchorProps } = mergeProps(\n linkProps,\n hoverProps,\n ) as React.AnchorHTMLAttributes<HTMLAnchorElement>;\n const ref = (el: HTMLAnchorElement | null) => {\n (linkRef as React.MutableRefObject<HTMLAnchorElement | null>).current = el;\n registerRef(id, el);\n };\n const commonProps = {\n ...anchorProps,\n ref,\n className: ownProps.classes.root,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n onFocus: () => onHighlight(id),\n onBlur: () => onHighlight(null),\n children: label,\n };\n const browserHref =\n navigation.type === 'native' ? navigation.browserHref : href;\n\n return (\n <li>\n {navigation.type === 'router' ? (\n <navigation.Link\n {...commonProps}\n {...navigation.routerLinkOptions}\n to={navigation.to}\n />\n ) : (\n <a {...commonProps} href={browserHref} />\n )}\n </li>\n );\n}\n\nfunction HeaderNavLink(props: HeaderNavLinkProps) {\n const definitionResult = useDefinition(HeaderNavItemDefinition, props);\n const Navigation = definitionResult.navigation;\n\n return (\n <Navigation\n props={{ href: definitionResult.ownProps.href }}\n view={HeaderNavLinkView}\n viewProps={{ definitionResult }}\n />\n );\n}\n\ninterface HeaderNavGroupItemProps {\n group: HeaderNavTabGroup;\n active: boolean;\n activeChildId?: string;\n registerRef: (key: string, el: HTMLElement | null) => void;\n onHighlight: (key: string | null) => void;\n}\n\nfunction HeaderNavGroupItem(props: HeaderNavGroupItemProps) {\n const { group, active, activeChildId, registerRef, onHighlight } = props;\n const { ownProps } = useDefinition(HeaderNavGroupDefinition, {});\n const { hoverProps } = useHover({\n onHoverStart: () => onHighlight(group.id),\n onHoverEnd: () => onHighlight(null),\n });\n\n return (\n <li>\n <MenuTrigger>\n <RAButton\n ref={el => {\n registerRef(group.id, el);\n }}\n className={ownProps.classes.root}\n aria-current={active ? 'page' : undefined}\n {...hoverProps}\n onFocus={() => onHighlight(group.id)}\n onBlur={() => onHighlight(null)}\n >\n {group.label}\n <RiArrowDownSLine size={16} />\n </RAButton>\n <Menu\n selectionMode=\"single\"\n selectedKeys={new Set(activeChildId ? [activeChildId] : [])}\n >\n {group.items.map(item => (\n <MenuItem key={item.id} id={item.id} href={item.href}>\n {item.label}\n </MenuItem>\n ))}\n </Menu>\n </MenuTrigger>\n </li>\n );\n}\n\ninterface HeaderNavProps {\n tabs: HeaderNavTabItem[];\n activeTabId?: string | null;\n}\n\nfunction useAutoActiveTabId(tabs: HeaderNavTabItem[]): string | undefined {\n const routing = useRoutingIntegration({ fallback: true });\n const basePath = routing.useResolvedPath('.').pathname;\n const { pathname } = routing.useLocation();\n\n return useMemo(() => {\n const allTabs = tabs.flatMap(tab => (isTabGroup(tab) ? tab.items : [tab]));\n const routeObjects = allTabs.map(tab => ({\n path: `${resolvePath(tab.href, basePath).pathname}/*`,\n id: tab.id,\n }));\n const matches = matchRoutes(routeObjects, pathname);\n return matches?.[0]?.route.id;\n }, [tabs, basePath, pathname]);\n}\n\nfunction HeaderNavAutoDetect(props: { tabs: HeaderNavTabItem[] }) {\n const activeTabId = useAutoActiveTabId(props.tabs);\n return <HeaderNavInner tabs={props.tabs} activeTabId={activeTabId} />;\n}\n\nfunction HeaderNavInner(props: HeaderNavProps) {\n const { tabs, activeTabId } = props;\n const { ownProps } = useDefinition(HeaderNavDefinition, {\n tabs,\n activeTabId,\n });\n const { classes } = ownProps;\n\n const { isFocusVisible } = useFocusVisible();\n const navRef = useRef<HTMLElement>(null);\n const itemRefs = useRef<Map<string, HTMLElement>>(new Map());\n\n const [highlightedKey, setHighlightedKey] = useState<string | null>(null);\n\n // Resolve activeTabId to a top-level key (groups own their children's active state)\n const { activeKey, activeChildId } = useMemo(() => {\n if (!activeTabId) return { activeKey: undefined, activeChildId: undefined };\n for (const item of tabs) {\n if (isTabGroup(item)) {\n const child = item.items.find(c => c.id === activeTabId);\n if (child) {\n return { activeKey: item.id, activeChildId: child.id };\n }\n } else if (item.id === activeTabId) {\n return { activeKey: item.id, activeChildId: undefined };\n }\n }\n return { activeKey: undefined, activeChildId: undefined };\n }, [activeTabId, tabs]);\n\n const registerRef = useCallback((key: string, el: HTMLElement | null) => {\n if (el) {\n itemRefs.current.set(key, el);\n } else {\n itemRefs.current.delete(key);\n }\n }, []);\n\n return (\n <nav\n ref={navRef}\n aria-label=\"Content navigation\"\n className={classes.root}\n data-focus-visible={isFocusVisible || undefined}\n >\n <ul role=\"list\" className={classes.list}>\n {tabs.map(item =>\n isTabGroup(item) ? (\n <HeaderNavGroupItem\n key={item.id}\n group={item}\n active={activeKey === item.id}\n activeChildId={activeChildId}\n registerRef={registerRef}\n onHighlight={setHighlightedKey}\n />\n ) : (\n <HeaderNavLink\n key={item.id}\n id={item.id}\n label={item.label}\n href={item.href}\n active={activeKey === item.id}\n registerRef={registerRef}\n onHighlight={setHighlightedKey}\n />\n ),\n )}\n </ul>\n <HeaderNavIndicators\n navRef={navRef}\n itemRefs={itemRefs}\n activeKey={activeKey}\n highlightedKey={highlightedKey}\n classes={{ active: classes.active, hovered: classes.hovered }}\n />\n </nav>\n );\n}\n\n/** @internal */\nexport function HeaderNav(props: HeaderNavProps) {\n const routing = useRoutingIntegration({ fallback: true });\n const inRouter = routing.useInRouterContext();\n\n if (props.activeTabId === undefined && inRouter) {\n return <HeaderNavAutoDetect tabs={props.tabs} />;\n }\n\n return <HeaderNavInner tabs={props.tabs} activeTabId={props.activeTabId} />;\n}\n","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type { HeaderOwnProps } from './types';\nimport styles from './Header.module.css';\n\n/**\n * Component definition for Header\n * @public\n */\nexport const HeaderDefinition = defineComponent<HeaderOwnProps>()({\n styles,\n bg: 'consumer',\n classNames: {\n headerTop: 'bui-HeaderTop',\n stickySentinel: 'bui-HeaderStickySentinel',\n content: 'bui-HeaderContent',\n headerBottom: 'bui-HeaderBottom',\n breadcrumbs: 'bui-HeaderBreadcrumbs',\n breadcrumbsSmall: 'bui-HeaderBreadcrumbsSmall',\n breadcrumbLink: 'bui-HeaderBreadcrumbLink',\n breadcrumbLinkSmall: 'bui-HeaderBreadcrumbLinkSmall',\n breadcrumbSeparator: 'bui-HeaderBreadcrumbSeparator',\n titleStack: 'bui-HeaderTitleStack',\n title: 'bui-HeaderTitle',\n titleSmall: 'bui-HeaderTitleSmall',\n tabsWrapper: 'bui-HeaderTabsWrapper',\n controls: 'bui-HeaderControls',\n tags: 'bui-HeaderTags',\n tag: 'bui-HeaderTag',\n description: 'bui-HeaderDescription',\n metaRow: 'bui-HeaderMetaRow',\n metaItem: 'bui-HeaderMetaItem',\n },\n propDefs: {\n title: {},\n customActions: {},\n tabs: {},\n activeTabId: {},\n breadcrumbs: {},\n description: {},\n tags: {},\n metadata: {},\n className: {},\n sticky: {},\n },\n});\n\n/**\n * @public\n * @deprecated Use {@link HeaderDefinition} instead.\n */\nexport const HeaderPageDefinition = HeaderDefinition;\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-HeaderTop\":\"d6yO0l4zz3McSdPg\",\"bui-HeaderContent\":\"hxIvk7f5W8T4u0_x\",\"bui-HeaderBottom\":\"sBCid7jAqHsYIqrc\",\"bui-HeaderStickySentinel\":\"kgD85NRPA0_J5Iqx\",\"bui-HeaderTabsWrapper\":\"bmVIsoUAhPwZBrh_\",\"bui-HeaderControls\":\"UuTgL1HrLw8aKiHC\",\"bui-HeaderTitleStack\":\"w9_h0inOJpAMDApB\",\"bui-HeaderBreadcrumbs\":\"JmA59TJW3k6oKPSn\",\"bui-HeaderBreadcrumbsSmall\":\"QSVW3yKFsQP6ay8p\",\"bui-HeaderBreadcrumbLink\":\"SPZSvNw8pXooRGZu\",\"bui-HeaderBreadcrumbLinkSmall\":\"bRhhaD21XwcEowH6\",\"bui-HeaderBreadcrumbSeparator\":\"q6r_2qtCYEk5f5C9\",\"bui-HeaderTitle\":\"CyePbw1pK5EaaY97\",\"bui-HeaderTitleSmall\":\"lICQaeQ7nwoibiTw\",\"bui-HeaderTags\":\"R9Lx7hYf6AHO68V8\",\"bui-HeaderTag\":\"rEvQyPKFaVAQxtKb\",\"bui-HeaderMetaRow\":\"EQFjSGwLsNsPXHwU\",\"bui-HeaderMetaItem\":\"NlFYkGgXGOEb2VXg\"};","/*\n * Copyright 2025 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 type { HeaderProps } from './types';\nimport { Text } from '../Text';\nimport { RiArrowRightSLine } from '@remixicon/react';\nimport { HeaderNav } from './HeaderNav';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { HeaderDefinition } from './definition';\nimport { sanitizeUrl } from '@braintree/sanitize-url';\nimport { Lexer } from 'marked';\nimport { Link } from '../Link';\nimport { Fragment, useEffect, useMemo, useRef, useState } from 'react';\nimport { Container } from '../Container';\n\nconst getScrollParent = (element: HTMLElement | null): Element | null => {\n let parent = element?.parentElement;\n\n while (parent) {\n const { overflow, overflowX, overflowY } = window.getComputedStyle(parent);\n\n if (\n /(auto|scroll|overlay|hidden)/.test(`${overflow}${overflowX}${overflowY}`)\n ) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return null;\n};\n\nconst isStickySentinelOutOfView = (\n sentinel: HTMLElement,\n root: Element | null,\n) => {\n const sentinelRect = sentinel.getBoundingClientRect();\n const rootTop = root ? root.getBoundingClientRect().top : 0;\n\n return sentinelRect.bottom <= rootTop;\n};\n\n/**\n * Parses inline Markdown links in a string and returns an array of React nodes.\n * URLs are sanitized via `@braintree/sanitize-url`; unsafe URLs are rendered as\n * plain text. Uses `marked` instead of `react-markdown` to avoid ESM issues.\n */\nfunction renderInlineMarkdown(text: string): React.ReactNode[] {\n return Lexer.lexInline(text).map((token, i) => {\n if (token.type === 'link') {\n const href = sanitizeUrl(token.href);\n if (href === 'about:blank') return token.text;\n return (\n <Link key={i} href={href} standalone>\n {token.text}\n </Link>\n );\n }\n return token.raw;\n });\n}\n\n/**\n * A secondary header with title, breadcrumbs, tabs, and actions.\n *\n * @public\n */\nexport const Header = (props: HeaderProps) => {\n const { ownProps, dataAttributes } = useDefinition(HeaderDefinition, props, {\n classNameTarget: 'content',\n });\n const {\n classes,\n title,\n tabs,\n activeTabId,\n customActions,\n breadcrumbs,\n description,\n tags,\n metadata,\n sticky,\n } = ownProps;\n\n const descriptionNodes = useMemo(\n () => (description ? renderInlineMarkdown(description) : null),\n [description],\n );\n\n // The sentinel sits directly before the sticky content and leaves the\n // viewport when the content becomes stuck, letting us toggle stuck styling.\n const stickySentinelRef = useRef<HTMLDivElement>(null);\n const [isStuck, setIsStuck] = useState(false);\n\n useEffect(() => {\n if (!sticky) {\n setIsStuck(false);\n return;\n }\n\n const sentinel = stickySentinelRef.current;\n if (!sentinel) {\n return;\n }\n\n const root = getScrollParent(sentinel);\n\n if (typeof IntersectionObserver === 'undefined') {\n const updateStuckState = () => {\n setIsStuck(isStickySentinelOutOfView(sentinel, root));\n };\n const scrollTarget = root ?? window;\n\n updateStuckState();\n scrollTarget.addEventListener('scroll', updateStuckState, {\n passive: true,\n });\n window.addEventListener('resize', updateStuckState);\n\n return () => {\n scrollTarget.removeEventListener('scroll', updateStuckState);\n window.removeEventListener('resize', updateStuckState);\n };\n }\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n setIsStuck(!entry.isIntersecting);\n },\n { root, threshold: 0 },\n );\n\n observer.observe(sentinel);\n\n return () => {\n observer.disconnect();\n };\n }, [sticky]);\n\n return (\n <>\n <Container\n className={classes.headerTop}\n data-sticky={sticky || undefined}\n >\n {tags && tags.length > 0 && (\n <ul className={classes.tags}>\n {tags.map((tag, i) => (\n <li\n key={`${i}:${tag.label}:${tag.href ?? ''}`}\n className={classes.tag}\n >\n {tag.href ? (\n <Link\n href={tag.href}\n variant=\"body-medium\"\n color=\"secondary\"\n standalone\n >\n {tag.label}\n </Link>\n ) : (\n <Text variant=\"body-medium\" color=\"secondary\">\n {tag.label}\n </Text>\n )}\n </li>\n ))}\n </ul>\n )}\n </Container>\n {sticky && (\n <div\n ref={stickySentinelRef}\n className={classes.stickySentinel}\n data-sticky=\"\"\n aria-hidden=\"true\"\n />\n )}\n <Container\n className={classes.content}\n data-sticky={sticky || undefined}\n data-stuck={isStuck || undefined}\n data-has-tags={tags && tags.length > 0 ? '' : undefined}\n {...dataAttributes}\n >\n <div className={classes.titleStack}>\n {isStuck ? (\n <div className={classes.breadcrumbsSmall}>\n {breadcrumbs &&\n breadcrumbs.map(breadcrumb => (\n <Fragment key={breadcrumb.label}>\n <Link\n href={breadcrumb.href}\n color=\"secondary\"\n className={classes.breadcrumbLinkSmall}\n standalone\n >\n {breadcrumb.label}\n </Link>\n <RiArrowRightSLine\n className={classes.breadcrumbSeparator}\n size={16}\n color=\"var(--bui-fg-secondary)\"\n />\n </Fragment>\n ))}\n <h2 className={classes.titleSmall}>{title}</h2>\n </div>\n ) : (\n <div className={classes.breadcrumbs}>\n {breadcrumbs &&\n breadcrumbs.map(breadcrumb => (\n <Fragment key={breadcrumb.label}>\n <Link\n href={breadcrumb.href}\n color=\"secondary\"\n className={classes.breadcrumbLink}\n standalone\n >\n {breadcrumb.label}\n </Link>\n <RiArrowRightSLine\n className={classes.breadcrumbSeparator}\n size={16}\n color=\"var(--bui-fg-secondary)\"\n />\n </Fragment>\n ))}\n <h2 className={classes.title}>{title}</h2>\n </div>\n )}\n </div>\n <div className={classes.controls}>{customActions}</div>\n </Container>\n <Container\n className={classes.headerBottom}\n data-sticky={sticky || undefined}\n >\n {description && (\n <Text\n variant=\"body-medium\"\n color=\"secondary\"\n className={classes.description}\n >\n {descriptionNodes}\n </Text>\n )}\n {metadata && metadata.length > 0 && (\n <dl className={classes.metaRow}>\n {metadata.map((item, i) => (\n <div key={`${i}:${item.label}`} className={classes.metaItem}>\n <dt>\n <Text variant=\"body-medium\" color=\"secondary\">\n {item.label}\n </Text>\n </dt>\n <dd>\n {typeof item.value === 'string' ? (\n <Text variant=\"body-medium\">{item.value}</Text>\n ) : (\n item.value\n )}\n </dd>\n </div>\n ))}\n </dl>\n )}\n {tabs && (\n <div className={classes.tabsWrapper}>\n <HeaderNav tabs={tabs} activeTabId={activeTabId} />\n </div>\n )}\n </Container>\n </>\n );\n};\n\n/**\n * @public\n * @deprecated Use {@link Header} instead.\n */\nexport const HeaderPage = Header;\n","/*\n * Copyright 2026 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 CompoundEntityRef,\n Entity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n EntityPresentationApi,\n EntityRefPresentationSnapshot,\n} from './EntityPresentationApi';\nimport { defaultEntityPresentation } from './defaultEntityPresentation';\n\n/**\n * Returns a synchronous presentation snapshot for an entity in non-React\n * contexts.\n *\n * @remarks\n *\n * This is the synchronous, non-React counterpart to\n * {@link useEntityPresentation}. It handles `Entity`, `CompoundEntityRef`,\n * and string ref inputs uniformly, using the provided\n * {@link EntityPresentationApi} when available and falling back to\n * {@link defaultEntityPresentation} otherwise.\n *\n * Because this function is synchronous, it uses cached data from the\n * presentation API (via `.snapshot`). If the entity has been seen before,\n * the snapshot will contain the full resolved title; otherwise it falls\n * back to what can be extracted from the ref alone. This is the correct\n * trade-off for sort comparators, column factories, filter callbacks, and\n * data mappers where a synchronous return value is required.\n *\n * In async contexts such as data loaders where you can `await`, prefer\n * using the {@link EntityPresentationApi} directly via\n * `forEntity().promise` for the richest possible presentation.\n *\n * @public\n * @param entityOrRef - An entity, a compound entity ref, or a string entity ref.\n * @param context - Optional context that may affect the presentation.\n * @param entityPresentationApi - Optional presentation API instance. When not\n * provided, falls back to {@link defaultEntityPresentation}.\n */\nexport function entityPresentationSnapshot(\n entityOrRef: Entity | CompoundEntityRef | string,\n context?: { defaultKind?: string; defaultNamespace?: string },\n entityPresentationApi?: EntityPresentationApi,\n): EntityRefPresentationSnapshot {\n if (entityPresentationApi) {\n const ref =\n typeof entityOrRef === 'string' || 'metadata' in entityOrRef\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n return entityPresentationApi.forEntity(ref, context).snapshot;\n }\n return defaultEntityPresentation(entityOrRef, context);\n}\n","/*\n * Copyright 2024 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 Box from '@material-ui/core/Box';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport Paper, { PaperProps } from '@material-ui/core/Paper';\nimport Popper, { PopperProps } from '@material-ui/core/Popper';\nimport TextField, { OutlinedTextFieldProps } from '@material-ui/core/TextField';\nimport Grow from '@material-ui/core/Grow';\nimport {\n createStyles,\n makeStyles,\n Theme,\n withStyles,\n} from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport { ReactNode, useCallback } from 'react';\nimport { merge } from 'lodash';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n margin: theme.spacing(1, 0),\n },\n label: {\n position: 'relative',\n fontWeight: 'bold',\n fontSize: theme.typography.body2.fontSize,\n fontFamily: theme.typography.fontFamily,\n color: theme.palette.text.primary,\n '& > span': {\n top: 0,\n left: 0,\n position: 'absolute',\n },\n },\n }),\n { name: 'BackstageAutocomplete' },\n);\n\nconst BootstrapAutocomplete = withStyles(\n (theme: Theme) =>\n createStyles({\n root: {},\n paper: {\n margin: 0,\n },\n hasClearIcon: {},\n hasPopupIcon: {},\n focused: {},\n inputRoot: {\n marginTop: 24,\n backgroundColor: theme.palette.background.paper,\n '$root$hasClearIcon$hasPopupIcon &': {\n paddingBlock: theme.spacing(0.75),\n paddingInlineStart: theme.spacing(0.75),\n },\n '$root$focused &': {\n outline: 'none',\n },\n '$root &:hover > fieldset': {\n borderColor: '#ced4da',\n },\n '$root$focused & > fieldset': {\n borderWidth: 1,\n borderColor: theme.palette.primary.main,\n },\n },\n popupIndicator: {\n padding: 0,\n margin: 0,\n color: '#616161',\n '&:hover': {\n backgroundColor: 'unset',\n },\n '& [class*=\"MuiTouchRipple-root\"]': {\n display: 'none',\n },\n },\n endAdornment: {\n '$root$hasClearIcon$hasPopupIcon &': {\n right: 4,\n },\n },\n input: {\n '$root$hasClearIcon$hasPopupIcon &': {\n fontSize: theme.typography.body1.fontSize,\n paddingBlock: theme.spacing(0.8125),\n },\n },\n }),\n { name: 'BackstageAutocompleteBase' },\n)(Autocomplete) as typeof Autocomplete;\n\nconst PopperComponent = (props: PopperProps) => (\n <Popper {...props} transition placement=\"bottom-start\">\n {({ TransitionProps }) => (\n <Grow {...TransitionProps} style={{ transformOrigin: '0 0 0' }}>\n <Box>{props.children as ReactNode}</Box>\n </Grow>\n )}\n </Popper>\n);\n\nconst PaperComponent = (props: PaperProps) => (\n <Paper {...props} elevation={8} />\n);\n\n/**\n * Props for {@link CatalogAutocomplete}\n *\n * @public\n */\nexport type CatalogAutocompleteProps<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n> = Omit<\n AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>,\n 'PopperComponent' | 'PaperComponent' | 'popupIcon' | 'renderInput'\n> & {\n name: string;\n label?: string;\n LabelProps?: TypographyProps<'label'>;\n TextFieldProps?: Omit<OutlinedTextFieldProps, 'variant'>;\n renderInput?: AutocompleteProps<\n T,\n Multiple,\n DisableClearable,\n FreeSolo\n >['renderInput'];\n};\n\n/** @public */\nexport function CatalogAutocomplete<\n T,\n Multiple extends boolean | undefined = undefined,\n DisableClearable extends boolean | undefined = undefined,\n FreeSolo extends boolean | undefined = undefined,\n>(props: CatalogAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) {\n const { label, name, LabelProps, TextFieldProps, ...rest } = props;\n const classes = useStyles();\n const renderInput = useCallback(\n (params: AutocompleteRenderInputParams) => (\n <TextField {...merge(params, TextFieldProps)} variant=\"outlined\" />\n ),\n [TextFieldProps],\n );\n const autocomplete = (\n <BootstrapAutocomplete\n size=\"small\"\n {...rest}\n renderInput={rest.renderInput ?? renderInput}\n popupIcon={<ExpandMoreIcon data-testid={`${name}-expand`} />}\n PaperComponent={PaperComponent}\n PopperComponent={PopperComponent}\n />\n );\n\n return (\n <Box className={classes.root}>\n {label ? (\n <Typography\n {...LabelProps}\n className={classNames(classes.label, LabelProps?.className)}\n component=\"label\"\n >\n <Box component=\"span\">{label}</Box>\n {autocomplete}\n </Typography>\n ) : (\n autocomplete\n )}\n </Box>\n );\n}\n","/*\n * Copyright 2021 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 { ReactNode, useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme, useTheme } from '@material-ui/core/styles';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport const Filters = (props: {\n children: ReactNode;\n options?: {\n drawerBreakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;\n drawerAnchor?: 'left' | 'right' | 'top' | 'bottom';\n };\n}) => {\n const isScreenSmallerThanBreakpoint = useMediaQuery(\n (theme: Theme) =>\n theme.breakpoints.down(props.options?.drawerBreakpoint ?? 'md'),\n { noSsr: true },\n );\n const theme = useTheme();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return isScreenSmallerThanBreakpoint ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n {t('catalogFilter.buttonTitle')}\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor={props.options?.drawerAnchor ?? 'left'}\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n {t('catalogFilter.title')}\n </Typography>\n {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const Content = (props: { children: ReactNode }) => {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\n </Grid>\n );\n};\n\n/** @public */\nexport const CatalogFilterLayout = (props: { children: ReactNode }) => {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.children}\n </Grid>\n );\n};\n\nCatalogFilterLayout.Filters = Filters;\nCatalogFilterLayout.Content = Content;\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 */\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { memo } from 'react';\n\ninterface Props {\n selected: boolean;\n value: string;\n availableOptions?: Record<string, number>;\n showCounts: boolean;\n}\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\nfunction OptionCheckbox({ selected }: { selected: boolean }) {\n return <Checkbox icon={icon} checkedIcon={checkedIcon} checked={selected} />;\n}\n\nexport const EntityAutocompletePickerOption = memo((props: Props) => {\n const { selected, value, availableOptions, showCounts } = props;\n const label = showCounts ? `${value} (${availableOptions?.[value]})` : value;\n\n return (\n <FormControlLabel\n control={<OptionCheckbox selected={selected} />}\n label={label}\n onClick={event => event.preventDefault()}\n />\n );\n});\n","/*\n * Copyright 2021 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 Box from '@material-ui/core/Box';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode, useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption';\nimport {\n DefaultEntityFilters,\n useEntityList,\n} from '../../hooks/useEntityListProvider';\nimport { EntityFilter } from '../../types';\nimport { reduceBackendCatalogFilters } from '../../utils/filters';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\nimport { AutocompleteRenderOptionState } from '@material-ui/lab/Autocomplete';\nimport { isEqual } from 'lodash';\n\n/** @public */\nexport type AllowedEntityFilters<T extends DefaultEntityFilters> = {\n [K in keyof T]-?: NonNullable<T[K]> extends EntityFilter & {\n values: string[];\n }\n ? K\n : never;\n}[keyof T];\n\n/** @public */\nexport type EntityAutocompletePickerProps<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n> = {\n label: string;\n name: Name;\n path: string;\n showCounts?: boolean;\n Filter: { new (values: string[]): NonNullable<T[Name]> };\n InputProps?: TextFieldProps;\n initialSelectedOptions?: string[];\n filtersForAvailableValues?: Array<keyof T>;\n hidden?: boolean;\n getOptionLabel?: (option: string) => string;\n renderOption?: (\n option: string,\n state: AutocompleteRenderOptionState,\n ) => ReactNode;\n};\n\n/** @public */\nexport type CatalogReactEntityAutocompletePickerClassKey = 'root' | 'label';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {\n textTransform: 'none',\n fontWeight: 'bold',\n },\n },\n { name: 'CatalogReactEntityAutocompletePicker' },\n);\n\n/** @public */\nexport function EntityAutocompletePicker<\n T extends DefaultEntityFilters = DefaultEntityFilters,\n Name extends AllowedEntityFilters<T> = AllowedEntityFilters<T>,\n>(props: EntityAutocompletePickerProps<T, Name>) {\n const {\n label,\n name,\n path,\n showCounts,\n Filter,\n InputProps,\n initialSelectedOptions = [],\n filtersForAvailableValues = ['kind'],\n hidden,\n getOptionLabel,\n renderOption,\n } = props;\n const classes = useStyles();\n\n const {\n updateFilters,\n filters,\n queryParameters: { [name]: queryParameter },\n } = useEntityList<T>();\n\n const catalogApi = useApi(catalogApiRef);\n const availableValuesFilters = filtersForAvailableValues.map(\n f => filters[f] as EntityFilter | undefined,\n );\n const { value: availableValues } = useAsync(async () => {\n const facet = path;\n const { facets } = await catalogApi.getEntityFacets({\n facets: [facet],\n filter: reduceBackendCatalogFilters(\n availableValuesFilters.filter(Boolean) as EntityFilter[],\n ),\n });\n\n return Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n }, [...availableValuesFilters]);\n\n const queryParameters = useMemo(\n () => [queryParameter].flat().filter(Boolean) as string[],\n [queryParameter],\n );\n\n const filteredOptions = (filters[name] as unknown as { values: string[] })\n ?.values;\n\n const [selectedOptions, setSelectedOptions] = useState(\n queryParameters.length\n ? queryParameters\n : filteredOptions ?? initialSelectedOptions,\n );\n\n // Set selected options on query parameter updates; this happens at initial page load and from\n // external updates to the page location\n useEffect(() => {\n if (queryParameters.length) {\n setSelectedOptions(queryParameters);\n }\n }, [queryParameters]);\n\n const availableOptions = Object.keys(availableValues ?? {});\n const shouldAddFilter = selectedOptions.length && availableOptions.length;\n\n // Update filter value when selectedOptions change\n useEffect(() => {\n updateFilters({\n [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined,\n } as Partial<T>);\n }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]);\n\n // Update selected options when filter value changes\n useEffect(() => {\n if (!shouldAddFilter) return;\n\n const newSelectedOptions = filteredOptions ?? [];\n\n // Check value is actually different (not just a different reference) to prevent selectedOptions <> filters loop\n if (!isEqual(newSelectedOptions, selectedOptions)) {\n setSelectedOptions(newSelectedOptions);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Don't re-set filter value when selectedOptions changes\n }, [filteredOptions]);\n\n const filter = filters[name];\n if (\n (filter && typeof filter === 'object' && !('values' in filter)) ||\n !availableOptions.length\n ) {\n return null;\n }\n\n return hidden ? null : (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<string, true>\n multiple\n disableCloseOnSelect\n label={label}\n name={`${String(name)}-picker`}\n options={availableOptions}\n value={selectedOptions}\n TextFieldProps={InputProps}\n onChange={(_event: object, options: string[]) =>\n setSelectedOptions(options)\n }\n {...(getOptionLabel && { getOptionLabel })}\n renderOption={\n renderOption ??\n ((option, { selected }) => (\n <EntityAutocompletePickerOption\n selected={selected}\n value={option}\n availableOptions={availableValues}\n showCounts={!!showCounts}\n />\n ))\n }\n />\n </Box>\n );\n}\n","/*\n * Copyright 2026 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 HTMLAttributes,\n UIEvent,\n cloneElement,\n createContext,\n forwardRef,\n useContext,\n Children,\n} from 'react';\nimport { FixedSizeList, ListChildComponentProps } from 'react-window';\n\n// MUI Autocomplete's ListboxComponent prop is typed as ComponentType<HTMLAttributes<HTMLElement>>,\n// so we use HTMLElement here to avoid a cast at the usage site.\ntype ListboxProps = HTMLAttributes<HTMLElement>;\n\nconst ITEM_SIZE = 36;\n\nconst renderRow = (props: ListChildComponentProps) => {\n const { data, index, style } = props;\n return cloneElement(data[index], { style });\n};\n\n// Passes Autocomplete listbox props (onScroll, data-testid, etc.) through to the\n// outer scroll container so MUI Autocomplete keeps working correctly.\n// See https://v4.mui.com/components/autocomplete/#Virtualize.tsx\nconst OuterElementContext = createContext<ListboxProps>({});\n\nconst OuterElementType = forwardRef<HTMLDivElement, ListboxProps>(\n ({ onScroll: rrOnScroll, ...props }, ref) => {\n const { onScroll: outerOnScroll, ...outerProps } =\n useContext(OuterElementContext);\n // Compose both handlers: spreading outerProps last would silently overwrite\n // react-window's onScroll, breaking virtualization.\n const handleScroll = (e: UIEvent<HTMLDivElement>) => {\n rrOnScroll?.(e);\n outerOnScroll?.(e);\n };\n return <div ref={ref} onScroll={handleScroll} {...props} {...outerProps} />;\n },\n);\n\nexport const VirtualizedListbox = forwardRef<HTMLDivElement, ListboxProps>(\n (props, ref) => {\n const { children, ...other } = props;\n const itemData = Children.toArray(children);\n const itemCount = itemData.length;\n\n const itemsToShow = Math.min(10, itemCount) + 0.5;\n const height = itemsToShow * ITEM_SIZE;\n\n return (\n <div ref={ref}>\n <OuterElementContext.Provider value={other}>\n <FixedSizeList\n height={height}\n itemData={itemData}\n itemCount={itemCount}\n itemSize={ITEM_SIZE}\n outerElementType={OuterElementType}\n width=\"100%\"\n >\n {renderRow}\n </FixedSizeList>\n </OuterElementContext.Provider>\n </div>\n );\n },\n);\n","/*\n * Copyright 2021 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 Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Typography from '@material-ui/core/Typography';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport { MouseEvent, useEffect, useMemo, useState } from 'react';\nimport { useEntityList } from '../../hooks/useEntityListProvider';\nimport { EntityOwnerFilter } from '../../filters';\nimport { useDebouncedEffect } from '@react-hookz/web';\nimport PersonIcon from '@material-ui/icons/Person';\nimport GroupIcon from '@material-ui/icons/Group';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n} from '../../apis';\nimport { useFetchEntities } from './useFetchEntities';\nimport { VirtualizedListbox } from './VirtualizedListbox';\nimport { withStyles } from '@material-ui/core/styles';\nimport { useEntityPresentation } from '../../apis';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogAutocomplete } from '../CatalogAutocomplete';\n\n/** @public */\nexport type CatalogReactEntityOwnerPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n root: {},\n label: {},\n input: {},\n fullWidth: { width: '100%' },\n boxLabel: {\n width: '100%',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n },\n },\n { name: 'CatalogReactEntityOwnerPicker' },\n);\n\n/** @public */\nexport type FixedWidthFormControlLabelClassKey = 'label' | 'root';\n\nconst FixedWidthFormControlLabel = withStyles(\n _theme => ({\n label: {\n width: '100%',\n },\n root: {\n width: '90%',\n },\n }),\n { name: 'FixedWidthFormControlLabel' },\n)(FormControlLabel);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/**\n * @public\n */\nexport type EntityOwnerPickerProps = {\n mode?: 'owners-only' | 'all';\n};\n\nfunction RenderOptionLabel(props: {\n entity: Entity;\n isSelected: boolean;\n mode: 'owners-only' | 'all';\n}) {\n const classes = useStyles();\n const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group';\n // owners-only stubs lack title/displayName; pass ref string so the presentation API fetches the full entity.\n const entityOrRef: Entity | string =\n props.mode === 'owners-only'\n ? stringifyEntityRef(props.entity)\n : props.entity;\n const { primaryTitle: title } = useEntityPresentation(entityOrRef);\n return (\n <Box className={classes.fullWidth}>\n <FixedWidthFormControlLabel\n className={classes.fullWidth}\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={props.isSelected}\n />\n }\n onClick={event => event.preventDefault()}\n label={\n <Tooltip title={title}>\n <Box display=\"flex\" alignItems=\"center\">\n {isGroup ? (\n <GroupIcon fontSize=\"small\" />\n ) : (\n <PersonIcon fontSize=\"small\" />\n )}\n &nbsp;\n <Box className={classes.boxLabel}>\n <Typography noWrap>{title}</Typography>\n </Box>\n </Box>\n </Tooltip>\n }\n />\n </Box>\n );\n}\n\n/** @public */\nexport const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => {\n const classes = useStyles();\n const { mode = 'owners-only' } = props || {};\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const {\n updateFilters,\n filters,\n queryParameters: { owners: ownersParameter },\n } = useEntityList();\n\n const [text, setText] = useState('');\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const queryParamOwners = useMemo(\n () => [ownersParameter].flat().filter(Boolean) as string[],\n [ownersParameter],\n );\n\n // Query parameters may contain humanized refs (e.g. `guests` rather than\n // `group:default/guests`), so they are normalized before being stored.\n const [selectedOwners, setSelectedOwners] = useState<string[]>(\n queryParamOwners.length\n ? new EntityOwnerFilter(queryParamOwners).values\n : filters.owners?.values ?? [],\n );\n\n const [{ value, loading }, handleFetch, cache] = useFetchEntities({\n mode,\n initialSelectedOwnersRefs: selectedOwners,\n });\n useDebouncedEffect(\n () => handleFetch({ text: text.toLocaleLowerCase('en-US') }),\n [text, handleFetch],\n 250,\n );\n\n const availableOwners = value?.items || [];\n\n // Set selected owners on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamOwners.length) {\n const filter = new EntityOwnerFilter(queryParamOwners);\n setSelectedOwners(filter.values);\n }\n }, [queryParamOwners]);\n\n useEffect(() => {\n updateFilters({\n owners: selectedOwners.length\n ? new EntityOwnerFilter(selectedOwners)\n : undefined,\n });\n }, [selectedOwners, updateFilters]);\n\n if (\n ['user', 'group'].includes(\n filters.kind?.value.toLocaleLowerCase('en-US') || '',\n )\n ) {\n return null;\n }\n\n return (\n <Box className={classes.root} pb={1} pt={1}>\n <CatalogAutocomplete<Entity, true>\n label={t('entityOwnerPicker.title')}\n multiple\n disableCloseOnSelect\n loading={loading}\n options={availableOwners}\n value={selectedOwners as unknown as Entity[]}\n getOptionSelected={(o, v) => {\n if (typeof v === 'string') {\n return stringifyEntityRef(o) === v;\n }\n return o === v;\n }}\n getOptionLabel={o => {\n if (mode === 'owners-only') {\n // Stubs have no title; use string ref so entityPresentationSnapshot hits the API cache.\n const ref = typeof o === 'string' ? o : stringifyEntityRef(o);\n return entityPresentationSnapshot(\n ref,\n undefined,\n entityPresentationApi,\n ).primaryTitle;\n }\n const entity =\n typeof o === 'string'\n ? cache.getEntity(o) ||\n parseEntityRef(o, {\n defaultKind: 'group',\n defaultNamespace: 'default',\n })\n : o;\n return entityPresentationSnapshot(\n entity,\n undefined,\n entityPresentationApi,\n ).primaryTitle;\n }}\n onChange={(_: object, owners) => {\n setText('');\n setSelectedOwners(\n owners.map(e => {\n const entityRef =\n typeof e === 'string' ? e : stringifyEntityRef(e);\n\n if (typeof e !== 'string') {\n cache.setEntity(e);\n }\n return entityRef;\n }),\n );\n }}\n filterOptions={x => x}\n renderOption={(entity, { selected }) => {\n return (\n <RenderOptionLabel\n entity={entity}\n isSelected={selected}\n mode={mode}\n />\n );\n }}\n name=\"owner-picker\"\n onInputChange={(_e, inputValue) => {\n setText(inputValue);\n }}\n ListboxComponent={VirtualizedListbox}\n ListboxProps={{\n onScroll: (e: MouseEvent) => {\n const element = e.currentTarget;\n const hasReachedEnd =\n Math.abs(\n element.scrollHeight - element.clientHeight - element.scrollTop,\n ) < 1;\n\n if (hasReachedEnd && value?.cursor) {\n handleFetch({ items: value.items, cursor: value.cursor });\n }\n },\n 'data-testid': 'owner-picker-listbox',\n }}\n LabelProps={{ className: classes.label }}\n TextFieldProps={{ className: classes.input }}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2023 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 */\nimport { useRef } from 'react';\nimport { useFacetsEntities } from './useFacetsEntities';\nimport { useQueryEntities } from './useQueryEntities';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { useMountEffect } from '@react-hookz/web';\n\nexport function useFetchEntities({\n mode,\n initialSelectedOwnersRefs,\n}: {\n mode: 'owners-only' | 'all';\n initialSelectedOwnersRefs: string[];\n}) {\n const isOwnersOnlyMode = mode === 'owners-only';\n const queryEntitiesResponse = useQueryEntities();\n const facetsEntitiesResponse = useFacetsEntities({\n enabled: isOwnersOnlyMode,\n });\n\n const [state, handleFetch] = isOwnersOnlyMode\n ? facetsEntitiesResponse\n : queryEntitiesResponse;\n\n return [\n state,\n handleFetch,\n useSelectedOwners({\n enabled: !isOwnersOnlyMode,\n initialSelectedOwnersRefs,\n }),\n ] as const;\n}\n\n/**\n * Hook used for storing the full entity of the specified owners\n * in order to display users and group using the information contained on each entity.\n * When a component is rendered for the first time, it loads the content of the entities\n * specified by `initialSelectedOwnersRefs` and export the `getEntity` and `setEntity`\n * utilities, used to retrieve and modify the owners.\n */\nfunction useSelectedOwners({\n enabled,\n initialSelectedOwnersRefs,\n}: {\n enabled: boolean;\n initialSelectedOwnersRefs: string[];\n}) {\n const allEntities = useRef<Record<string, Entity>>({});\n const catalogApi = useApi(catalogApiRef);\n\n const [, handleFetch] = useAsyncFn(async () => {\n const initialSelectedEntities = await catalogApi.getEntitiesByRefs({\n entityRefs: initialSelectedOwnersRefs,\n });\n initialSelectedEntities.items.forEach(e => {\n if (e) {\n allEntities.current[stringifyEntityRef(e)] = e;\n }\n });\n }, []);\n\n useMountEffect(() => {\n if (enabled && initialSelectedOwnersRefs.length > 0) {\n handleFetch();\n }\n });\n\n return {\n getEntity: (entityRef: string) => allEntities.current[entityRef],\n setEntity: (entity: Entity) => {\n allEntities.current[stringifyEntityRef(entity)] = entity;\n },\n };\n}\n","/*\n * Copyright 2023 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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../../api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { Entity } from '@backstage/catalog-model';\n\ntype QueryEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\nexport function useQueryEntities() {\n const catalogApi = useApi(catalogApiRef);\n return useAsyncFn(\n async (\n request: { text: string } | QueryEntitiesResponse,\n options?: { limit: number },\n ): Promise<QueryEntitiesResponse> => {\n const initialRequest = request as { text: string };\n const cursorRequest = request as QueryEntitiesResponse;\n const limit = options?.limit ?? 20;\n\n if (cursorRequest.cursor) {\n const response = await catalogApi.queryEntities({\n cursor: cursorRequest.cursor,\n limit,\n });\n return {\n cursor: response.pageInfo.nextCursor,\n items: [...cursorRequest.items, ...response.items],\n };\n }\n\n const response = await catalogApi.queryEntities({\n fullTextFilter: {\n term: initialRequest.text || '',\n fields: [\n 'metadata.name',\n 'kind',\n 'spec.profile.displayname',\n 'metadata.title',\n ],\n },\n filter: { kind: ['User', 'Group'] },\n orderFields: [{ field: 'metadata.name', order: 'asc' }],\n limit,\n });\n\n return {\n cursor: response.pageInfo.nextCursor,\n items: response.items,\n };\n },\n [],\n { loading: true },\n );\n}\n","/*\n * Copyright 2023 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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport { catalogApiRef } from '../../api';\nimport { useState } from 'react';\nimport { Entity, parseEntityRef } from '@backstage/catalog-model';\n\ntype FacetsCursor = {\n start: number;\n text: string;\n};\n\ntype FacetsEntitiesResponse = {\n items: Entity[];\n cursor?: string;\n};\n\ntype FacetsInitialRequest = {\n text: string;\n};\n\n/**\n * This hook asynchronously loads the entity owners using the facets endpoint.\n * EntityOwnerPicker uses this hook when mode=\"owners-only\" is passed as prop.\n * All the owners are kept internally in memory and rendered in batches once requested\n * by the frontend. The values returned by this hook are compatible with `useQueryEntities`\n * hook, which is also used by EntityOwnerPicker.\n * In this mode, the EntityOwnerPicker won't show detailed information of the owners.\n */\nexport function useFacetsEntities({ enabled }: { enabled: boolean }) {\n const catalogApi = useApi(catalogApiRef);\n\n const [facetsPromise] = useState(async () => {\n if (!enabled) {\n return [];\n }\n const facet = 'relations.ownedBy';\n\n return catalogApi\n .getEntityFacets({ facets: [facet] })\n .then(response =>\n response.facets[facet]\n .map(e => e.value)\n .map(ref => {\n const { kind, name, namespace } = parseEntityRef(ref);\n return {\n apiVersion: 'backstage.io/v1beta1',\n kind,\n metadata: { name, namespace },\n };\n })\n .sort(\n (a, b) =>\n a.kind.localeCompare(b.kind, 'en-US') ||\n a.metadata.namespace.localeCompare(\n b.metadata.namespace,\n 'en-US',\n ) ||\n a.metadata.name.localeCompare(b.metadata.name, 'en-US'),\n ),\n )\n .catch(() => []);\n });\n\n return useAsyncFn<\n (\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n options?: { limit?: number },\n ) => Promise<FacetsEntitiesResponse>\n >(\n async (request, options) => {\n const facets = await facetsPromise;\n\n if (!facets) {\n return {\n items: [],\n };\n }\n\n const limit = options?.limit ?? 20;\n\n const { text, start } = decodeCursor(request);\n const filteredRefs = facets.filter(e => filterEntity(text, e));\n const end = start + limit;\n return {\n items: filteredRefs.slice(0, end),\n ...encodeCursor({\n entities: filteredRefs,\n limit: end,\n payload: {\n text,\n start: end,\n },\n }),\n };\n },\n [facetsPromise],\n { loading: true, value: { items: [] } },\n );\n}\n\nfunction decodeCursor(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): FacetsCursor {\n if (isFacetsResponse(request) && request.cursor) {\n return JSON.parse(atob(request.cursor));\n }\n return {\n text: (request as FacetsInitialRequest).text || '',\n start: 0,\n };\n}\n\nfunction isFacetsResponse(\n request: FacetsInitialRequest | FacetsEntitiesResponse,\n): request is FacetsEntitiesResponse {\n return !!(request as FacetsEntitiesResponse).cursor;\n}\n\nfunction encodeCursor({\n entities,\n limit,\n payload,\n}: {\n entities: Entity[];\n limit: number;\n payload: { text: string; start: number };\n}) {\n if (entities.length > limit) {\n return { cursor: btoa(JSON.stringify(payload)) };\n }\n return {};\n}\n\nfunction filterEntity(text: string, entity: Entity) {\n const normalizedText = text.trim();\n return (\n entity.kind.includes(normalizedText) ||\n entity.metadata.namespace?.includes(normalizedText) ||\n entity.metadata.name.includes(normalizedText)\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 */\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Fragment } from 'react';\nimport { EntityRefLink } from './EntityRefLink';\nimport { LinkProps } from '@backstage/core-components';\n\n/**\n * Props for {@link EntityRefLink}.\n *\n * @public\n */\nexport type EntityRefLinksProps<\n TRef extends string | CompoundEntityRef | Entity,\n> = {\n defaultKind?: string;\n entityRefs: TRef[];\n hideIcons?: boolean;\n /** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */\n fetchEntities?: boolean;\n /** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */\n getTitle?(entity: TRef): string | undefined;\n} & Omit<LinkProps, 'to'>;\n\n/**\n * Shows a list of clickable links to entities.\n *\n * @public\n */\nexport function EntityRefLinks<\n TRef extends string | CompoundEntityRef | Entity,\n>(props: EntityRefLinksProps<TRef>) {\n const { entityRefs, hideIcons, ...linkProps } = props;\n\n return (\n <>\n {entityRefs.map((r: TRef, i: number) => {\n const entityRefString =\n typeof r === 'string' ? r : stringifyEntityRef(r);\n return (\n <Fragment key={`${i}.${entityRefString}`}>\n {i > 0 && ', '}\n <EntityRefLink {...linkProps} entityRef={r} hideIcon={hideIcons} />\n </Fragment>\n );\n })}\n </>\n );\n}\n","/*\n * Copyright 2021 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 { makeStyles } from '@material-ui/core/styles';\nimport { EntityTagFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker/EntityAutocompletePicker';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @public */\nexport type CatalogReactEntityTagPickerClassKey = 'input';\n\n/** @public */\nexport type EntityTagPickerProps = {\n showCounts?: boolean;\n initialFilter?: string[];\n hidden?: boolean;\n};\n\nconst useStyles = makeStyles(\n { input: {} },\n { name: 'CatalogReactEntityTagPicker' },\n);\n\n/** @public */\nexport const EntityTagPicker = (props: EntityTagPickerProps) => {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <EntityAutocompletePicker\n label={t('entityTagPicker.title')}\n name=\"tags\"\n path=\"metadata.tags\"\n Filter={EntityTagFilter}\n showCounts={props.showCounts}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={props.initialFilter ? props.initialFilter : []}\n hidden={props.hidden}\n />\n );\n};\n","/*\n * Copyright 2021 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 configApiRef,\n IconComponent,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Card from '@material-ui/core/Card';\nimport List from '@material-ui/core/List';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport { StarIcon } from '@backstage/core-components';\nimport { Fragment, useEffect, useMemo, useState } from 'react';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { UserListFilterKind } from '../../types';\nimport { useOwnedEntitiesCount } from './useOwnedEntitiesCount';\nimport { useAllEntitiesCount } from './useAllEntitiesCount';\nimport { useStarredEntitiesCount } from './useStarredEntitiesCount';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/** @public */\nexport type CatalogReactUserListPickerClassKey =\n | 'root'\n | 'title'\n | 'listIcon'\n | 'menuItem'\n | 'groupWrapper';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n backgroundColor: 'rgba(0, 0, 0, .11)',\n boxShadow: 'none',\n margin: theme.spacing(1, 0, 1, 0),\n },\n title: {\n margin: theme.spacing(1, 0, 0, 1),\n textTransform: 'uppercase',\n fontSize: 12,\n fontWeight: 'bold',\n },\n listIcon: {\n minWidth: 30,\n color: theme.palette.text.primary,\n },\n menuItem: {\n minHeight: theme.spacing(6),\n },\n groupWrapper: {\n margin: theme.spacing(1, 1, 2, 1),\n },\n }),\n { name: 'CatalogReactUserListPicker' },\n);\n\nexport type ButtonGroup = {\n name: string;\n items: {\n id: 'owned' | 'starred' | 'all';\n label: string;\n icon?: IconComponent;\n }[];\n};\n\nfunction getFilterGroups(\n orgName: string,\n t: TranslationFunction<typeof catalogReactTranslationRef.T>,\n): ButtonGroup[] {\n return [\n {\n name: t('userListPicker.personalFilter.title'),\n items: [\n {\n id: 'owned',\n label: t('userListPicker.personalFilter.ownedLabel'),\n icon: SettingsIcon,\n },\n {\n id: 'starred',\n label: t('userListPicker.personalFilter.starredLabel'),\n icon: StarIcon,\n },\n ],\n },\n {\n name: orgName,\n items: [\n {\n id: 'all',\n label: t('userListPicker.orgFilterAllLabel'),\n },\n ],\n },\n ];\n}\n\n/** @public */\nexport type UserListPickerProps = {\n initialFilter?: UserListFilterKind;\n availableFilters?: UserListFilterKind[];\n hidden?: boolean;\n alwaysKeepFilters?: boolean;\n};\n\n/** @public */\nexport const UserListPicker = (props: UserListPickerProps) => {\n const { initialFilter, availableFilters, hidden, alwaysKeepFilters } = props;\n const classes = useStyles();\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n const orgName =\n configApi.getOptionalString('organization.name') ??\n t('userListPicker.defaultOrgName');\n const {\n filters,\n updateFilters,\n queryParameters: { user: userParameter },\n } = useEntityList();\n const kindParameter = filters.kind?.value?.toLowerCase();\n\n // Remove group items that aren't in availableFilters and exclude\n // any now-empty groups.\n const userAndGroupFilterIds = ['starred', 'all'];\n const filterGroups = getFilterGroups(orgName, t)\n .map(filterGroup => ({\n ...filterGroup,\n items: filterGroup.items.filter(({ id }) =>\n // TODO: avoid hardcoding kinds here\n ['group', 'user'].some(kind => kind === kindParameter)\n ? userAndGroupFilterIds.includes(id)\n : !availableFilters || availableFilters.includes(id),\n ),\n }))\n .filter(({ items }) => !!items.length);\n\n const {\n count: ownedEntitiesCount,\n loading: loadingOwnedEntities,\n filter: ownedEntitiesFilter,\n } = useOwnedEntitiesCount();\n const { count: allCount } = useAllEntitiesCount();\n const {\n count: starredEntitiesCount,\n filter: starredEntitiesFilter,\n loading: loadingStarredEntities,\n } = useStarredEntitiesCount();\n\n const queryParamUserFilter = useMemo(\n () => [userParameter].flat()[0],\n [userParameter],\n );\n\n const [selectedUserFilter, setSelectedUserFilter] = useState(\n (queryParamUserFilter as UserListFilterKind) ?? initialFilter,\n );\n\n const filterCounts = useMemo(() => {\n return {\n all: allCount,\n starred: starredEntitiesCount,\n owned: ownedEntitiesCount,\n };\n }, [starredEntitiesCount, ownedEntitiesCount, allCount]);\n\n // Set selected user filter on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamUserFilter) {\n setSelectedUserFilter(queryParamUserFilter as UserListFilterKind);\n }\n }, [queryParamUserFilter]);\n\n const loading = loadingOwnedEntities || loadingStarredEntities;\n\n useEffect(() => {\n if (\n !loading &&\n !!selectedUserFilter &&\n selectedUserFilter !== 'all' &&\n filterCounts[selectedUserFilter] === 0 &&\n !alwaysKeepFilters\n ) {\n setSelectedUserFilter('all');\n }\n }, [\n loading,\n filterCounts,\n selectedUserFilter,\n setSelectedUserFilter,\n alwaysKeepFilters,\n ]);\n\n useEffect(() => {\n if (!selectedUserFilter) {\n return;\n }\n if (loading) {\n return;\n }\n\n const getFilter = () => {\n if (selectedUserFilter === 'owned') {\n return ownedEntitiesFilter;\n }\n if (selectedUserFilter === 'starred') {\n return starredEntitiesFilter;\n }\n return EntityUserFilter.all();\n };\n\n updateFilters({ user: getFilter() });\n }, [\n selectedUserFilter,\n starredEntitiesFilter,\n ownedEntitiesFilter,\n updateFilters,\n\n loading,\n ]);\n\n return hidden ? null : (\n <Card className={classes.root}>\n {filterGroups.map(group => (\n <Fragment key={group.name}>\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n className={classes.title}\n >\n {group.name}\n </Typography>\n <Card className={classes.groupWrapper}>\n <List disablePadding dense role=\"menu\" aria-label={group.name}>\n {group.items.map((item, index) => (\n <MenuItem\n role=\"none presentation\"\n key={item.id}\n divider={index !== group.items.length - 1}\n onClick={() => setSelectedUserFilter(item.id)}\n selected={item.id === filters.user?.value}\n className={classes.menuItem}\n disabled={filterCounts[item.id] === 0}\n data-testid={`user-picker-${item.id}`}\n tabIndex={0}\n ContainerProps={{ role: 'menuitem' }}\n >\n {item.icon && (\n <ListItemIcon className={classes.listIcon}>\n <item.icon fontSize=\"small\" />\n </ListItemIcon>\n )}\n <ListItemText>\n <Typography variant=\"body1\">{item.label} </Typography>\n </ListItemText>\n <ListItemSecondaryAction>\n {filterCounts[item.id] ?? '-'}\n </ListItemSecondaryAction>\n </MenuItem>\n ))}\n </List>\n </Card>\n </Fragment>\n ))}\n </Card>\n );\n};\n","/*\n * Copyright 2023 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 { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport { compact, intersection } from 'lodash';\nimport { useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityOwnerFilter, EntityUserFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { CatalogFilters, reduceCatalogFilters } from '../../utils/filters';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDeepCompareEffect from 'react-use/esm/useDeepCompareEffect';\n\nexport function useOwnedEntitiesCount() {\n const identityApi = useApi(identityApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n const { filters } = useEntityList();\n\n const { value: ownershipEntityRefs, loading: loadingEntityRefs } = useAsync(\n async () => (await identityApi.getBackstageIdentity()).ownershipEntityRefs,\n // load only on mount\n [],\n );\n\n const { user, owners, ...allFilters } = filters;\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(\n compact(Object.values(allFilters)),\n );\n\n const [{ value: count, loading: loadingEntityOwnership }, fetchEntities] =\n useAsyncFn(\n async (req: {\n ownershipEntityRefs: string[];\n owners: EntityOwnerFilter | undefined;\n filter: CatalogFilters;\n }) => {\n const ownedClaims = getOwnedCountClaims(\n req.owners,\n req.ownershipEntityRefs,\n );\n if (ownedClaims === undefined) {\n // this implicitly means that there aren't claims in common with\n // the logged in users, so avoid invoking the queryEntities endpoint\n // which will implicitly returns 0\n return 0;\n }\n\n const { ['metadata.name']: metadata, ...filter } = req.filter.filter;\n\n const { totalItems } = await catalogApi.queryEntities({\n ...req.filter,\n filter: {\n ...filter,\n 'relations.ownedBy': ownedClaims,\n },\n limit: 0,\n });\n return totalItems;\n },\n [],\n { loading: true },\n );\n\n useDeepCompareEffect(() => {\n // context contains no filter, wait\n if (Object.keys(catalogFilters.filter).length === 0) {\n return;\n }\n // ownershipEntityRefs is loading, wait\n if (ownershipEntityRefs === undefined) {\n return;\n }\n fetchEntities({\n ownershipEntityRefs,\n owners,\n filter: catalogFilters,\n });\n }, [ownershipEntityRefs, owners, catalogFilters]);\n\n const loading = loadingEntityRefs || loadingEntityOwnership;\n\n return {\n count,\n loading,\n filter: useMemo(\n () => EntityUserFilter.owned(ownershipEntityRefs ?? []),\n [ownershipEntityRefs],\n ),\n ownershipEntityRefs,\n };\n}\n\nfunction getOwnedCountClaims(\n owners: EntityOwnerFilter | undefined,\n ownershipEntityRefs: string[] | undefined,\n) {\n if (!ownershipEntityRefs?.length) {\n return undefined;\n }\n const ownersRefs = owners?.values ?? [];\n if (ownersRefs.length) {\n const commonOwnedBy = intersection(ownersRefs, ownershipEntityRefs);\n if (commonOwnedBy.length === 0) {\n return undefined;\n }\n return commonOwnedBy;\n }\n return ownershipEntityRefs;\n}\n","/*\n * Copyright 2023 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 */\nimport { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { useEntityList } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useAllEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n limit: 0,\n };\n\n if (Object.keys(catalogFilters.filter).length === 0) {\n prevRequest.current = undefined;\n return prevRequest.current;\n }\n\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n return newRequest;\n }, [filters]);\n\n const { value: count, loading } = useAsync(async () => {\n if (request === undefined) {\n return 0;\n }\n const { totalItems } = await catalogApi.queryEntities(request);\n\n return totalItems;\n }, [request]);\n\n return { count, loading };\n}\n","/*\n * Copyright 2023 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 { QueryEntitiesInitialRequest } from '@backstage/catalog-client';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport { useMemo, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../api';\nimport { EntityUserFilter } from '../../filters';\nimport { useEntityList, useStarredEntities } from '../../hooks';\nimport { reduceCatalogFilters } from '../../utils/filters';\n\nexport function useStarredEntitiesCount() {\n const catalogApi = useApi(catalogApiRef);\n const { filters } = useEntityList();\n const { starredEntities } = useStarredEntities();\n\n const prevRequest = useRef<QueryEntitiesInitialRequest>();\n const request = useMemo(() => {\n const { user, ...allFilters } = filters;\n const compacted = compact(Object.values(allFilters));\n const { orderFields, ...catalogFilters } = reduceCatalogFilters(compacted);\n\n const facet = 'metadata.name';\n\n const newRequest: QueryEntitiesInitialRequest = {\n ...catalogFilters,\n filter: {\n ...catalogFilters.filter,\n /**\n * here we are filtering entities by `name`. Given this filter,\n * the response might contain more entities than expected, in case multiple entities\n * of different kind or namespace share the same name. Those extra entities are filtered out\n * client side by `EntityUserFilter`, so they won't be visible to the user.\n */\n [facet]: Array.from(starredEntities).map(e => parseEntityRef(e).name),\n },\n /**\n * limit is set to a high value as we are not expecting many starred entities\n */\n limit: 1000,\n };\n if (isEqual(newRequest, prevRequest.current)) {\n return prevRequest.current;\n }\n prevRequest.current = newRequest;\n\n return newRequest;\n }, [filters, starredEntities]);\n\n const { value: count, loading } = useAsync(async () => {\n if (!starredEntities.size) {\n return 0;\n }\n\n /**\n * given a list of starred entity refs and some filters coming from CatalogPage,\n * it reduces the list of starred entities, to a list of entities that matches the\n * provided filters. It won't be possible to getEntitiesByRefs\n * as the method doesn't accept any filter.\n */\n const response = await catalogApi.queryEntities(request);\n\n return response.items\n .map(e =>\n stringifyEntityRef({\n kind: e.kind,\n namespace: e.metadata.namespace,\n name: e.metadata.name,\n }),\n )\n .filter(e => starredEntities.has(e)).length;\n }, [request, starredEntities]);\n\n const filter = useMemo(\n () => EntityUserFilter.starred(Array.from(starredEntities)),\n [starredEntities],\n );\n\n return { count, loading, filter };\n}\n","/*\n * Copyright 2021 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 Entity,\n parseEntityRef,\n RELATION_OWNED_BY,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport { EntityFilter, UserListFilterKind } from './types';\nimport { getEntityRelations } from './utils/getEntityRelations';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\n/**\n * Filter entities based on Kind.\n * @public\n */\nexport class EntityKindFilter implements EntityFilter {\n readonly value: string;\n readonly label: string;\n\n constructor(value: string, label: string) {\n this.value = value;\n this.label = label;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { kind: this.value };\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on type\n * @public\n */\nexport class EntityTypeFilter implements EntityFilter {\n readonly value: string | string[];\n\n constructor(value: string | string[]) {\n this.value = value;\n }\n\n // Simplify `string | string[]` for consumers, always returns an array\n getTypes(): string[] {\n return Array.isArray(this.value) ? this.value : [this.value];\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.type': this.getTypes() };\n }\n\n toQueryValue(): string[] {\n return this.getTypes();\n }\n}\n\n/**\n * Filters entities based on tag.\n * @public\n */\nexport class EntityTagFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.every(v => (entity.metadata.tags ?? []).includes(v));\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.tags': this.values };\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities where the text matches spec, title or tags.\n * @public\n */\nexport class EntityTextFilter implements EntityFilter {\n readonly value: string;\n\n constructor(value: string) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const words = this.toUpperArray(this.value.split(/\\s/));\n const exactMatch = this.toUpperArray([entity.metadata.tags]);\n const targets = (entity.spec as { targets?: unknown })?.targets;\n const partialMatch = this.toUpperArray([\n entity.metadata.name,\n entity.metadata.title,\n (entity.spec?.profile as { displayName?: string })?.displayName,\n (entity.spec as { target?: string })?.target,\n ...(Array.isArray(targets) ? targets : []),\n ]);\n\n for (const word of words) {\n if (\n exactMatch.every(m => m !== word) &&\n partialMatch.every(m => !m.includes(word))\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n getFullTextFilters() {\n return {\n term: this.value,\n // Update this to be more dynamic based on table columns.\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'spec.profile.displayName',\n 'spec.target',\n 'spec.targets',\n ],\n };\n }\n\n toQueryValue() {\n return this.value;\n }\n\n private toUpperArray(\n value: Array<string | string[] | undefined>,\n ): Array<string> {\n return value\n .flat()\n .filter((m): m is string => Boolean(m) && typeof m === 'string')\n .map(m => m.toLocaleUpperCase('en-US'));\n }\n}\n\n/**\n * Filter matching entities that are owned by group.\n * @public\n *\n * CAUTION: This class may contain both full and partial entity refs.\n */\nexport class EntityOwnerFilter implements EntityFilter {\n readonly values: string[];\n constructor(values: string[]) {\n this.values = values.reduce((fullRefs, ref) => {\n // Attempt to remove bad entity references here.\n try {\n fullRefs.push(\n stringifyEntityRef(parseEntityRef(ref, { defaultKind: 'Group' })),\n );\n return fullRefs;\n } catch (err) {\n return fullRefs;\n }\n }, [] as string[]);\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'relations.ownedBy': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v =>\n getEntityRelations(entity, RELATION_OWNED_BY).some(\n o => stringifyEntityRef(o) === v,\n ),\n );\n }\n\n /**\n * Get the URL query parameter value. May be a mix of full and humanized entity refs.\n * @returns list of entity refs.\n */\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities on lifecycle.\n * @public\n */\nexport class EntityLifecycleFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'spec.lifecycle': this.values };\n }\n\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.spec?.lifecycle === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * Filters entities to those within the given namespace(s).\n * @public\n */\nexport class EntityNamespaceFilter implements EntityFilter {\n readonly values: string[];\n\n constructor(values: string[]) {\n this.values = values;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n return { 'metadata.namespace': this.values };\n }\n filterEntity(entity: Entity): boolean {\n return this.values.some(v => entity.metadata.namespace === v);\n }\n\n toQueryValue(): string[] {\n return this.values;\n }\n}\n\n/**\n * @public\n */\nexport class EntityUserFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly refs?: string[];\n\n private constructor(value: UserListFilterKind, refs?: string[]) {\n this.value = value;\n this.refs = refs;\n }\n\n static owned(ownershipEntityRefs: string[]) {\n return new EntityUserFilter('owned', ownershipEntityRefs);\n }\n\n static all() {\n return new EntityUserFilter('all');\n }\n\n static starred(starredEntityRefs: string[]) {\n return new EntityUserFilter('starred', starredEntityRefs);\n }\n\n getCatalogFilters(): Record<string, string[]> {\n if (this.value === 'owned') {\n return { 'relations.ownedBy': this.refs ?? [] };\n }\n if (this.value === 'starred') {\n return {\n 'metadata.name': this.refs?.map(e => parseEntityRef(e).name) ?? [],\n };\n }\n return {};\n }\n\n filterEntity(entity: Entity) {\n if (this.value === 'starred') {\n return this.refs?.includes(stringifyEntityRef(entity)) ?? true;\n }\n // used only for retro-compatibility with non paginated data.\n // This is supposed to return always true for paginated\n // owned entities, since the filters are applied server side.\n if (this.value === 'owned') {\n const relations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return (\n this.refs?.some(v =>\n relations.some(o => stringifyEntityRef(o) === v),\n ) ?? false\n );\n }\n return true;\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based on whatever the user has starred or owns them.\n * @deprecated use EntityUserFilter\n * @public\n */\nexport class UserListFilter implements EntityFilter {\n readonly value: UserListFilterKind;\n readonly isOwnedEntity: (entity: Entity) => boolean;\n readonly isStarredEntity: (entity: Entity) => boolean;\n\n constructor(\n value: UserListFilterKind,\n isOwnedEntity: (entity: Entity) => boolean,\n isStarredEntity: (entity: Entity) => boolean,\n ) {\n this.value = value;\n this.isOwnedEntity = isOwnedEntity;\n this.isStarredEntity = isStarredEntity;\n }\n\n filterEntity(entity: Entity): boolean {\n switch (this.value) {\n case 'owned':\n return this.isOwnedEntity(entity);\n case 'starred':\n return this.isStarredEntity(entity);\n default:\n return true;\n }\n }\n\n toQueryValue(): string {\n return this.value;\n }\n}\n\n/**\n * Filters entities based if it is an orphan or not.\n * @public\n */\nexport class EntityOrphanFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n getCatalogFilters(): Record<string, string | string[]> {\n if (this.value) {\n return { 'metadata.annotations.backstage.io/orphan': String(this.value) };\n }\n return {};\n }\n\n filterEntity(entity: Entity): boolean {\n const orphan = entity.metadata.annotations?.['backstage.io/orphan'];\n return orphan !== undefined && this.value.toString() === orphan;\n }\n}\n\n/**\n * Filters entities based on if it has errors or not.\n * @public\n */\nexport class EntityErrorFilter implements EntityFilter {\n readonly value: boolean;\n\n constructor(value: boolean) {\n this.value = value;\n }\n\n filterEntity(entity: Entity): boolean {\n const error =\n ((entity as AlphaEntity)?.status?.items?.length as number) > 0;\n return error !== undefined && this.value === error;\n }\n}\n\n/**\n * Sort entities by a given field/column.\n * @public\n */\nexport class EntityOrderFilter implements EntityFilter {\n readonly values: [string, 'asc' | 'desc'][];\n\n constructor(values: [string, 'asc' | 'desc'][]) {\n this.values = values;\n }\n\n getOrderFilters(): EntityOrderQuery {\n return this.values.map(([field, order]) => ({ field, order }));\n }\n\n toQueryValue(): string[] {\n return this.values.flat();\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 { QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n useVersionedContext,\n} from '@backstage/version-bridge';\nimport { compact, isEqual } from 'lodash';\nimport qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useLocation } from 'react-router-dom';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport useMountedState from 'react-use/esm/useMountedState';\nimport { catalogApiRef } from '../api';\nimport {\n EntityErrorFilter,\n EntityKindFilter,\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityTypeFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityFilter, EntityListPagination } from '../types';\nimport {\n reduceBackendCatalogFilters,\n reduceCatalogFilters,\n reduceEntityFilters,\n} from '../utils/filters';\n\n/** @public */\nexport type DefaultEntityFilters = {\n kind?: EntityKindFilter;\n type?: EntityTypeFilter;\n user?: UserListFilter | EntityUserFilter;\n owners?: EntityOwnerFilter;\n lifecycles?: EntityLifecycleFilter;\n tags?: EntityTagFilter;\n text?: EntityTextFilter;\n orphan?: EntityOrphanFilter;\n error?: EntityErrorFilter;\n namespace?: EntityNamespaceFilter;\n order?: EntityOrderFilter;\n};\n\n/** @public */\nexport type PaginationMode = 'cursor' | 'offset' | 'none';\n\n/** @public */\nexport type EntityListContextProps<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n> = {\n /**\n * The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension\n * of that default (to add custom filter types).\n */\n filters: EntityFilters;\n\n /**\n * The resolved list of catalog entities, after all filters are applied.\n */\n entities: Entity[];\n\n /**\n * The resolved list of catalog entities, after _only catalog-backend_ filters are applied.\n */\n backendEntities: Entity[];\n\n /**\n * Update one or more of the registered filters. Optional filters can be set to `undefined` to\n * reset the filter.\n */\n updateFilters: (\n filters:\n | Partial<EntityFilters>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => void;\n\n /**\n * Filter values from query parameters.\n */\n queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;\n\n loading: boolean;\n error?: Error;\n\n pageInfo?: {\n next?: () => void;\n prev?: () => void;\n };\n totalItems?: number;\n totalItemsLoading: boolean;\n limit: number;\n offset?: number;\n setLimit: (limit: number) => void;\n setOffset?: (offset: number) => void;\n paginationMode: PaginationMode;\n\n /**\n * Trigger refresh of entities and entity totals.\n */\n refresh?: () => void;\n};\n\n// This context has support for multiple concurrent versions of this package.\n// It is currently used in parallel with the old context in order to provide\n// a smooth transition, but will eventually be the only context we use.\nexport const NewEntityListContext = createVersionedContext<{\n 1: EntityListContextProps<any>;\n}>('entity-list-context');\n\n/**\n * Creates new context for entity listing and filtering.\n */\nexport const OldEntityListContext = createContext<\n EntityListContextProps<any> | undefined\n>(undefined);\n\ntype BackendState = {\n backendEntities: Entity[];\n pageInfo?: QueryEntitiesResponse['pageInfo'];\n totalItems?: number;\n};\n\n/**\n * @public\n */\nexport type EntityListProviderProps = PropsWithChildren<{\n pagination?: EntityListPagination;\n}>;\n\n/**\n * Provides entities and filters for a catalog listing.\n * @public\n */\nexport const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(\n props: EntityListProviderProps,\n) => {\n const isMounted = useMountedState();\n const catalogApi = useApi(catalogApiRef);\n const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(\n {} as EntityFilters,\n );\n\n // We use react-router's useLocation hook so updates from external sources trigger an update to\n // the queryParameters in outputState. Updates from this hook use replaceState below and won't\n // trigger a useLocation change; this would instead come from an external source, such as a manual\n // update of the URL or two catalog sidebar links with different catalog filters.\n const location = useLocation();\n\n let paginationMode: PaginationMode = 'none';\n if (props.pagination === true) {\n paginationMode = 'cursor';\n } else if (typeof props.pagination === 'object') {\n paginationMode = props.pagination.mode ?? 'cursor';\n }\n const paginationLimit =\n typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20;\n\n const {\n queryParameters,\n cursor: initialCursor,\n offset: initialOffset,\n limit: initialLimit,\n } = useMemo(() => {\n const parsed = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n\n let limit = paginationLimit;\n if (typeof parsed.limit === 'string') {\n const queryLimit = Number.parseInt(parsed.limit, 10);\n if (!isNaN(queryLimit)) {\n limit = queryLimit;\n }\n }\n\n const offset =\n typeof parsed.offset === 'string' && paginationMode === 'offset'\n ? Number.parseInt(parsed.offset, 10)\n : undefined;\n\n return {\n queryParameters: (parsed.filters ?? {}) as Record<\n string,\n string | string[]\n >,\n cursor:\n typeof parsed.cursor === 'string' && paginationMode === 'cursor'\n ? parsed.cursor\n : undefined,\n offset:\n paginationMode === 'offset' && offset && !isNaN(offset)\n ? offset\n : undefined,\n limit,\n };\n }, [paginationMode, location.search, paginationLimit]);\n\n const [cursor, setCursor] = useState(initialCursor);\n const [offset, setOffset] = useState<number | undefined>(initialOffset);\n const [limit, setLimit] = useState(initialLimit);\n\n const [backendState, setBackendState] = useState<BackendState>({\n backendEntities: [],\n });\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | undefined>();\n const [refreshToken, setRefreshToken] = useState(0);\n\n // Tracks the params of the last API call so identical requests are\n // skipped even when requestedFilters changes (e.g. a label change\n // or a frontend-only filter addition).\n const lastFetchParamsRef = useRef<unknown>(undefined);\n // Generation counter — only the most recent fetch updates state,\n // so out-of-order responses from overlapping requests are discarded.\n const fetchGenRef = useRef(0);\n\n // Adjusted filters remove the owners filter for user/group kinds,\n // since ownership is not meaningful for those entity types.\n const adjustedFilters = useMemo(() => {\n const kindValue = requestedFilters.kind?.value?.toLocaleLowerCase('en-US');\n return kindValue === 'user' || kindValue === 'group'\n ? { ...requestedFilters, owners: undefined }\n : requestedFilters;\n }, [requestedFilters]);\n\n const refresh = async () => {\n const compacted = compact(Object.values(adjustedFilters));\n\n let fetchParams: unknown;\n let doFetch: () => Promise<BackendState>;\n\n if (paginationMode !== 'none') {\n if (cursor) {\n fetchParams = { cursor, limit };\n doFetch = async () => {\n const response = await catalogApi.queryEntities({\n cursor,\n limit,\n totalItems: 'exclude',\n });\n return {\n backendEntities: response.items,\n pageInfo: response.pageInfo,\n };\n };\n } else {\n const backendFilter = reduceCatalogFilters(compacted);\n fetchParams = { ...backendFilter, limit, offset };\n doFetch = async () => {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit,\n offset,\n totalItems: 'exclude',\n });\n return {\n backendEntities: response.items,\n pageInfo: response.pageInfo,\n };\n };\n }\n } else {\n const backendFilter = reduceBackendCatalogFilters(compacted);\n const { orderFields } = reduceCatalogFilters(compacted);\n fetchParams = { filter: backendFilter, order: orderFields };\n doFetch = async () => {\n const response = await catalogApi.getEntities({\n filter: backendFilter,\n order: orderFields,\n });\n return { backendEntities: response.items };\n };\n }\n\n // No filters registered yet — wait for filter components to\n // call updateFilters before making the first request.\n // Exception: a cursor in the URL is a self-contained page reference\n // that doesn't need filter state to be valid.\n if (\n compacted.length === 0 &&\n lastFetchParamsRef.current === undefined &&\n !cursor\n ) {\n setLoading(false);\n return;\n }\n\n if (isEqual(fetchParams, lastFetchParamsRef.current)) {\n return;\n }\n lastFetchParamsRef.current = fetchParams;\n\n const gen = ++fetchGenRef.current;\n setLoading(true);\n setError(undefined);\n\n try {\n const result = await doFetch();\n if (gen === fetchGenRef.current) {\n setBackendState(result);\n }\n } catch (e) {\n if (gen === fetchGenRef.current) {\n // Clear the ref so the same params can be retried, and so\n // a response discarded due to a concurrent request (gen mismatch)\n // doesn't permanently block fetching those params again.\n lastFetchParamsRef.current = undefined;\n setError(e as Error);\n }\n } finally {\n if (gen === fetchGenRef.current) {\n setLoading(false);\n }\n }\n };\n\n // Slight debounce on the refresh, since (especially on page load)\n // several filters will be calling updateFilters in rapid succession.\n useDebounce(refresh, 10, [\n adjustedFilters,\n cursor,\n limit,\n offset,\n refreshToken,\n ]);\n\n // Fetch the total count separately, only when filters change. This is\n // decoupled from the main list fetch so that page navigation doesn't\n // re-run the expensive count query, and so that the count can arrive\n // asynchronously without blocking the list response.\n const [{ value: totalItems, loading: totalItemsLoading }, refreshCount] =\n useAsyncFn(async () => {\n if (paginationMode === 'none') {\n return undefined;\n }\n const compacted = compact(Object.values(adjustedFilters));\n if (compacted.length === 0) {\n return undefined;\n }\n const backendFilter = reduceCatalogFilters(compacted);\n try {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit: 0,\n });\n return response.totalItems;\n } catch {\n return undefined;\n }\n }, [catalogApi, paginationMode, adjustedFilters]);\n\n useDebounce(refreshCount, 10, [adjustedFilters, refreshToken]);\n\n // Frontend filtering — synchronous, no debounce needed. Updates\n // instantly when requestedFilters or backendEntities change.\n const entities = useMemo(() => {\n const compacted = compact(Object.values(adjustedFilters));\n const entityFilter = reduceEntityFilters(compacted);\n return backendState.backendEntities.filter(entityFilter);\n }, [adjustedFilters, backendState.backendEntities]);\n\n // Sync filter state to URL query parameters. We use direct history\n // manipulation since useSearchParams and useNavigate in\n // react-router-dom cause unnecessary extra rerenders. Also make sure\n // to replace the state rather than pushing, since we don't want\n // there to be back/forward slots for every single filter change.\n useEffect(() => {\n if (!isMounted() || Object.keys(requestedFilters).length === 0) {\n return;\n }\n const queryParams = Object.keys(requestedFilters).reduce((params, key) => {\n const filter = requestedFilters[key as keyof EntityFilters] as\n | EntityFilter\n | undefined;\n if (filter?.toQueryValue) {\n params[key] = filter.toQueryValue();\n }\n return params;\n }, {} as Record<string, string | string[]>);\n\n const oldParams = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n arrayLimit: 10000,\n });\n const newParams = qs.stringify(\n {\n ...oldParams,\n filters: queryParams,\n ...(paginationMode === 'none' ? {} : { cursor, limit, offset }),\n },\n { addQueryPrefix: true, arrayFormat: 'repeat' },\n );\n const newUrl = `${window.location.pathname}${newParams}`;\n window.history?.replaceState(null, document.title, newUrl);\n }, [\n cursor,\n isMounted,\n limit,\n location.search,\n offset,\n requestedFilters,\n paginationMode,\n ]);\n\n const updateFilters = useCallback(\n (\n update:\n | Partial<EntityFilter>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => {\n // changing filters will affect pagination, so we need to reset\n // the cursor and start from the first page.\n // TODO(vinzscam): this is currently causing issues at page reload\n // where the state is not kept. Unfortunately we need to rethink\n // the way filters work in order to fix this.\n if (paginationMode === 'cursor') {\n setCursor(undefined);\n } else if (paginationMode === 'offset') {\n // Same thing with offset\n setOffset(0);\n }\n setRequestedFilters(prevFilters => {\n const newFilters =\n typeof update === 'function' ? update(prevFilters) : update;\n return { ...prevFilters, ...newFilters };\n });\n },\n [paginationMode],\n );\n\n const triggerRefresh = useCallback(() => {\n // Clear the ref to allow refetching with the same params.\n lastFetchParamsRef.current = undefined;\n setRefreshToken(t => t + 1);\n }, []);\n\n const pageInfo = useMemo(() => {\n if (paginationMode !== 'cursor') {\n return undefined;\n }\n\n const prevCursor = backendState.pageInfo?.prevCursor;\n const nextCursor = backendState.pageInfo?.nextCursor;\n return {\n prev: prevCursor ? () => setCursor(prevCursor) : undefined,\n next: nextCursor ? () => setCursor(nextCursor) : undefined,\n };\n }, [paginationMode, backendState.pageInfo]);\n\n const value = useMemo(\n () => ({\n filters: requestedFilters,\n entities,\n backendEntities: backendState.backendEntities,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n totalItems:\n paginationMode === 'none'\n ? entities.length\n : totalItems ?? backendState.totalItems,\n totalItemsLoading: paginationMode !== 'none' && totalItemsLoading,\n limit,\n offset,\n setLimit,\n setOffset,\n paginationMode,\n refresh: triggerRefresh,\n }),\n [\n requestedFilters,\n entities,\n backendState,\n totalItems,\n totalItemsLoading,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n paginationMode,\n limit,\n offset,\n setLimit,\n setOffset,\n triggerRefresh,\n ],\n );\n\n return (\n <OldEntityListContext.Provider value={value}>\n <NewEntityListContext.Provider\n value={createVersionedValueMap({ 1: value })}\n >\n {props.children}\n </NewEntityListContext.Provider>\n </OldEntityListContext.Provider>\n );\n};\n\n/**\n * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.\n * @public\n */\nexport function useEntityList<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n>(): EntityListContextProps<EntityFilters> {\n const versionedHolder = useVersionedContext<{\n 1: EntityListContextProps<any>;\n }>('entity-list-context');\n const oldContext = useContext(OldEntityListContext);\n\n if (versionedHolder) {\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error('EntityListContext v1 not available');\n }\n return value;\n }\n\n if (oldContext) {\n return oldContext;\n }\n\n throw new Error('useEntityList must be used within EntityListProvider');\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 {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useMemo } from 'react';\nimport useObservable from 'react-use/esm/useObservable';\nimport { starredEntitiesApiRef } from '../apis';\n\nfunction getEntityRef(\n entityOrRef: Entity | CompoundEntityRef | string,\n): string {\n return typeof entityOrRef === 'string'\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n}\n\n/** @public */\nexport function useStarredEntities(): {\n starredEntities: Set<string>;\n toggleStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => void;\n isStarredEntity: (\n entityOrRef: Entity | CompoundEntityRef | string,\n ) => boolean;\n} {\n const starredEntitiesApi = useApi(starredEntitiesApiRef);\n\n const starredEntities = useObservable(\n useMemo(() => starredEntitiesApi.starredEntitie$(), [starredEntitiesApi]),\n new Set<string>(),\n );\n\n const isStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntities.has(getEntityRef(entityOrRef)),\n [starredEntities],\n );\n\n const toggleStarredEntity = useCallback(\n (entityOrRef: Entity | CompoundEntityRef | string) =>\n starredEntitiesApi.toggleStarred(getEntityRef(entityOrRef)).then(),\n [starredEntitiesApi],\n );\n\n return {\n starredEntities,\n toggleStarredEntity,\n isStarredEntity,\n };\n}\n","/*\n * Copyright 2021 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 { Entity } from '@backstage/catalog-model';\nimport { EntityFilter } from '../types';\nimport {\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityOrderQuery } from '@backstage/catalog-client';\n\nexport interface CatalogFilters {\n filter: Record<string, string | symbol | (string | symbol)[]>;\n fullTextFilter?: {\n term: string;\n };\n orderFields?: EntityOrderQuery;\n}\n\nfunction isEntityTextFilter(t: EntityFilter): t is EntityTextFilter {\n return !!(t as EntityTextFilter).getFullTextFilters;\n}\n\nfunction isEntityOrderFilter(t: EntityFilter): t is EntityOrderFilter {\n return !!(t as EntityOrderFilter).getOrderFilters;\n}\n\nexport function reduceCatalogFilters(filters: EntityFilter[]): CatalogFilters {\n const condensedFilters = filters.reduce<CatalogFilters['filter']>(\n (compoundFilter, filter) => {\n return {\n ...compoundFilter,\n ...(filter.getCatalogFilters ? filter.getCatalogFilters() : {}),\n };\n },\n {},\n );\n\n const fullTextFilter = filters.find(isEntityTextFilter)?.getFullTextFilters();\n\n const orderFields = filters.find(isEntityOrderFilter)?.getOrderFilters() || [\n {\n field: 'metadata.name',\n order: 'asc',\n },\n ];\n return { filter: condensedFilters, fullTextFilter, orderFields };\n}\n\n/**\n * This function computes and returns an object containing the filters to be sent\n * to the backend. Any filter coming from `EntityKindFilter` and `EntityTypeFilter`, together\n * with custom filter set by the adopters is allowed. This function is used by `EntityListProvider`\n * and it won't be needed anymore in the future once pagination is implemented, as all the filters\n * will be applied backend-side.\n */\nexport function reduceBackendCatalogFilters(filters: EntityFilter[]) {\n const backendCatalogFilters: Record<\n string,\n string | symbol | (string | symbol)[]\n > = {};\n\n filters.forEach(filter => {\n if (\n filter instanceof EntityTagFilter ||\n filter instanceof EntityOwnerFilter ||\n filter instanceof EntityLifecycleFilter ||\n filter instanceof EntityNamespaceFilter ||\n filter instanceof EntityUserFilter ||\n filter instanceof EntityOrphanFilter ||\n filter instanceof EntityTextFilter ||\n filter instanceof UserListFilter\n ) {\n return;\n }\n Object.assign(backendCatalogFilters, filter.getCatalogFilters?.() || {});\n });\n\n return backendCatalogFilters;\n}\n\nexport function reduceEntityFilters(\n filters: EntityFilter[],\n): (entity: Entity) => boolean {\n return (entity: Entity) =>\n filters.every(\n filter => !filter.filterEntity || filter.filterEntity(entity),\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 {\n Entity,\n CompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\n\n// TODO(freben): This should be returning entity refs instead\n/**\n * Get the related entity references.\n *\n * @public\n */\nexport function getEntityRelations(\n entity: Entity | undefined,\n relationType: string,\n filter?: { kind: string },\n): CompoundEntityRef[] {\n let entityNames =\n entity?.relations\n ?.filter(r => r.type === relationType)\n .map(r => parseEntityRef(r.targetRef)) || [];\n\n if (filter?.kind) {\n entityNames = entityNames.filter(\n e =>\n e.kind.toLocaleLowerCase('en-US') ===\n filter.kind.toLocaleLowerCase('en-US'),\n );\n }\n\n return entityNames;\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 { useMemo } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\n\n/** @public */\nexport type HighlightedSearchResultTextClassKey = 'highlight';\n\nconst useStyles = makeStyles(\n () => ({\n highlight: {},\n }),\n { name: 'BackstageHighlightedSearchResultText' },\n);\n\n/**\n * Props for {@link HighlightedSearchResultText}.\n *\n * @public\n */\nexport type HighlightedSearchResultTextProps = {\n text: string;\n preTag: string;\n postTag: string;\n};\n\n/**\n * @public\n */\nexport const HighlightedSearchResultText = (\n props: HighlightedSearchResultTextProps,\n) => {\n const { text, preTag, postTag } = props;\n\n const classes = useStyles();\n const terms = useMemo(\n () => text.split(new RegExp(`(${preTag}.+?${postTag})`)),\n [postTag, preTag, text],\n );\n\n return (\n <>\n {terms.map((t, idx) =>\n t.includes(preTag) ? (\n <mark className={classes.highlight} key={idx}>\n {t.replace(new RegExp(`${preTag}|${postTag}`, 'g'), '')}\n </mark>\n ) : (\n t\n ),\n )}\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 { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * @public\n */\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\n/**\n * @public\n */\nexport interface SearchApi {\n query(\n query: SearchQuery,\n options?: { signal?: AbortSignal },\n ): Promise<SearchResultSet>;\n}\n\n/**\n * @public\n *\n * Search Api Mock that can be used in tests and storybooks\n */\nexport class MockSearchApi implements SearchApi {\n public mockedResults?: SearchResultSet;\n\n constructor(mockedResults?: SearchResultSet) {\n this.mockedResults = mockedResults;\n }\n\n query(\n _query: SearchQuery,\n _options?: { signal?: AbortSignal },\n ): Promise<SearchResultSet> {\n return Promise.resolve(this.mockedResults || { results: [] });\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 { isEqual } from 'lodash';\nimport {\n SetStateAction,\n Dispatch,\n DispatchWithoutAction,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/esm/useAsync';\nimport usePrevious from 'react-use/esm/usePrevious';\n\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport { JsonObject } from '@backstage/types';\nimport {\n AnalyticsContext,\n useApi,\n configApiRef,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/plugin-search-common';\n\nimport { searchApiRef } from '../api';\n\n/**\n *\n * @public\n */\nexport type SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n setTerm: Dispatch<SetStateAction<string>>;\n setTypes: Dispatch<SetStateAction<string[]>>;\n setFilters: Dispatch<SetStateAction<JsonObject>>;\n setPageLimit: Dispatch<SetStateAction<number | undefined>>;\n setPageCursor: Dispatch<SetStateAction<string | undefined>>;\n fetchNextPage?: DispatchWithoutAction;\n fetchPreviousPage?: DispatchWithoutAction;\n} & SearchContextState;\n\n/**\n *\n * @public\n */\nexport type SearchContextState = {\n term: string;\n types: string[];\n filters: JsonObject;\n pageLimit?: number;\n pageCursor?: string;\n};\n\nconst SearchContext = createVersionedContext<{\n 1: SearchContextValue;\n}>('search-context');\n\n/**\n * @public\n *\n * React hook which provides the search context\n */\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (!context) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n\n const value = context.atVersion(1);\n if (!value) {\n throw new Error('No SearchContext v1 found');\n }\n return value;\n};\n\n/**\n * @public\n *\n * React hook which checks for an existing search context\n */\nexport const useSearchContextCheck = () => {\n const context = useContext(SearchContext);\n return context !== undefined;\n};\n\n/**\n * The initial state of `SearchContextProvider`.\n *\n */\nconst defaultInitialSearchState: SearchContextState = {\n term: '',\n types: [],\n filters: {},\n pageLimit: undefined,\n pageCursor: undefined,\n};\n\nconst useSearchContextValue = (\n initialValue: SearchContextState = defaultInitialSearchState,\n) => {\n const searchApi = useApi(searchApiRef);\n const analytics = useAnalytics();\n\n const [term, setTerm] = useState<string>(initialValue.term);\n const [types, setTypes] = useState<string[]>(initialValue.types);\n const [filters, setFilters] = useState<JsonObject>(initialValue.filters);\n const [pageLimit, setPageLimit] = useState<number | undefined>(\n initialValue.pageLimit,\n );\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialValue.pageCursor,\n );\n const isFirstEmptyMount = useRef(true);\n\n const prevTerm = usePrevious(term);\n const prevFilters = usePrevious(filters);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const result = useAsync(async (): Promise<SearchResultSet> => {\n if (isFirstEmptyMount.current) {\n isFirstEmptyMount.current = false;\n if (!term && !types.length && !Object.keys(filters).length) {\n return {\n results: [],\n numberOfResults: 0,\n };\n }\n }\n\n // Here we cancel the previous request before making a new one\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n const resultSet = await searchApi.query(\n {\n term,\n types,\n filters,\n pageLimit,\n pageCursor,\n },\n { signal: controller.signal },\n );\n\n if (term) {\n analytics.captureEvent('search', term, {\n value: resultSet.numberOfResults,\n });\n }\n return resultSet;\n }, [term, types, filters, pageLimit, pageCursor]);\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n // Only reset the term if it has been modified by the user at least once, the initial state must not reset the term.\n if (prevTerm !== undefined && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, setPageCursor]);\n\n useEffect(() => {\n // Any time filters is reset, we want to start from page 0.\n // Only reset the page if it has been modified by the user at least once, the initial state must not reset the page.\n if (prevFilters !== undefined && !isEqual(filters, prevFilters)) {\n setPageCursor(undefined);\n }\n }, [filters, prevFilters, setPageCursor]);\n\n const value: SearchContextValue = {\n result,\n term,\n setTerm,\n types,\n setTypes,\n filters,\n setFilters,\n pageLimit,\n setPageLimit,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n return value;\n};\n\nexport type LocalSearchContextProps = PropsWithChildren<{\n initialState?: SearchContextState;\n}>;\n\nconst LocalSearchContext = (props: SearchContextProviderProps) => {\n const { initialState, children } = props;\n const value = useSearchContextValue(initialState);\n\n return (\n <AnalyticsContext\n attributes={{ searchTypes: value.types.sort().join(',') }}\n >\n <SearchContext.Provider value={createVersionedValueMap({ 1: value })}>\n {children}\n </SearchContext.Provider>\n </AnalyticsContext>\n );\n};\n\n/**\n * Props for {@link SearchContextProvider}\n *\n * @public\n */\nexport type SearchContextProviderProps =\n | PropsWithChildren<{\n /**\n * State initialized by a local context.\n */\n initialState?: SearchContextState;\n /**\n * Do not create an inheritance from the parent, as a new initial state must be defined in a local context.\n */\n inheritParentContextIfAvailable?: never;\n }>\n | PropsWithChildren<{\n /**\n * Does not accept initial state since it is already initialized by parent context.\n */\n initialState?: never;\n /**\n * If true, don't create a child context if there is a parent one already defined.\n * @remarks Defaults to false.\n */\n inheritParentContextIfAvailable?: boolean;\n }>;\n\n/**\n * @public\n * Search context provider which gives you access to shared state between search components\n */\nexport const SearchContextProvider = (props: SearchContextProviderProps) => {\n const { initialState, inheritParentContextIfAvailable, children } = props;\n const hasParentContext = useSearchContextCheck();\n\n const configApi = useApi(configApiRef);\n\n const propsInitialSearchState = initialState ?? {};\n\n const configInitialSearchState = configApi.has('search.query.pageLimit')\n ? { pageLimit: configApi.getNumber('search.query.pageLimit') }\n : {};\n\n const searchContextInitialState = {\n ...defaultInitialSearchState,\n ...propsInitialSearchState,\n ...configInitialSearchState,\n };\n\n return hasParentContext && inheritParentContextIfAvailable ? (\n <>{children}</>\n ) : (\n <LocalSearchContext initialState={searchContextInitialState}>\n {children}\n </LocalSearchContext>\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 { PropsWithChildren, useState, useEffect, useCallback } from 'react';\n\nimport { create } from 'jss';\nimport StylesProvider from '@material-ui/styles/StylesProvider';\nimport jssPreset from '@material-ui/styles/jssPreset';\n\n/**\n * Name for the event dispatched when ShadowRoot styles are loaded.\n * @public\n */\nexport const SHADOW_DOM_STYLE_LOAD_EVENT = 'TECH_DOCS_SHADOW_DOM_STYLE_LOAD';\n\n/**\n * Dispatch style load event after all styles are loaded.\n * @param element - the ShadowRoot tree.\n */\nconst useShadowDomStylesEvents = (element: Element | null) => {\n useEffect(() => {\n if (!element) {\n return () => {};\n }\n\n const styles = element.querySelectorAll<HTMLElement>(\n 'head > link[rel=\"stylesheet\"]',\n );\n\n let count = styles?.length ?? 0;\n const event = new CustomEvent(SHADOW_DOM_STYLE_LOAD_EVENT);\n\n if (!count) {\n element.dispatchEvent(event);\n return () => {};\n }\n\n const handleLoad = () => {\n if (--count === 0) {\n element.dispatchEvent(event);\n }\n };\n\n styles?.forEach(style => {\n style.addEventListener('load', handleLoad);\n });\n\n return () => {\n styles?.forEach(style => {\n style.removeEventListener('load', handleLoad);\n });\n };\n }, [element]);\n};\n\n/**\n * Returns the style's loading state.\n *\n * @example\n * Here's an example that updates the sidebar position only after styles are calculated:\n * ```jsx\n * import {\n * TechDocsShadowDom,\n * useShadowDomStylesLoading,\n * } from '@backstage/plugin-techdocs-react';\n *\n * export const TechDocsReaderPageContent = () => {\n * // ...\n * const dom = useTechDocsReaderDom(entity);\n * const isStyleLoading = useShadowDomStylesLoading(dom);\n *\n * const updateSidebarPosition = useCallback(() => {\n * //...\n * }, [dom]);\n *\n * useEffect(() => {\n * if (!isStyleLoading) {\n * updateSidebarPosition();\n * }\n * }, [isStyleLoading, updateSidebarPosition]);\n *\n * const handleDomAppend = useCallback(\n * (newShadowRoot: ShadowRoot) => {\n * setShadowRoot(newShadowRoot);\n * },\n * [setShadowRoot],\n * );\n *\n * return <TechDocsShadowDom element={dom} onAppend={handleDomAppend} />;\n * };\n * ```\n *\n * @param element - which is the ShadowRoot tree.\n * @returns a boolean value, true if styles are being loaded.\n * @public\n */\nexport const useShadowDomStylesLoading = (element: Element | null) => {\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n if (!element) return () => {};\n\n setLoading(true);\n\n const style = (element as HTMLElement).style;\n\n style.setProperty('opacity', '0');\n\n const handleLoad = () => {\n setLoading(false);\n style.setProperty('opacity', '1');\n };\n\n element.addEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, handleLoad);\n\n return () => {\n element.removeEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, handleLoad);\n };\n }, [element]);\n\n return loading;\n};\n\n/**\n * Props for {@link TechDocsShadowDom}.\n *\n * @remarks\n * If you want to use portals to render Material UI components in the Shadow DOM,\n * you must render these portals as children because this component wraps its children in a Material UI StylesProvider\n * to ensure that Material UI styles are applied.\n *\n * @public\n */\nexport type TechDocsShadowDomProps = PropsWithChildren<{\n /**\n * Element tree that is appended to ShadowRoot.\n */\n element: Element;\n /**\n * Callback called when the element tree is appended in ShadowRoot.\n */\n onAppend?: (shadowRoot: ShadowRoot) => void;\n}>;\n\n/**\n * Renders a tree of elements in a Shadow DOM.\n *\n * @remarks\n * Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow DOM causing the screen to flash multiple times,\n * so if you want to know when Shadow DOM styles are computed, you can listen for the \"TECH_DOCS_SHADOW_DOM_STYLE_LOAD\" event dispatched by the element tree.\n *\n * @example\n * Here is an example using this component and also listening for styles loaded event:\n *```jsx\n * import {\n * TechDocsShadowDom,\n * SHADOW_DOM_STYLE_LOAD_EVENT,\n * } from '@backstage/plugin-techdocs-react';\n *\n * export const TechDocsReaderPageContent = ({ entity }: TechDocsReaderPageContentProps) => {\n * // ...\n * const dom = useTechDocsReaderDom(entity);\n *\n * useEffect(() => {\n * const updateSidebarPosition = () => {\n * // ...\n * };\n * dom?.addEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, updateSidebarPosition);\n * return () => {\n * dom?.removeEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, updateSidebarPosition);\n * };\n * }, [dom]);\n *\n * const handleDomAppend = useCallback(\n * (newShadowRoot: ShadowRoot) => {\n * setShadowRoot(newShadowRoot);\n * },\n * [setShadowRoot],\n * );\n *\n * return <TechDocsShadowDom element={dom} onAppend={handleDomAppend} />;\n * };\n * ```\n *\n * @param props - see {@link TechDocsShadowDomProps}.\n * @public\n */\nexport const TechDocsShadowDom = (props: TechDocsShadowDomProps) => {\n const { element, onAppend, children } = props;\n\n const [jss, setJss] = useState(\n create({\n ...jssPreset(),\n insertionPoint: undefined,\n }),\n );\n\n useShadowDomStylesEvents(element);\n\n const ref = useCallback(\n (shadowHost: HTMLDivElement) => {\n if (!element || !shadowHost) return;\n\n setJss(\n create({\n ...jssPreset(),\n insertionPoint: element.querySelector('head') || undefined,\n }),\n );\n\n let shadowRoot = shadowHost.shadowRoot;\n\n if (!shadowRoot) {\n shadowRoot = shadowHost.attachShadow({ mode: 'open' });\n }\n\n shadowRoot.replaceChildren(element);\n\n if (typeof onAppend === 'function') {\n onAppend(shadowRoot);\n }\n },\n [element, onAppend],\n );\n\n return (\n <>\n {/* The sheetsManager={new Map()} is needed in order to deduplicate the injection of CSS in the page. */}\n <StylesProvider jss={jss} sheetsManager={new Map()}>\n <div ref={ref} data-testid=\"techdocs-native-shadowroot\" />\n {children}\n </StylesProvider>\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 {\n techdocsApiRef,\n techdocsStorageApiRef,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsClient, TechDocsStorageClient } from './client';\nimport {\n rootDocsRouteRef,\n rootRouteRef,\n rootCatalogDocsRouteRef,\n} from './routes';\nimport {\n configApiRef,\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n createSearchResultListItemExtension,\n SearchResultListItemExtensionProps,\n} from '@backstage/plugin-search-react';\nimport { TechDocsSearchResultListItemProps } from './search/components/TechDocsSearchResultListItem';\n\n/**\n * The Backstage plugin that renders technical documentation for your components\n *\n * @public\n */\nexport const techdocsPlugin = createPlugin({\n id: 'techdocs',\n apis: [\n createApiFactory({\n api: techdocsStorageApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsStorageClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n createApiFactory({\n api: techdocsApiRef,\n deps: {\n configApi: configApiRef,\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, discoveryApi, fetchApi }) =>\n new TechDocsClient({\n configApi,\n discoveryApi,\n fetchApi,\n }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n docRoot: rootDocsRouteRef,\n entityContent: rootCatalogDocsRouteRef,\n },\n});\n\n/**\n * Routable extension used to render docs\n *\n * @public\n */\nexport const TechdocsPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechdocsPage',\n component: () => import('./Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Routable extension used to render docs on Entity page\n *\n * @public\n */\nexport const EntityTechdocsContent = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'EntityTechdocsContent',\n component: () => import('./Router').then(m => m.LegacyEmbeddedDocsRouter),\n mountPoint: rootCatalogDocsRouteRef,\n }),\n);\n\n/**\n * Component which takes a custom tabs config object and renders a documentation landing page.\n *\n * @public\n */\nexport const TechDocsCustomHome = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsCustomHome',\n component: () =>\n import('./home/components/TechDocsCustomHome').then(\n m => m.TechDocsCustomHome,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Responsible for rendering the provided router element\n *\n * @public\n */\nexport const TechDocsIndexPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsIndexPage',\n component: () =>\n import('./home/components/TechDocsIndexPage').then(\n m => m.TechDocsIndexPage,\n ),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * Component responsible for composing a TechDocs reader page experience\n *\n * @public\n */\nexport const TechDocsReaderPage = techdocsPlugin.provide(\n createRoutableExtension({\n name: 'TechDocsReaderPage',\n component: () =>\n import('./reader/components/TechDocsReaderPage').then(\n m => m.TechDocsReaderPage,\n ),\n mountPoint: rootDocsRouteRef,\n }),\n);\n\n/**\n * React extension used to render results on Search page or modal\n *\n * @public\n */\nexport const TechDocsSearchResultListItem: (\n props: SearchResultListItemExtensionProps<TechDocsSearchResultListItemProps>,\n) => JSX.Element | null = techdocsPlugin.provide(\n createSearchResultListItemExtension({\n name: 'TechDocsSearchResultListItem',\n component: () =>\n import('./search/components/TechDocsSearchResultListItem').then(\n m => m.TechDocsSearchResultListItem,\n ),\n predicate: result => result.type === 'techdocs',\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 {\n PluginConfig,\n BackstagePlugin,\n Extension,\n AnyRoutes,\n AnyExternalRoutes,\n PluginFeatureFlagConfig,\n} from './types';\nimport { AnyApiFactory } from '../apis';\n\n/**\n * @internal\n */\nexport class PluginImpl<\n Routes extends AnyRoutes,\n ExternalRoutes extends AnyExternalRoutes,\n> implements BackstagePlugin<Routes, ExternalRoutes>\n{\n constructor(private readonly config: PluginConfig<Routes, ExternalRoutes>) {}\n\n getId(): string {\n return this.config.id;\n }\n\n getApis(): Iterable<AnyApiFactory> {\n return this.config.apis ?? [];\n }\n\n getFeatureFlags(): Iterable<PluginFeatureFlagConfig> {\n return this.config.featureFlags?.slice() ?? [];\n }\n\n get routes(): Routes {\n return this.config.routes ?? ({} as Routes);\n }\n\n get externalRoutes(): ExternalRoutes {\n return this.config.externalRoutes ?? ({} as ExternalRoutes);\n }\n\n provide<T>(extension: Extension<T>): T {\n return extension.expose(this);\n }\n\n toString() {\n return `plugin{${this.config.id}}`;\n }\n}\n\n/**\n * Creates Backstage Plugin from config.\n *\n * @param config - Plugin configuration.\n * @public\n */\nexport function createPlugin<\n Routes extends AnyRoutes = {},\n ExternalRoutes extends AnyExternalRoutes = {},\n>(\n config: PluginConfig<Routes, ExternalRoutes>,\n): BackstagePlugin<Routes, ExternalRoutes> {\n return new PluginImpl(config);\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 {\n Entity,\n getCompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\nimport { TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport { getEntityRootTechDocsPath } from '@backstage/plugin-techdocs-react';\n\nimport { TechDocsReaderPage } from './plugin';\nimport { TechDocsReaderPageContent } from './reader/components/TechDocsReaderPageContent';\nimport { TechDocsReaderPageSubheader } from './reader/components/TechDocsReaderPageSubheader';\nimport { useEntityPageTechDocsRedirect } from './search/hooks/useTechDocsLocation';\n\ntype EntityPageDocsProps = {\n entity: Entity;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\nexport const EntityPageDocs = ({\n entity,\n withSearch = true,\n}: EntityPageDocsProps) => {\n let entityRef = getCompoundEntityRef(entity);\n\n const searchResultUrlMapper = useEntityPageTechDocsRedirect(entityRef);\n\n if (entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]) {\n try {\n entityRef = parseEntityRef(\n entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION],\n );\n } catch {\n // not a fan of this but we don't care if the parseEntityRef fails\n }\n }\n\n const defaultPath = getEntityRootTechDocsPath(entity);\n\n return (\n <TechDocsReaderPage entityRef={entityRef}>\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent\n withSearch={withSearch}\n searchResultUrlMapper={searchResultUrlMapper}\n defaultPath={defaultPath}\n />\n </TechDocsReaderPage>\n );\n};\n","/*\n * Copyright 2024 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 */\nimport { useMemo } from 'react';\n\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nimport { rootCatalogDocsRouteRef, rootDocsRouteRef } from '../../routes';\n\nconst trimStartSlash = (path: string) => path.replace(/^\\/+/, '');\nconst trimEndSlash = (path: string) => path.replace(/\\/+$/, '');\n\n/**\n * Returns a function that takes a location to a Tech Docs entry, and returns a\n * new location, re-routed to the catalog page tab.\n *\n * @internal\n */\nexport function useEntityPageTechDocsRedirect(entityRef: CompoundEntityRef) {\n const { kind, name, namespace } = entityRef;\n\n const routeDocsRoot = useRouteRef(rootDocsRouteRef);\n const routeDocsCatalog = useRouteRef(rootCatalogDocsRouteRef);\n\n // Re-routes a /docs/:namespace/:kind/:name/* location into\n // /catalog/:namespace/:kind/:name/docs/*, while handling situations where\n // these defaults are changed.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const reRouteLocationToCatalog = useMemo(() => {\n const rootDocsPath = trimEndSlash(routeDocsRoot({ kind, namespace, name }));\n const catalogDocsPath = trimEndSlash(routeDocsCatalog());\n\n return (url: string): string => {\n if (\n url\n .toLocaleLowerCase('en-US')\n .startsWith(rootDocsPath.toLocaleLowerCase('en-US'))\n ) {\n const suffix = trimStartSlash(url.slice(rootDocsPath.length));\n return suffix.length === 0 || suffix.startsWith('#')\n ? `${catalogDocsPath}${suffix}`\n : `${catalogDocsPath}/${suffix}`;\n }\n return url;\n };\n }, [routeDocsRoot, routeDocsCatalog, kind, name, namespace]);\n\n return reRouteLocationToCatalog;\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 Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { CodeSnippet, Link, EmptyState } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { useEntity } from '../../hooks';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/** @public */\nexport type MissingAnnotationEmptyStateClassKey = 'code';\n\nconst useStyles = makeStyles(\n theme => ({\n code: {\n borderRadius: 6,\n margin: theme.spacing(2, 0),\n background:\n theme.palette.type === 'dark' ? '#444' : theme.palette.common.white,\n },\n }),\n { name: 'BackstageMissingAnnotationEmptyState' },\n);\n\nfunction generateYamlExample(\n annotations: string[],\n entity?: Entity,\n): { yamlText: string; lineNumbers: number[] } {\n const kind = entity?.kind || 'Component';\n const name = entity?.metadata.name || 'example';\n const type = entity?.spec?.type || 'website';\n const owner = entity?.spec?.owner || 'user:default/guest';\n\n const yamlText = `apiVersion: backstage.io/v1alpha1\nkind: ${kind}\nmetadata:\n name: ${name}\n annotations:${annotations.map(ann => `\\n ${ann}: value`).join('')}\nspec:\n type: ${type}\n owner: ${owner}`;\n\n let line = 6; // Line 6 is the line number that annotations are added to.\n const lineNumbers: number[] = [];\n annotations.forEach(() => {\n lineNumbers.push(line);\n line++;\n });\n\n return {\n yamlText,\n lineNumbers,\n };\n}\n\nfunction generateDescription(\n annotations: string[],\n entityKind = 'Component',\n t: TranslationFunction<typeof catalogReactTranslationRef.T>,\n) {\n const annotationList = annotations\n .map(ann => <code key={ann}>{ann}</code>)\n .reduce((prev, curr) => (\n <>\n {prev}, {curr}\n </>\n ));\n\n return t('missingAnnotationEmptyState.generateDescription', {\n count: annotations.length,\n entityKind,\n annotations: annotationList,\n });\n}\n\n/**\n * @public\n * Renders an empty state when an annotation is missing from an entity.\n */\nexport function MissingAnnotationEmptyState(props: {\n annotation: string | string[];\n readMoreUrl?: string;\n}) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n let entity: Entity | undefined;\n try {\n const entityContext = useEntity();\n entity = entityContext.entity;\n } catch (err) {\n // ignore when entity context doesnt exist\n }\n\n const { annotation, readMoreUrl } = props;\n const annotations = Array.isArray(annotation) ? annotation : [annotation];\n const url =\n readMoreUrl ||\n 'https://backstage.io/docs/features/software-catalog/well-known-annotations';\n const classes = useStyles();\n\n const entityKind = entity?.kind || 'Component';\n const { yamlText, lineNumbers } = generateYamlExample(annotations, entity);\n return (\n <EmptyState\n missing=\"field\"\n title={t('missingAnnotationEmptyState.title')}\n description={generateDescription(annotations, entityKind, t)}\n action={\n <>\n <Typography variant=\"body1\">\n {t('missingAnnotationEmptyState.annotationYaml', { entityKind })}\n </Typography>\n <Box className={classes.code}>\n <CodeSnippet\n text={yamlText}\n language=\"yaml\"\n showLineNumbers\n highlightedNumbers={lineNumbers}\n customStyle={{ background: 'inherit', fontSize: '115%' }}\n />\n </Box>\n <Button color=\"primary\" component={Link} to={url}>\n {t('missingAnnotationEmptyState.readMore')}\n </Button>\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 { ReactElement, PropsWithChildren } from 'react';\nimport { Route, Routes, useRoutes } from 'react-router-dom';\n\nimport { Entity } from '@backstage/catalog-model';\nimport { EntityPageDocs } from './EntityPageDocs';\nimport { TechDocsIndexPage } from './home/components/TechDocsIndexPage';\nimport { TechDocsReaderPage } from './reader/components/TechDocsReaderPage';\nimport {\n useEntity,\n MissingAnnotationEmptyState,\n} from '@backstage/plugin-catalog-react';\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\n\n/**\n * Helper that takes in entity and returns true/false if TechDocs is available for the entity\n *\n * @public\n */\nexport const isTechDocsAvailable = (entity: Entity) =>\n Boolean(entity?.metadata?.annotations?.[TECHDOCS_ANNOTATION]) ||\n Boolean(entity?.metadata?.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]);\n\n/**\n * Responsible for registering routes for TechDocs, TechDocs Homepage and separate TechDocs page\n *\n * @public\n */\nexport const Router = () => {\n return (\n <Routes>\n <Route path=\"/\" element={<TechDocsIndexPage />} />\n <Route\n path=\"/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n />\n </Routes>\n );\n};\n\nexport const TechDocsReaderRouter = (props: PropsWithChildren) => {\n const { children } = props;\n\n // Using objects instead of <Route> elements, otherwise \"outlet\" will be null on sub-pages and add-ons won't render\n const element = useRoutes([\n {\n path: '*',\n element: <TechDocsReaderPage />,\n children: [\n {\n path: '*',\n element: children,\n },\n ],\n },\n ]);\n\n return element;\n};\n\nexport const EmbeddedDocsRouter = (\n props: PropsWithChildren<{\n emptyState?: ReactElement;\n withSearch?: boolean;\n }>,\n) => {\n const { children, emptyState, withSearch = true } = props;\n const { entity } = useEntity();\n\n // Using objects instead of <Route> elements, otherwise \"outlet\" will be null on sub-pages and add-ons won't render\n const element = useRoutes([\n {\n path: '/*',\n element: <EntityPageDocs entity={entity} withSearch={withSearch} />,\n children: [\n {\n path: '*',\n element: children,\n },\n ],\n },\n ]);\n\n const projectId =\n entity.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION];\n\n if (!projectId) {\n return (\n emptyState ?? (\n <MissingAnnotationEmptyState annotation={[TECHDOCS_ANNOTATION]} />\n )\n );\n }\n return element;\n};\n\n/**\n * Responsible for registering route to view docs on Entity page\n *\n * @public\n */\nexport const LegacyEmbeddedDocsRouter = ({\n children,\n withSearch = true,\n}: PropsWithChildren<{ withSearch?: boolean }>) => {\n // Wrap the Router to avoid exposing the emptyState prop in the non-alpha\n // public API and make it easier for us to change later.\n return <EmbeddedDocsRouter children={children} withSearch={withSearch} />;\n};\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-SearchAutocomplete\":\"t9ib_bVDdW0Xootq\",\"bui-SearchAutocompleteSearchField\":\"Qf03194HgHcI80bI\",\"bui-SearchAutocompleteInput\":\"JW7_WzZ4218yUxN1\",\"bui-SearchAutocompleteClear\":\"O8qR4ow00UGAmbxF\",\"bui-SearchAutocompletePopover\":\"z77XzI20MQEPf2t6\",\"bui-SearchAutocompleteInner\":\"BQZoiGXiru4nlmWr\",\"bui-SearchAutocompleteListBox\":\"mYf5rCmZp8sweHCa\",\"bui-SearchAutocompleteItem\":\"Mooy7E0382UZYzPe\",\"bui-SearchAutocompleteItemContent\":\"GoL56cqq7NIpJ8Ak\",\"bui-SearchAutocompleteLoadingState\":\"kGxB_7841AUUy5BV\",\"bui-SearchAutocompleteEmptyState\":\"Gfbgv_XjouQ_ffOx\"};","/*\n * Copyright 2026 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 { defineComponent } from '../../hooks/useDefinition';\nimport type {\n SearchAutocompleteOwnProps,\n SearchAutocompleteItemOwnProps,\n} from './types';\nimport styles from './SearchAutocomplete.module.css';\n\n/**\n * Component definition for SearchAutocomplete.\n * @public\n */\nexport const SearchAutocompleteDefinition =\n defineComponent<SearchAutocompleteOwnProps>()({\n styles,\n bg: 'consumer',\n classNames: {\n root: 'bui-SearchAutocomplete',\n searchField: 'bui-SearchAutocompleteSearchField',\n searchFieldInput: 'bui-SearchAutocompleteInput',\n searchFieldClear: 'bui-SearchAutocompleteClear',\n popover: 'bui-SearchAutocompletePopover',\n inner: 'bui-SearchAutocompleteInner',\n listBox: 'bui-SearchAutocompleteListBox',\n loadingState: 'bui-SearchAutocompleteLoadingState',\n emptyState: 'bui-SearchAutocompleteEmptyState',\n },\n propDefs: {\n 'aria-label': {},\n 'aria-labelledby': {},\n size: { dataAttribute: true, default: 'small' },\n placeholder: { default: 'Search' },\n inputValue: {},\n onInputChange: {},\n popoverWidth: {},\n popoverPlacement: {},\n children: {},\n isLoading: {},\n defaultOpen: {},\n className: {},\n style: {},\n },\n });\n\n/** @internal */\nexport const SearchAutocompleteItemDefinition =\n defineComponent<SearchAutocompleteItemOwnProps>()({\n styles,\n classNames: {\n root: 'bui-SearchAutocompleteItem',\n itemContent: 'bui-SearchAutocompleteItemContent',\n },\n navigation: { type: 'anchor' },\n propDefs: {\n children: {},\n className: {},\n },\n });\n","/*\n * Copyright 2026 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 { Children, useRef } from 'react';\nimport { useInteractOutside } from 'react-aria';\nimport {\n Autocomplete,\n SearchField as RASearchField,\n Input,\n Button as RAButton,\n Popover as RAPopover,\n ListBox,\n ListBoxItem,\n OverlayTriggerStateContext,\n} from 'react-aria-components';\nimport { useOverlayTriggerState } from 'react-stately';\nimport { RiSearch2Line, RiCloseCircleLine } from '@remixicon/react';\nimport {\n useDefinition,\n type UseDefinitionResult,\n} from '../../hooks/useDefinition';\nimport {\n SearchAutocompleteDefinition,\n SearchAutocompleteItemDefinition,\n} from './definition';\nimport { Box } from '../Box';\nimport { BgReset } from '../../hooks/useBg';\nimport { VisuallyHidden } from '../VisuallyHidden';\nimport {\n getReactAriaAnchorProps,\n type AnchorNavigation,\n} from '../../navigation/useNavigation';\n\nimport type {\n SearchAutocompleteProps,\n SearchAutocompleteItemProps,\n} from './types';\n\nconst SearchAutocompleteEmptyState = () => {\n const { ownProps } = useDefinition(SearchAutocompleteDefinition, {});\n return <div className={ownProps.classes.emptyState}>No results found.</div>;\n};\n\n/**\n * A search input that shows a dropdown list of suggestions as the user types, with loading and empty states.\n *\n * @public\n */\nexport function SearchAutocomplete(props: SearchAutocompleteProps) {\n const { ownProps, dataAttributes } = useDefinition(\n SearchAutocompleteDefinition,\n props,\n );\n const {\n classes,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n inputValue,\n onInputChange,\n placeholder,\n popoverWidth,\n popoverPlacement = 'bottom start',\n children,\n isLoading,\n defaultOpen,\n style,\n } = ownProps;\n\n const triggerRef = useRef<HTMLDivElement | null>(null);\n const popoverRef = useRef<HTMLElement | null>(null);\n const hasValue = !!inputValue;\n const hasChildren = Children.count(children) > 0;\n\n let liveMessage = '';\n if (isLoading) {\n liveMessage = 'Searching';\n } else if (hasValue && !hasChildren) {\n liveMessage = 'No results found';\n }\n const overlayState = useOverlayTriggerState({ defaultOpen });\n\n // Close on interact outside — same pattern as ComboBox.\n // isNonModal disables useOverlay's built-in useInteractOutside,\n // so we add our own that filters out clicks on the trigger.\n useInteractOutside({\n ref: popoverRef,\n onInteractOutside: e => {\n const target = e.target as Element;\n if (triggerRef.current?.contains(target)) {\n return;\n }\n overlayState.close();\n },\n isDisabled: !overlayState.isOpen,\n });\n\n return (\n <OverlayTriggerStateContext.Provider value={overlayState}>\n <Autocomplete\n inputValue={inputValue}\n onInputChange={value => {\n onInputChange?.(value);\n if (value) {\n overlayState.open();\n } else {\n overlayState.close();\n }\n }}\n >\n <RASearchField\n className={classes.searchField}\n aria-label={ariaLabel ?? (ariaLabelledBy ? undefined : placeholder)}\n aria-labelledby={ariaLabelledBy}\n data-size={dataAttributes['data-size']}\n onKeyDown={e => {\n if (e.key === 'Enter' && !overlayState.isOpen && hasValue) {\n e.preventDefault();\n overlayState.open();\n }\n }}\n >\n <div\n ref={triggerRef}\n className={classes.root}\n {...dataAttributes}\n style={style}\n >\n <div aria-hidden=\"true\">\n <RiSearch2Line />\n </div>\n <Input\n className={classes.searchFieldInput}\n placeholder={placeholder}\n />\n <RAButton\n className={classes.searchFieldClear}\n style={{ visibility: hasValue ? 'visible' : 'hidden' }}\n >\n <RiCloseCircleLine />\n </RAButton>\n </div>\n </RASearchField>\n {/* isNonModal keeps the page interactive while the popover is open,\n required for virtual focus (aria-activedescendant) to work correctly */}\n <RAPopover\n ref={popoverRef}\n className={classes.popover}\n triggerRef={triggerRef}\n isNonModal\n placement={popoverPlacement}\n {...(popoverWidth ? { style: { width: popoverWidth } } : {})}\n >\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n <ListBox\n className={classes.listBox}\n autoFocus=\"first\"\n shouldFocusOnHover\n aria-busy={isLoading || undefined}\n data-stale={isLoading || undefined}\n renderEmptyState={() =>\n isLoading ? (\n <div className={classes.loadingState}>Searching...</div>\n ) : (\n <SearchAutocompleteEmptyState />\n )\n }\n onAction={() => {\n overlayState.close();\n }}\n >\n {children}\n </ListBox>\n </Box>\n </BgReset>\n </RAPopover>\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {liveMessage}\n </VisuallyHidden>\n </Autocomplete>\n </OverlayTriggerStateContext.Provider>\n );\n}\n\ntype SearchAutocompleteItemViewProps = {\n definitionResult: UseDefinitionResult<\n typeof SearchAutocompleteItemDefinition,\n SearchAutocompleteItemProps\n >;\n navigation: AnchorNavigation;\n};\n\nfunction SearchAutocompleteItemView({\n definitionResult,\n navigation,\n}: SearchAutocompleteItemViewProps) {\n const { ownProps, restProps } = definitionResult;\n const { classes, children } = ownProps;\n const navigationProps = getReactAriaAnchorProps(navigation, restProps);\n\n return (\n <ListBoxItem\n textValue={typeof children === 'string' ? children : undefined}\n className={classes.root}\n {...restProps}\n {...navigationProps}\n >\n <div className={classes.itemContent}>{children}</div>\n </ListBoxItem>\n );\n}\n\n/**\n * An individual option item within a SearchAutocomplete dropdown.\n *\n * @public\n */\nexport function SearchAutocompleteItem(props: SearchAutocompleteItemProps) {\n const definitionResult = useDefinition(\n SearchAutocompleteItemDefinition,\n props,\n );\n const Navigation = definitionResult.navigation;\n\n return (\n <Navigation\n props={definitionResult.restProps}\n view={SearchAutocompleteItemView}\n viewProps={{ definitionResult }}\n />\n );\n}\n","/*\n * Copyright 2026 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 { useNavigate } from 'react-router-dom';\nimport {\n Text,\n Flex,\n SearchAutocomplete,\n SearchAutocompleteItem,\n} from '@backstage/ui';\nimport { SearchContextProvider } from '@backstage/plugin-search-react';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { HighlightedSearchResultText } from '@backstage/plugin-search-react';\nimport { useTechDocsSearch } from '../../hooks/useTechDocsSearch';\n\ntype TechDocsReaderSearchBarProps = {\n entityId: CompoundEntityRef;\n};\n\nconst TechDocsReaderSearchBar = (props: TechDocsReaderSearchBarProps) => {\n const { entityId } = props;\n const navigate = useNavigate();\n const { results, term, setTerm, deferredLoading } =\n useTechDocsSearch(entityId);\n\n return (\n <SearchAutocomplete\n aria-label=\"Search docs\"\n placeholder=\"Search docs\"\n size=\"small\"\n inputValue={term}\n onInputChange={setTerm}\n isLoading={deferredLoading}\n popoverWidth=\"min(720px, calc(100vw - 32px))\"\n popoverPlacement=\"bottom end\"\n >\n {results.map((result, index) => (\n <SearchAutocompleteItem\n key={index}\n id={String(index)}\n textValue={result.document.title}\n onAction={() => {\n setTerm('');\n navigate(result.document.location);\n requestAnimationFrame(() => {\n (document.activeElement as HTMLElement)?.blur();\n });\n }}\n >\n <Flex direction=\"column\" gap=\"1\">\n <Text weight=\"bold\">\n {result.highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={result.highlight.fields.title}\n preTag={result.highlight.preTag}\n postTag={result.highlight.postTag}\n />\n ) : (\n result.document.title\n )}\n </Text>\n {(result.highlight?.fields.text || result.document.text) && (\n <Text\n variant=\"body-small\"\n color=\"secondary\"\n style={{\n display: '-webkit-box',\n WebkitLineClamp: 3,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {result.highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={result.highlight.fields.text}\n preTag={result.highlight.preTag}\n postTag={result.highlight.postTag}\n />\n ) : (\n result.document.text\n )}\n </Text>\n )}\n </Flex>\n </SearchAutocompleteItem>\n ))}\n </SearchAutocomplete>\n );\n};\n\nexport type TechDocsReaderSearchProps = {\n entityId: CompoundEntityRef;\n};\n\nexport const TechDocsReaderSearch = (props: TechDocsReaderSearchProps) => {\n const initialState = {\n term: '',\n types: ['techdocs'],\n pageCursor: '',\n filters: props.entityId,\n };\n return (\n <SearchContextProvider initialState={initialState}>\n <TechDocsReaderSearchBar {...props} />\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2026 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 Helmet from 'react-helmet';\nimport { Header, ButtonLink } from '@backstage/ui';\nimport { RiCodeLine } from '@remixicon/react';\nimport { TechDocsAddonLocations as locations } from '@backstage/plugin-techdocs-react';\nimport { TechDocsReaderSearch } from './TechDocsReaderSearch';\nimport { useTechDocsReaderHeaderData } from '../../hooks/useTechDocsReaderHeaderData';\n\nexport type TechDocsReaderHeaderProps = {\n withSearch?: boolean;\n};\n\nexport const TechDocsReaderHeader = (props: TechDocsReaderHeaderProps) => {\n const { withSearch = true } = props;\n const {\n title,\n entityRef,\n tabTitle,\n hidden,\n showSourceLink,\n sourceLink,\n addons,\n } = useTechDocsReaderHeaderData();\n\n if (hidden) return null;\n\n return (\n <>\n <Helmet titleTemplate=\"%s\">\n <title>{tabTitle}</title>\n </Helmet>\n <Header\n title={title || ''}\n customActions={\n <>\n {withSearch && <TechDocsReaderSearch entityId={entityRef} />}\n {showSourceLink && (\n <ButtonLink\n href={sourceLink!}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n variant=\"secondary\"\n size=\"small\"\n iconStart={<RiCodeLine />}\n aria-label=\"View source\"\n />\n )}\n {addons.renderComponentsByLocation(locations.Header)}\n </>\n }\n />\n </>\n );\n};\n","// extracted by css-extract-rspack-plugin\nexport default {\"entityCard\":\"yq831xiAsNsOpUlb\",\"cardBody\":\"MY4uvUy71MA7v2tq\",\"definitionList\":\"UkguRkEUDeUYLdbC\",\"definitionGroup\":\"Y8Fg3yghDlEWhHYR\",\"definitionValue\":\"yOMTDnv9l34EOx49\",\"searchWrapper\":\"oTZj1IybGm8aLl23\"};","/*\n * Copyright 2026 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 { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';\nimport {\n EntityRefLink,\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { RELATION_OWNED_BY } from '@backstage/catalog-model';\nimport { Card, CardBody, Text } from '@backstage/ui';\nimport capitalize from 'lodash/capitalize';\nimport styles from './TechDocsReaderEntityCard.module.css';\nimport { TechDocsReaderSearch } from './TechDocsReaderSearch';\n\nexport type TechDocsReaderEntityCardProps = {\n withSearch?: boolean;\n};\n\nexport const TechDocsReaderEntityCard = (\n props: TechDocsReaderEntityCardProps,\n) => {\n const { withSearch } = props;\n const {\n entityRef,\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n if (entityMetadataLoading || !entityMetadata) return null;\n\n const { spec } = entityMetadata;\n const lifecycle = spec?.lifecycle;\n const ownedByRelations = getEntityRelations(\n entityMetadata,\n RELATION_OWNED_BY,\n );\n\n return (\n <Card className={styles.entityCard}>\n <CardBody className={styles.cardBody}>\n <dl className={styles.definitionList}>\n <div className={styles.definitionGroup}>\n <dt>\n <Text variant=\"body-small\" weight=\"bold\">\n {capitalize(entityMetadata.kind)}:\n </Text>\n </dt>\n <dd className={styles.definitionValue}>\n <EntityRefLink entityRef={entityRef} defaultKind=\"Component\" />\n </dd>\n </div>\n {ownedByRelations.length > 0 && (\n <div className={styles.definitionGroup}>\n <dt>\n <Text variant=\"body-small\" weight=\"bold\">\n Owner:\n </Text>\n </dt>\n <dd className={styles.definitionValue}>\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n </dd>\n </div>\n )}\n {lifecycle && (\n <div className={styles.definitionGroup}>\n <dt>\n <Text variant=\"body-small\" weight=\"bold\">\n Lifecycle:\n </Text>\n </dt>\n <dd className={styles.definitionValue}>\n <Text variant=\"body-small\">{String(lifecycle)}</Text>\n </dd>\n </div>\n )}\n </dl>\n {withSearch && (\n <div className={styles.searchWrapper}>\n <TechDocsReaderSearch entityId={entityRef} />\n </div>\n )}\n </CardBody>\n </Card>\n );\n};\n","/*\n * Copyright 2026 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 { TechDocsShadowDom } from '@backstage/plugin-techdocs-react';\nimport { Progress } from '@backstage/core-components';\n\nimport { TechDocsStateIndicator } from '../../reader/components/TechDocsStateIndicator';\nimport { withTechDocsReaderProvider } from '../../reader/components/TechDocsReaderProvider';\nimport { TechDocsReaderPageContentAddons } from '../../reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons';\nimport type { TechDocsReaderPageContentProps } from '../../reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent';\nimport { useTechDocsReaderContentData } from '../../hooks/useTechDocsReaderContentData';\n\nexport const TechDocsReaderContent = withTechDocsReaderProvider(\n (props: TechDocsReaderPageContentProps) => {\n const {\n dom,\n handleAppend,\n isNotFound,\n isDomReady,\n showProgress,\n NotFoundErrorPage,\n } = useTechDocsReaderContentData({\n defaultPath: props.defaultPath,\n onReady: props.onReady,\n });\n\n if (isNotFound) return <NotFoundErrorPage />;\n\n if (!isDomReady) {\n return <TechDocsStateIndicator />;\n }\n\n return (\n <>\n <TechDocsStateIndicator />\n {showProgress && <Progress />}\n <TechDocsShadowDom element={dom!} onAppend={handleAppend}>\n <TechDocsReaderPageContentAddons />\n </TechDocsShadowDom>\n </>\n );\n },\n);\n","/*\n * Copyright 2026 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 { Container } from '@backstage/ui';\nimport { TechDocsReaderHeader } from './TechDocsReaderHeader';\nimport { TechDocsReaderEntityCard } from './TechDocsReaderEntityCard';\nimport { TechDocsReaderPageSubheader } from '../../reader/components/TechDocsReaderPageSubheader';\nimport { TechDocsReaderContent } from './TechDocsReaderContent';\n\nexport type TechDocsReaderLayoutProps = {\n withHeader?: boolean;\n withSearch?: boolean;\n};\n\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <>\n {withHeader && <TechDocsReaderHeader withSearch={withSearch} />}\n <Container mt=\"6\">\n <TechDocsReaderEntityCard withSearch={!withHeader && withSearch} />\n <TechDocsReaderPageSubheader />\n <TechDocsReaderContent />\n </Container>\n </>\n );\n};\n","/*\n * Copyright 2026 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 { ReactElement, Suspense } from 'react';\nimport {\n TechDocsAddons,\n type TechDocsAddonOptions,\n} from '@backstage/plugin-techdocs-react';\nimport { attachTechDocsAddonComponentData } from '@backstage/plugin-techdocs-react/alpha';\nimport { EmbeddedDocsRouter, TechDocsReaderRouter } from '../../Router';\nimport { TechDocsReaderLayout } from './TechDocsReaderLayout';\n\nfunction Addons(props: { options: TechDocsAddonOptions[] }) {\n return (\n <TechDocsAddons>\n {props.options.map(options => {\n const Addon = options.component;\n attachTechDocsAddonComponentData(Addon, options);\n return (\n <Suspense key={options.name} fallback={null}>\n <Addon />\n </Suspense>\n );\n })}\n </TechDocsAddons>\n );\n}\n\nexport function TechDocsReaderPage(props: {\n addonOptions: TechDocsAddonOptions[];\n withSearch: boolean;\n withHeader: boolean;\n}) {\n return (\n <TechDocsReaderRouter>\n <TechDocsReaderLayout\n withSearch={props.withSearch}\n withHeader={props.withHeader}\n />\n <Addons options={props.addonOptions} />\n </TechDocsReaderRouter>\n );\n}\n\nexport function TechDocsEntityContent(props: {\n addonOptions: TechDocsAddonOptions[];\n emptyState?: ReactElement;\n}) {\n return (\n <EmbeddedDocsRouter emptyState={props.emptyState}>\n <Addons options={props.addonOptions} />\n </EmbeddedDocsRouter>\n );\n}\n","/*\n * Copyright 2021 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 { Config } from '@backstage/config';\n\n// Lower-case entity triplets by default, but allow override.\nexport function toLowerMaybe(str: string, config: Config) {\n return config.getOptionalBoolean(\n 'techdocs.legacyUseCaseSensitiveTripletPaths',\n )\n ? str\n : str.toLocaleLowerCase('en-US');\n}\n","/*\n * Copyright 2021 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 useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\n\nimport {\n configApiRef,\n useApi,\n useApiHolder,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { Entity } from '@backstage/catalog-model';\nimport { rootDocsRouteRef } from '../../../routes';\nimport { entityPresentationApiRef } from '@backstage/plugin-catalog-react';\nimport {\n EmptyState,\n LinkButton,\n Table,\n TableColumn,\n TableOptions,\n TableProps,\n} from '@backstage/core-components';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { actionFactories } from './actions';\nimport { columnFactories } from './columns';\nimport {\n DocsTableRow,\n DocsTableColumnFactories,\n DocsTableActionFactories,\n} from './types';\nimport { entitiesToDocsMapper } from './helpers';\n\n/**\n * Props for {@link DocsTable}.\n *\n * @public\n */\nexport type DocsTableProps = {\n entities: Entity[] | undefined;\n title?: string | undefined;\n loading?: boolean | undefined;\n columns?: TableColumn<DocsTableRow>[];\n actions?: TableProps<DocsTableRow>['actions'];\n options?: TableOptions<DocsTableRow>;\n};\n\n/**\n * Component which renders a table documents\n *\n * @public\n */\nconst DocsTableComponent = (props: DocsTableProps): JSX.Element | null => {\n const { entities, title, loading, columns, actions, options } = props;\n const [, copyToClipboard] = useCopyToClipboard();\n const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);\n const config = useApi(configApiRef);\n const apiHolder = useApiHolder();\n\n const { t } = useTranslationRef(techdocsTranslationRef);\n if (!entities) return null;\n\n const documents = entitiesToDocsMapper(\n entities,\n getRouteToReaderPageFor,\n config,\n apiHolder.get(entityPresentationApiRef),\n );\n\n const tableColumns = columns || [\n columnFactories.createTitleColumn({\n hidden: true,\n entityPresentationApi: apiHolder.get(entityPresentationApiRef),\n }),\n columnFactories.createNameColumn({\n entityPresentationApi: apiHolder.get(entityPresentationApiRef),\n }),\n columnFactories.createOwnerColumn(),\n columnFactories.createKindColumn(),\n columnFactories.createTypeColumn(),\n ];\n\n const defaultActions: TableProps<DocsTableRow>['actions'] = [\n actionFactories.createCopyDocsUrlAction(copyToClipboard, t),\n ];\n\n const pageSize = 20;\n const paging = documents && documents.length > pageSize;\n\n return (\n <>\n {loading || (documents && documents.length > 0) ? (\n <Table<DocsTableRow>\n isLoading={loading}\n options={{\n paging,\n pageSize,\n search: true,\n actionsColumnIndex: -1,\n ...options,\n }}\n data={documents}\n columns={tableColumns}\n actions={actions || defaultActions}\n title={\n title\n ? `${title} (${documents.length})`\n : `${t('table.title.all')} (${documents.length})`\n }\n localization={{\n header: {\n actions: t('table.header.actions'),\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.searchPlaceholder'),\n },\n pagination: {\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n },\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n },\n }}\n />\n ) : (\n <EmptyState\n missing=\"data\"\n title={t('table.emptyState.title')}\n description={t('table.emptyState.description')}\n action={\n <LinkButton\n color=\"primary\"\n to=\"https://backstage.io/docs/features/techdocs/getting-started\"\n variant=\"contained\"\n >\n {t('table.emptyState.docsButton')}\n </LinkButton>\n }\n />\n )}\n </>\n );\n};\n\n/**\n * @public\n */\nexport const DocsTable = DocsTableComponent as {\n (props: DocsTableProps): JSX.Element | null;\n columns: DocsTableColumnFactories;\n actions: DocsTableActionFactories;\n};\n\nDocsTable.columns = columnFactories;\nDocsTable.actions = actionFactories;\n","/*\n * Copyright 2024 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 { useState, useEffect } from 'react';\n\nimport { Table, TableProps } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { DocsTableRow } from './types';\nimport {\n EntityTextFilter,\n useEntityList,\n} from '@backstage/plugin-catalog-react';\n\n/**\n * @internal\n */\nexport function OffsetPaginatedDocsTable(props: TableProps<DocsTableRow>) {\n const { actions, columns, data, isLoading, options, title } = props;\n const { updateFilters, setLimit, setOffset, limit, totalItems, offset } =\n useEntityList();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const [page, setPage] = useState(\n offset && limit ? Math.floor(offset / limit) : 0,\n );\n\n useEffect(() => {\n if (totalItems && page * limit >= totalItems) {\n setOffset!(Math.max(0, totalItems - limit));\n } else {\n setOffset!(Math.max(0, page * limit));\n }\n }, [setOffset, page, limit, totalItems]);\n\n return (\n <Table<DocsTableRow>\n title={title}\n columns={columns}\n data={data}\n options={{\n paginationPosition: 'both',\n pageSizeOptions: [5, 10, 20, 50, 100],\n pageSize: limit,\n emptyRowsWhenPaging: false,\n actionsColumnIndex: -1,\n ...options,\n }}\n actions={actions}\n onSearchChange={(searchText: string) =>\n updateFilters({\n text: searchText ? new EntityTextFilter(searchText) : undefined,\n })\n }\n page={page}\n onPageChange={newPage => {\n setPage(newPage);\n }}\n onRowsPerPageChange={pageSize => {\n setLimit(pageSize);\n }}\n totalCount={totalItems}\n localization={{\n header: {\n actions: t('table.header.actions'),\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.searchPlaceholder'),\n },\n pagination: {\n labelDisplayedRows: '',\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n },\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n },\n }}\n isLoading={isLoading}\n />\n );\n}\n","/*\n * Copyright 2024 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, TableProps } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { DocsTableRow } from './types';\n\ntype PaginatedDocsTableProps = {\n prev?(): void;\n next?(): void;\n} & TableProps<DocsTableRow>;\n\n/**\n * @internal\n */\n\nexport function CursorPaginatedDocsTable(props: PaginatedDocsTableProps) {\n const {\n actions,\n columns,\n data,\n next,\n prev,\n title,\n isLoading,\n options,\n ...restProps\n } = props;\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n return (\n <Table\n title={isLoading ? '' : title}\n columns={columns}\n data={data}\n options={{\n paginationPosition: 'both',\n ...options,\n // These settings are configured to force server side pagination\n pageSizeOptions: [],\n showFirstLastPageButtons: false,\n pageSize: Number.MAX_SAFE_INTEGER,\n emptyRowsWhenPaging: false,\n actionsColumnIndex: -1,\n }}\n onPageChange={page => {\n if (page > 0) {\n next?.();\n } else {\n prev?.();\n }\n }}\n /* this will enable the prev button accordingly */\n page={prev ? 1 : 0}\n /* this will enable the next button accordingly */\n totalCount={next ? Number.MAX_VALUE : Number.MAX_SAFE_INTEGER}\n localization={{\n header: {\n actions: t('table.header.actions'),\n },\n toolbar: {\n searchPlaceholder: t('table.toolbar.searchPlaceholder'),\n },\n pagination: {\n labelDisplayedRows: '',\n labelRowsSelect: t('table.pagination.labelRowsSelect'),\n },\n body: {\n emptyDataSourceMessage: t('table.body.emptyDataSourceMessage'),\n },\n }}\n isLoading={isLoading}\n {...restProps}\n />\n );\n}\n","/*\n * Copyright 2021 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 useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\nimport { capitalize } from 'lodash';\nimport {\n CodeSnippet,\n TableColumn,\n TableOptions,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n configApiRef,\n useApi,\n useApiHolder,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n useEntityList,\n useStarredEntities,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { DocsTable } from './DocsTable';\nimport { OffsetPaginatedDocsTable } from './OffsetPaginatedDocsTable';\nimport { CursorPaginatedDocsTable } from './CursorPaginatedDocsTable';\nimport { actionFactories } from './actions';\nimport { columnFactories } from './columns';\nimport {\n DocsTableRow,\n DocsTableColumnFactories,\n DocsTableActionFactories,\n} from './types';\nimport { rootDocsRouteRef } from '../../../routes';\nimport { entitiesToDocsMapper } from './helpers';\n\n/**\n * Props for {@link EntityListDocsTable}.\n *\n * @public\n */\nexport type EntityListDocsTableProps = {\n columns?: TableColumn<DocsTableRow>[];\n actions?: TableProps<DocsTableRow>['actions'];\n options?: TableOptions<DocsTableRow>;\n};\n\n/**\n * Component which renders a table with entities from catalog.\n *\n * @public\n */\nconst EntityListDocsTableComponent = (\n props: EntityListDocsTableProps,\n): JSX.Element | null => {\n const { columns, actions, options } = props;\n const { loading, error, entities, filters, paginationMode, pageInfo } =\n useEntityList();\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const [, copyToClipboard] = useCopyToClipboard();\n const getRouteToReaderPageFor = useRouteRef(rootDocsRouteRef);\n const config = useApi(configApiRef);\n const apiHolder = useApiHolder();\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n const title = capitalize(filters.user?.value ?? 'all');\n\n const defaultActions = [\n actionFactories.createCopyDocsUrlAction(copyToClipboard, t),\n actionFactories.createStarEntityAction(\n isStarredEntity,\n toggleStarredEntity,\n t,\n ),\n ];\n\n const documents = entitiesToDocsMapper(\n entities,\n getRouteToReaderPageFor,\n config,\n apiHolder.get(entityPresentationApiRef),\n );\n\n const tableColumns = columns || [\n columnFactories.createTitleColumn({\n hidden: true,\n entityPresentationApi: apiHolder.get(entityPresentationApiRef),\n }),\n columnFactories.createNameColumn({\n entityPresentationApi: apiHolder.get(entityPresentationApiRef),\n }),\n columnFactories.createOwnerColumn(),\n columnFactories.createKindColumn(),\n columnFactories.createTypeColumn(),\n ];\n\n if (paginationMode === 'cursor') {\n return (\n <CursorPaginatedDocsTable\n columns={tableColumns}\n isLoading={loading}\n title={title}\n actions={actions || defaultActions}\n options={options}\n data={documents}\n next={pageInfo?.next}\n prev={pageInfo?.prev}\n />\n );\n } else if (paginationMode === 'offset') {\n return (\n <OffsetPaginatedDocsTable\n columns={tableColumns}\n isLoading={loading}\n title={title}\n actions={actions || defaultActions}\n options={options}\n data={documents}\n />\n );\n }\n\n if (error) {\n return (\n <WarningPanel severity=\"error\" title={t('error.couldNotLoad')}>\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n );\n }\n\n return (\n <DocsTable\n title={title}\n entities={entities}\n loading={loading}\n actions={actions || defaultActions}\n columns={tableColumns}\n options={options}\n />\n );\n};\n\n/**\n * @public\n */\nexport const EntityListDocsTable = EntityListDocsTableComponent as {\n (props: EntityListDocsTableProps): JSX.Element | null;\n columns: DocsTableColumnFactories;\n actions: DocsTableActionFactories;\n};\n\nEntityListDocsTable.columns = columnFactories;\nEntityListDocsTable.actions = actionFactories;\n","/*\n * Copyright 2021 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 ShareIcon from '@material-ui/icons/Share';\nimport { DocsTableRow } from './types';\nimport { FavoriteToggleIcon } from '@backstage/core-components';\nimport type { TranslationFunction } from '@backstage/core-plugin-api/alpha';\nimport type { techdocsTranslationRef } from '../../../translation';\n\ntype InternalTranslationFunctionType = TranslationFunction<\n typeof techdocsTranslationRef extends { T: infer T } ? T : never\n>;\n\n/**\n * Not directly exported, but through DocsTable.actions and EntityListDocsTable.actions\n *\n * @public\n */\nexport const actionFactories = {\n createCopyDocsUrlAction(\n copyToClipboard: Function,\n t?: InternalTranslationFunctionType,\n ) {\n return (row: DocsTableRow) => {\n return {\n icon: () => <ShareIcon fontSize=\"small\" />,\n tooltip:\n t?.('table.actions.copyDocsUrl', {}) ??\n 'Click to copy documentation link to clipboard',\n onClick: () =>\n copyToClipboard(`${window.location.origin}${row.resolved.docsUrl}`),\n };\n };\n },\n createStarEntityAction(\n isStarredEntity: Function,\n toggleStarredEntity: Function,\n t?: InternalTranslationFunctionType,\n ) {\n return (row: DocsTableRow) => {\n const entity = row.entity;\n const isStarred = isStarredEntity(entity);\n const tooltip = isStarred\n ? t?.('table.actions.removeFromFavorites', {}) ??\n 'Remove from favorites'\n : t?.('table.actions.addToFavorites', {}) ?? 'Add to favorites';\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => <FavoriteToggleIcon isFavorite={isStarred} />,\n tooltip,\n onClick: () => toggleStarredEntity(entity),\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 Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode } from 'react';\n\nexport type SubvalueCellClassKey = 'value' | 'subvalue';\n\nconst useSubvalueCellStyles = makeStyles(\n theme => ({\n value: {\n marginBottom: theme.spacing(0.75),\n },\n subvalue: {\n color: theme.palette.textSubtle,\n fontWeight: 'normal',\n },\n }),\n { name: 'BackstageSubvalueCell' },\n);\n\ntype SubvalueCellProps = {\n value: ReactNode;\n subvalue: ReactNode;\n};\n\nexport function SubvalueCell(props: SubvalueCellProps) {\n const { value, subvalue } = props;\n const classes = useSubvalueCellStyles();\n\n return (\n <>\n <Box className={classes.value}>{value}</Box>\n <Box className={classes.subvalue}>{subvalue}</Box>\n </>\n );\n}\n","/*\n * Copyright 2021 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 Link,\n SubvalueCell,\n type TableColumn,\n} from '@backstage/core-components';\nimport {\n EntityDisplayName,\n type EntityPresentationApi,\n entityPresentationSnapshot,\n EntityRefLinks,\n} from '@backstage/plugin-catalog-react';\nimport { Entity } from '@backstage/catalog-model';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { DocsTableRow } from './types';\n\nfunction customTitle(\n entity: Entity,\n presentationApi?: EntityPresentationApi,\n): string {\n return entityPresentationSnapshot(entity, undefined, presentationApi)\n .primaryTitle;\n}\n\n/**\n * Component for translating table column titles\n * @alpha\n */\nconst TableColumnTitle = ({\n translationKey,\n}: {\n translationKey: 'document' | 'owner' | 'kind' | 'type';\n}) => {\n const { t } = useTranslationRef(techdocsTranslationRef);\n return <>{t(`table.columns.${translationKey}`)}</>;\n};\n\n/**\n * Not directly exported, but through DocsTable.columns and EntityListDocsTable.columns\n *\n * @public\n */\nexport const columnFactories = {\n createTitleColumn(options?: {\n hidden?: boolean;\n entityPresentationApi?: EntityPresentationApi;\n }): TableColumn<DocsTableRow> {\n const nameCol = columnFactories.createNameColumn({\n entityPresentationApi: options?.entityPresentationApi,\n });\n return {\n ...nameCol,\n field: 'entity.metadata.title',\n hidden: options?.hidden,\n };\n },\n\n createNameColumn(options?: {\n entityPresentationApi?: EntityPresentationApi;\n }): TableColumn<DocsTableRow> {\n const presentationApi = options?.entityPresentationApi;\n return {\n title: <TableColumnTitle translationKey=\"document\" />,\n field: 'entity.metadata.name',\n highlight: true,\n searchable: true,\n defaultSort: 'asc',\n customSort: (row1, row2) => {\n const title1 = customTitle(\n row1.entity,\n presentationApi,\n ).toLocaleLowerCase();\n const title2 = customTitle(\n row2.entity,\n presentationApi,\n ).toLocaleLowerCase();\n return title1.localeCompare(title2);\n },\n customFilterAndSearch: (filter, row) =>\n customTitle(row.entity, presentationApi)\n .toLocaleLowerCase()\n .includes(filter.toLocaleLowerCase()),\n render: (row: DocsTableRow) => (\n <SubvalueCell\n value={\n <Link to={row.resolved.docsUrl}>\n {presentationApi ? (\n <EntityDisplayName entityRef={row.entity} />\n ) : (\n customTitle(row.entity)\n )}\n </Link>\n }\n subvalue={row.entity.metadata.description}\n />\n ),\n };\n },\n createOwnerColumn(): TableColumn<DocsTableRow> {\n return {\n title: <TableColumnTitle translationKey=\"owner\" />,\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n },\n createKindColumn(): TableColumn<DocsTableRow> {\n return {\n title: <TableColumnTitle translationKey=\"kind\" />,\n field: 'entity.kind',\n };\n },\n createTypeColumn(): TableColumn<DocsTableRow> {\n return {\n title: <TableColumnTitle translationKey=\"type\" />,\n field: 'entity.spec.type',\n };\n },\n};\n\nexport const defaultColumns: TableColumn<DocsTableRow>[] = [\n columnFactories.createTitleColumn({ hidden: true }),\n columnFactories.createNameColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createKindColumn(),\n columnFactories.createTypeColumn(),\n];\n","/*\n * Copyright 2024 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 { RELATION_OWNED_BY, Entity } from '@backstage/catalog-model';\nimport {\n entityPresentationSnapshot,\n getEntityRelations,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport { toLowerMaybe } from '../../../helpers';\nimport { ConfigApi, RouteFunc } from '@backstage/core-plugin-api';\n\ntype getRouteFunc = RouteFunc<{\n namespace: string;\n kind: string;\n name: string;\n}>;\n\nexport function entitiesToDocsMapper(\n entities: Entity[],\n getRouteToReaderPageFor: getRouteFunc,\n config: ConfigApi,\n entityPresentationApi?: EntityPresentationApi,\n) {\n return entities.map(entity => {\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n return {\n entity,\n resolved: {\n docsUrl: getRouteToReaderPageFor({\n namespace: toLowerMaybe(\n entity.metadata.namespace ?? 'default',\n config,\n ),\n kind: toLowerMaybe(entity.kind, config),\n name: toLowerMaybe(entity.metadata.name, config),\n }),\n ownedByRelations,\n ownedByRelationsTitle: ownedByRelations\n .map(\n r =>\n entityPresentationSnapshot(\n r,\n { defaultKind: 'group' },\n entityPresentationApi,\n ).primaryTitle,\n )\n .join(', '),\n },\n };\n });\n}\n","/*\n * Copyright 2021 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 { ReactNode, FC } from 'react';\nimport {\n Content,\n ContentHeader,\n SupportButton,\n} from '@backstage/core-components';\nimport {\n CatalogFilterLayout,\n EntityListProvider,\n EntityOwnerPicker,\n EntityTagPicker,\n UserListPicker,\n} from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\nimport { TechDocsPageWrapper } from './TechDocsPageWrapper';\nimport { TechDocsPicker } from './TechDocsPicker';\nimport { EntityListDocsTable } from './Tables';\nimport { TechDocsIndexPageProps } from './TechDocsIndexPage';\n\n/**\n * Props for {@link DefaultTechDocsHome}\n *\n * @public\n * @deprecated Please use `TechDocsIndexPageProps` instead.\n */\nexport type DefaultTechDocsHomeProps = TechDocsIndexPageProps;\n\n/**\n * Component which renders a default documentation landing page.\n *\n * @public\n */\nexport const DefaultTechDocsHome = (props: TechDocsIndexPageProps) => {\n const {\n initialFilter = 'owned',\n columns,\n actions,\n ownerPickerMode,\n pagination,\n options,\n PageWrapper,\n CustomHeader,\n } = props;\n const { t } = useTranslationRef(techdocsTranslationRef);\n const Wrapper: FC<{\n children: ReactNode;\n }> = PageWrapper ? PageWrapper : TechDocsPageWrapper;\n const Header: FC =\n CustomHeader ||\n (() => (\n <ContentHeader title=\"\">\n <SupportButton>{t('home.supportButton')}</SupportButton>\n </ContentHeader>\n ));\n return (\n <Wrapper>\n <Content>\n <Header />\n <EntityListProvider pagination={pagination}>\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>\n <TechDocsPicker />\n <UserListPicker initialFilter={initialFilter} />\n <EntityOwnerPicker mode={ownerPickerMode} />\n <EntityTagPicker />\n </CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>\n <EntityListDocsTable\n actions={actions}\n columns={columns}\n options={options}\n />\n </CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </EntityListProvider>\n </Content>\n </Wrapper>\n );\n};\n","/*\n * Copyright 2021 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 { FC } from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport {\n TableColumn,\n TableProps,\n TableOptions,\n} from '@backstage/core-components';\nimport {\n EntityListPagination,\n EntityOwnerPickerProps,\n UserListFilterKind,\n} from '@backstage/plugin-catalog-react';\nimport { DefaultTechDocsHome } from './DefaultTechDocsHome';\nimport { DocsTableRow } from './Tables';\n\n/**\n * Props for {@link TechDocsIndexPage}\n *\n * @public\n */\nexport type TechDocsIndexPageProps = {\n initialFilter?: UserListFilterKind;\n columns?: TableColumn<DocsTableRow>[];\n actions?: TableProps<DocsTableRow>['actions'];\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n pagination?: EntityListPagination;\n options?: TableOptions<DocsTableRow>;\n PageWrapper?: FC;\n CustomHeader?: FC;\n};\n\nexport const TechDocsIndexPage = (props: TechDocsIndexPageProps) => {\n const outlet = useOutlet();\n\n return outlet || <DefaultTechDocsHome {...props} />;\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 { PropsWithChildren, ComponentProps } from 'react';\n\nimport { Header } from '../Header';\nimport { Page } from './Page';\n\ntype PageWithHeaderProps = ComponentProps<typeof Header> & {\n themeId: string;\n};\n\nexport function PageWithHeader(props: PropsWithChildren<PageWithHeaderProps>) {\n const { themeId, children, ...restProps } = props;\n return (\n <Page themeId={themeId}>\n <Header {...restProps} />\n {children}\n </Page>\n );\n}\n","/*\n * Copyright 2021 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 { ReactNode, FC } from 'react';\n\nimport { PageWithHeader } from '@backstage/core-components';\nimport { useApi, configApiRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\n\n/**\n * Props for {@link TechDocsPageWrapper}\n *\n * @public\n */\nexport type TechDocsPageWrapperProps = {\n children?: ReactNode;\n CustomPageWrapper?: FC<{ children?: ReactNode }>;\n};\n\n/**\n * Component wrapping a TechDocs page with Page and Header components\n *\n * @public\n */\nexport const TechDocsPageWrapper = (props: TechDocsPageWrapperProps) => {\n const { children, CustomPageWrapper } = props;\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(techdocsTranslationRef);\n const orgName =\n configApi.getOptionalString('organization.name') ?? 'Backstage';\n const generatedSubtitle = t('pageWrapper.subtitle', { orgName });\n\n return (\n <>\n {CustomPageWrapper ? (\n <CustomPageWrapper>{children}</CustomPageWrapper>\n ) : (\n <PageWithHeader\n title={t('pageWrapper.title')}\n subtitle={generatedSubtitle}\n themeId=\"documentation\"\n >\n {children}\n </PageWithHeader>\n )}\n </>\n );\n};\n","/*\n * Copyright 2021 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 { useEffect } from 'react';\nimport {\n CATALOG_FILTER_EXISTS,\n DefaultEntityFilters,\n EntityFilter,\n useEntityList,\n} from '@backstage/plugin-catalog-react';\nimport { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';\n\nclass TechDocsFilter implements EntityFilter {\n getCatalogFilters(): Record<string, string | symbol | (string | symbol)[]> {\n return {\n [`metadata.annotations.${TECHDOCS_ANNOTATION}`]: CATALOG_FILTER_EXISTS,\n };\n }\n}\n\ntype CustomFilters = DefaultEntityFilters & {\n techdocs?: TechDocsFilter;\n};\n\n/**\n * Component responsible for updating TechDocs filters\n *\n * @public\n */\nexport const TechDocsPicker = () => {\n const { updateFilters } = useEntityList<CustomFilters>();\n\n useEffect(() => {\n updateFilters({\n techdocs: new TechDocsFilter(),\n });\n }, [updateFilters]);\n\n return null;\n};\n","/*\n * Copyright 2023 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\nlet ReactDOMPromise: Promise<\n typeof import('react-dom') | typeof import('react-dom/client')\n>;\nif (process.env.HAS_REACT_DOM_CLIENT) {\n ReactDOMPromise = import('react-dom/client');\n} else {\n ReactDOMPromise = import('react-dom');\n}\n\n/** @internal */\nexport function renderReactElement(element: JSX.Element, root: HTMLElement) {\n ReactDOMPromise.then(ReactDOM => {\n if ('createRoot' in ReactDOM) {\n ReactDOM.createRoot(root).render(element);\n } else {\n ReactDOM.render(element, root);\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 { isElement } from '../utils';\n\nconst MKDOCS_CSS = /main\\.[A-Fa-f0-9]{8}\\.min\\.css$/;\nconst GOOGLE_FONTS = /^https:\\/\\/fonts\\.googleapis\\.com/;\nconst GSTATIC_FONTS = /^https:\\/\\/fonts\\.gstatic\\.com/;\n\n/**\n * Checks whether a node is link or not.\n * @param node - can be any element.\n * @returns true when node is link.\n */\nconst isLink = (node: Element) => node.nodeName === 'LINK';\n\n/**\n * Checks whether a link is safe or not.\n * @param node - is an link element.\n * @returns true when link is mkdocs css, google fonts or gstatic fonts.\n */\nconst isSafe = (node: Element) => {\n const href = node?.getAttribute('href') || '';\n const isMkdocsCss = href.match(MKDOCS_CSS);\n const isGoogleFonts = href.match(GOOGLE_FONTS);\n const isGstaticFonts = href.match(GSTATIC_FONTS);\n return isMkdocsCss || isGoogleFonts || isGstaticFonts;\n};\n\n/**\n * Function that removes unsafe link nodes.\n * @param node - can be any element.\n */\nexport const removeUnsafeLinks = (node: Node) => {\n if (!isElement(node)) return;\n\n if (isLink(node) && !isSafe(node)) {\n node.remove();\n }\n};\n","/*\n * Copyright 2025 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\nexport const isElement = (node: Node): node is Element => {\n return node.nodeType === Node.ELEMENT_NODE;\n};\n","/*\n * Copyright 2025 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 */\nimport { UponSanitizeElementHook } from 'dompurify';\nimport { isElement } from '../utils';\n\n/**\n * Checks if a meta tag is a refresh redirect tag that should be allowed.\n * These tags are required for the TechDocs redirect feature.\n */\nconst isAllowedMetaRefreshTag = (element: Element): boolean => {\n const httpEquiv = element.getAttribute('http-equiv');\n const content = element.getAttribute('content');\n\n return httpEquiv === 'refresh' && content?.includes('url=') === true;\n};\n\n/**\n * Removes unsafe meta tags from the DOM while preserving allowed refresh redirect tags.\n * Only meta tags used for page refreshing/redirects are allowed as they are required\n * for the TechDocs redirect feature.\n */\nexport const removeUnsafeMetaTags: UponSanitizeElementHook = (node, data) => {\n if (!isElement(node)) return;\n\n if (data.tagName === 'meta' && !isAllowedMetaRefreshTag(node)) {\n node.parentNode?.removeChild(node);\n }\n};\n","/*\n * Copyright 2025 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 */\nimport { UponSanitizeAttributeHook } from 'dompurify';\n\n/**\n * Removes attributes that should only be present on meta tags from other elements.\n * This ensures that http-equiv and content attributes are only allowed on meta tags\n * where they are required for the redirect feature.\n */\nexport const removeRestrictedAttributes: UponSanitizeAttributeHook = (\n node,\n data,\n) => {\n if (node.tagName !== 'META') {\n if (data.attrName === 'http-equiv' || data.attrName === 'content') {\n node.removeAttribute(data.attrName);\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 { RuleOptions } from './types';\n\nconst TECHDOCS_SIDEBAR_WIDTH = '16rem';\nconst APP_SIDEBAR_WIDTH_PINNED = '224px';\nconst APP_SIDEBAR_WIDTH_COLLAPSED = '72px';\n\nexport default ({ theme, sidebar }: RuleOptions) => `\n\n/*================== Layout ==================*/\n\n/* mkdocs material v9 compat */\n.md-nav__title {\n color: var(--md-default-fg-color);\n}\n\n.md-grid {\n max-width: 100%;\n margin: 0;\n}\n\n.md-nav {\n font-size: calc(var(--md-typeset-font-size) * 0.9);\n}\n.md-nav__link:not(:has(svg)) {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.md-nav__link:has(svg) > .md-ellipsis {\n flex-grow: 1;\n}\n.md-nav__icon {\n height: 20px !important;\n width: 20px !important;\n margin-left:${theme.spacing(1)}px;\n}\n.md-nav__icon svg {\n margin: 0;\n width: 20px !important;\n height: 20px !important;\n}\n.md-nav__icon:after {\n width: 20px !important;\n height: 20px !important;\n}\n.md-status--updated::after {\n -webkit-mask-image: var(--md-status--updated);\n mask-image: var(--md-status--updated);\n}\n\n.md-nav__item--active > .md-nav__link, a.md-nav__link--active {\n text-decoration: underline;\n color: var(--md-typeset-a-color);\n}\n.md-nav__link--active > .md-status:after {\n background-color: var(--md-typeset-a-color);\n}\n.md-nav__link[href]:hover > .md-status:after {\n background-color: var(--md-accent-fg-color);\n}\n\n.md-main__inner {\n margin-top: 0;\n}\n\n.md-sidebar {\n bottom: 75px;\n position: fixed;\n width: ${TECHDOCS_SIDEBAR_WIDTH};\n}\n.md-sidebar .md-sidebar__scrollwrap {\n width: calc(${TECHDOCS_SIDEBAR_WIDTH});\n height: 100%\n}\n\n@supports selector(::-webkit-scrollbar) {\n [dir=ltr] .md-sidebar__inner {\n padding-right: calc(100% - 15.1rem);\n }\n}\n.md-sidebar--secondary {\n right: ${theme.spacing(3)}px;\n}\n\n.md-content {\n max-width: calc(100% - ${TECHDOCS_SIDEBAR_WIDTH} * 2);\n margin-left: ${TECHDOCS_SIDEBAR_WIDTH};\n margin-bottom: 50px;\n}\n\n.md-content > .md-sidebar {\n left: ${TECHDOCS_SIDEBAR_WIDTH};\n}\n\n.md-footer {\n position: fixed;\n bottom: 0px;\n pointer-events: none;\n}\n\n.md-footer-nav__link, .md-footer__link {\n pointer-events: all;\n}\n\n.md-footer__title {\n background-color: unset;\n}\n.md-footer-nav__link, .md-footer__link {\n width: ${TECHDOCS_SIDEBAR_WIDTH};\n}\n\n.md-dialog {\n background-color: unset;\n}\n\n@media screen and (min-width: 76.25em) {\n .md-sidebar {\n height: auto;\n /* Less padding before the Previous / Next buttons */\n padding-bottom: 0 !important;\n }\n}\n\n@media screen and (max-width: 76.1875em) {\n .md-nav {\n transition: none !important;\n background-color: var(--md-default-bg-color)\n }\n .md-nav--primary .md-nav__title {\n cursor: auto;\n color: var(--md-default-fg-color);\n font-weight: 700;\n white-space: normal;\n line-height: 1rem;\n height: auto;\n display: flex;\n flex-flow: column;\n row-gap: 1.6rem;\n padding: 1.2rem .8rem .8rem;\n background-color: var(--md-default-bg-color);\n }\n .md-nav--primary .md-nav__title~.md-nav__list {\n box-shadow: none;\n }\n .md-nav--primary .md-nav__title ~ .md-nav__list > :first-child {\n border-top: none;\n }\n .md-nav--primary .md-nav__title .md-nav__button {\n display: none;\n }\n .md-nav--primary .md-nav__title .md-nav__icon {\n color: var(--md-default-fg-color);\n position: static;\n height: auto;\n margin: 0 0 0 -0.2rem;\n }\n .md-nav--primary > .md-nav__title [for=\"none\"] {\n padding-top: 0;\n }\n .md-nav--primary .md-nav__item {\n border-top: none;\n }\n .md-nav--primary :is(.md-nav__title,.md-nav__item) {\n font-size : var(--md-typeset-font-size);\n }\n .md-nav .md-source {\n display: none;\n }\n\n .md-sidebar {\n height: 100%;\n }\n .md-sidebar--primary {\n width: ${TECHDOCS_SIDEBAR_WIDTH} !important;\n z-index: 200;\n left: ${\n sidebar.isPinned\n ? `calc(-${TECHDOCS_SIDEBAR_WIDTH} + var(--techdocs-sidebar-closed-offset-pinned, ${APP_SIDEBAR_WIDTH_PINNED}))`\n : `calc(-${TECHDOCS_SIDEBAR_WIDTH} + var(--techdocs-sidebar-closed-offset-collapsed, ${APP_SIDEBAR_WIDTH_COLLAPSED}))`\n } !important;\n }\n .md-sidebar--secondary:not([hidden]) {\n display: none;\n }\n\n [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary {\n transform: translateX(var(--techdocs-sidebar-open-translate, ${TECHDOCS_SIDEBAR_WIDTH}));\n }\n\n .md-content {\n max-width: 100%;\n margin-left: 0;\n }\n\n .md-header__button {\n margin: 0.4rem 0;\n margin-left: 0.4rem;\n padding: 0;\n }\n\n .md-overlay {\n left: 0;\n }\n\n .md-footer {\n position: static;\n padding-left: 0;\n }\n .md-footer-nav__link {\n /* footer links begin to overlap at small sizes without setting width */\n width: 50%;\n }\n}\n\n@media screen and (max-width: 600px) {\n .md-sidebar--primary {\n left: -${TECHDOCS_SIDEBAR_WIDTH} !important;\n width: ${TECHDOCS_SIDEBAR_WIDTH};\n }\n}\n\n\n@media print {\n .md-sidebar,\n #toggle-sidebar {\n display: none;\n }\n\n .md-content {\n margin: 0;\n width: 100%;\n max-width: 100%;\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 { RuleOptions } from './types';\n\ntype RuleTypography = RuleOptions['theme']['typography'];\n\ntype BackstageTypography = RuleTypography & {\n htmlFontSize?: number;\n};\n\ntype TypographyHeadings = Pick<\n RuleTypography,\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n>;\n\ntype TypographyHeadingsKeys = keyof TypographyHeadings;\n\nconst headings: TypographyHeadingsKeys[] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\nconst relativeLengthUnit: RegExp = /(em)|(rem)/gi;\nconst cssVariable: RegExp = /var\\(|\\)/gi;\n\nexport default ({ theme }: RuleOptions) => `\n/*================== Typeset ==================*/\n\n.md-typeset {\n font-size: var(--md-typeset-font-size);\n}\n\n${headings.reduce<string>((style, heading) => {\n const htmlFontSize =\n (theme.typography as BackstageTypography).htmlFontSize ?? 16;\n const styles = theme.typography[heading];\n const { lineHeight, fontFamily, fontWeight, fontSize } = styles;\n const calculate = (value: typeof fontSize): string | undefined => {\n if (typeof value === 'number') {\n // Convert px to rem and apply 60% factor\n return calculate(`${(value / htmlFontSize) * 0.6}rem`);\n } else if (typeof value === 'string') {\n if (value.match(cssVariable)) {\n // Resolve css variable and calculate recursively\n const resolvedValue = window\n .getComputedStyle(document.body)\n .getPropertyValue(value.replaceAll(cssVariable, ''));\n if (resolvedValue !== '') {\n return calculate(resolvedValue);\n }\n } else if (value.match(relativeLengthUnit)) {\n // Use relative size as factor\n const factor = value.replace(relativeLengthUnit, '');\n return `calc(${factor} * var(--md-typeset-font-size))`;\n }\n }\n // Value is not a number, relative length unit, or CSS variable, return as is\n return value;\n };\n return style.concat(`\n .md-typeset ${heading} {\n color: var(--md-default-fg-color);\n line-height: ${lineHeight};\n font-family: ${fontFamily};\n font-weight: ${fontWeight};\n font-size: ${calculate(fontSize)};\n }\n `);\n}, '')}\n\n.md-typeset .md-content__button {\n color: var(--md-default-fg-color);\n}\n\n.md-typeset hr {\n border-bottom: 0.05rem dotted ${theme.palette.divider};\n}\n\n.md-typeset details {\n font-size: var(--md-typeset-font-size) !important;\n}\n.md-typeset details summary {\n padding-left: 2.5rem !important;\n}\n.md-typeset details summary:before,\n.md-typeset details summary:after {\n top: 50% !important;\n width: 20px !important;\n height: 20px !important;\n transform: rotate(0deg) translateY(-50%) !important;\n}\n.md-typeset details[open] > summary:after {\n transform: rotate(90deg) translateX(-50%) !important;\n}\n\n.md-typeset blockquote {\n color: var(--md-default-fg-color--light);\n border-left: 0.2rem solid var(--md-default-fg-color--light);\n}\n\n.md-typeset table:not([class]) {\n font-size: var(--md-typeset-font-size);\n border: 1px solid var(--md-typeset-table-color);\n border-bottom: none;\n border-collapse: collapse;\n border-radius: ${theme.shape.borderRadius}px;\n}\n.md-typeset table:not([class]) th {\n font-weight: bold;\n}\n.md-typeset table:not([class]) td, .md-typeset table:not([class]) th {\n border-bottom: 1px solid var(--md-typeset-table-color);\n}\n\n.md-typeset pre > code::-webkit-scrollbar-thumb {\n background-color: hsla(0, 0%, 0%, 0.32);\n}\n.md-typeset pre > code::-webkit-scrollbar-thumb:hover {\n background-color: hsla(0, 0%, 0%, 0.87);\n}\n\n.md-typeset code {\n word-break: keep-all;\n}\n`;\n","/*\n * Copyright 2024 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 { RuleOptions } from './types';\nimport { Theme } from '@material-ui/core/styles';\n\nconst themeHashes: Record<Theme['palette']['type'], ReadonlyArray<string>> = {\n dark: ['#only-light', '#gh-light-mode-only'],\n light: ['#only-dark', '#gh-dark-mode-only'],\n};\n\nexport default ({ theme }: RuleOptions) => `\n/*================== Palette ==================*/\n/*\n When color palette toggle is enabled in material theme for Mkdocs, there is a possibility to show conditionally \n images by adding #only-dark or #only-light to resource hash. Backstage doesn't use mkdocs color palette mechanism,\n so there is a need to add css rules from palette*.css manually.\n*/\n\n${themeHashes[theme.palette.type]\n .map(hash => `img[src$=\"${hash}\"]`)\n .join(', ')} {\n display: none;\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 { default as variables } from './variables';\nimport { default as reset } from './reset';\nimport { default as layout } from './layout';\nimport { default as typeset } from './typeset';\nimport { default as animations } from './animations';\nimport { default as extensions } from './extensions';\nimport palette from './palette';\n\n/**\n * A list of style rules that will be applied to an element in the order they were added.\n *\n * @remarks\n * The order of items is important, which means that a rule can override any other rule previously added to the list,\n * i.e. the rules will be applied from the first added to the last added.\n */\nexport const rules = [\n variables,\n reset,\n layout,\n typeset,\n animations,\n extensions,\n palette,\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 { alpha, lighten } from '@material-ui/core/styles';\nimport { RuleOptions } from './types';\n\nexport default ({ theme }: RuleOptions) => `\n/*================== Variables ==================*/\n/*\n As the MkDocs output is rendered in shadow DOM, the CSS variable definitions on the root selector are not applied. Instead, they have to be applied on :host.\n As there is no way to transform the served main*.css yet (for example in the backend), we have to copy from main*.css and modify them.\n*/\n\n:host {\n /* FONT */\n --md-default-fg-color: ${theme.palette.text.primary};\n --md-default-fg-color--light: ${theme.palette.text.secondary};\n --md-default-fg-color--lighter: ${alpha(theme.palette.text.secondary, 0.3)};\n --md-default-fg-color--lightest: ${alpha(theme.palette.text.secondary, 0.15)};\n\n /* BACKGROUND */\n --md-default-bg-color:${theme.palette.background.default};\n --md-default-bg-color--light: ${theme.palette.background.paper};\n --md-default-bg-color--lighter: ${lighten(\n theme.palette.background.paper,\n 0.7,\n )};\n --md-default-bg-color--lightest: ${lighten(\n theme.palette.background.paper,\n 0.3,\n )};\n\n /* PRIMARY */\n --md-primary-fg-color: ${theme.palette.primary.main};\n --md-primary-fg-color--light: ${theme.palette.primary.light};\n --md-primary-fg-color--dark: ${theme.palette.primary.dark};\n --md-primary-bg-color: ${theme.palette.primary.contrastText};\n --md-primary-bg-color--light: ${lighten(\n theme.palette.primary.contrastText,\n 0.7,\n )};\n\n /* ACCENT */\n --md-accent-fg-color: var(--md-primary-fg-color);\n --md-accent-fg-color--transparent: ${alpha(theme.palette.primary.main, 0.1)};\n --md-accent-bg-color: var(--md-primary-bg-color);\n --md-accent-bg-color--light: var(--md-primary-bg-color--light);\n\n /* SHADOW */\n --md-shadow-z1: ${theme.shadows[1]};\n --md-shadow-z2: ${theme.shadows[2]};\n --md-shadow-z3: ${theme.shadows[3]};\n\n /* EXTENSIONS */\n --md-admonition-fg-color: var(--md-default-fg-color);\n --md-admonition-bg-color: var(--md-default-bg-color);\n /* Admonitions and others are using SVG masks to define icons. These masks are defined as CSS variables. */\n --md-admonition-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z\"/></svg>');\n --md-admonition-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z\"/></svg>');\n --md-admonition-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z\"/></svg>');\n --md-admonition-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z\"/></svg>');\n --md-admonition-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>');\n --md-admonition-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z\"/></svg>');\n --md-admonition-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z\"/></svg>');\n --md-admonition-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z\"/></svg>');\n --md-admonition-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z\"/></svg>');\n --md-admonition-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z\"/></svg>');\n --md-admonition-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z\"/></svg>');\n --md-admonition-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z\"/></svg>');\n --md-footnotes-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.42L5.83 13H21V7h-2z\"/></svg>');\n --md-details-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z\"/></svg>');\n --md-tasklist-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z\"/></svg>');\n --md-tasklist-icon--checked: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>');\n --md-nav-icon--prev: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z\"/></svg>');\n --md-nav-icon--next: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42z\"/></svg>');\n --md-toc-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 9h14V7H3v2m0 4h14v-2H3v2m0 4h14v-2H3v2m16 0h2v-2h-2v2m0-10v2h2V7h-2m0 6h2v-2h-2v2z\"/></svg>');\n --md-clipboard-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1z\"/></svg>');\n --md-search-result-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16 1.39.43 2 .82V8l-6-6m6.31 16.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22 1.4-1.34 2.11-.69 4.89 1.4 6.22 1.46.93 3.32.93 4.79.02L22 23.39 23.39 22l-3.08-3.1m-3.81.1a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5z\"/></svg>');\n --md-source-forks-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z\"/></svg>');\n --md-source-repositories-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 1 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 0 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 0 1 1-1h8zM5 12.25v3.25a.25.25 0 0 0 .4.2l1.45-1.087a.25.25 0 0 1 .3 0L8.6 15.7a.25.25 0 0 0 .4-.2v-3.25a.25.25 0 0 0-.25-.25h-3.5a.25.25 0 0 0-.25.25z\"/></svg>');\n --md-source-stars-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694v.001z\"/></svg>');\n --md-source-version-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M2.5 7.775V2.75a.25.25 0 0 1 .25-.25h5.025a.25.25 0 0 1 .177.073l6.25 6.25a.25.25 0 0 1 0 .354l-5.025 5.025a.25.25 0 0 1-.354 0l-6.25-6.25a.25.25 0 0 1-.073-.177zm-1.5 0V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.75 1.75 0 0 1 1 7.775zM6 5a1 1 0 1 0 0 2 1 1 0 0 0 0-2z\"/></svg>');\n --md-version-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\"><!--! Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d=\"m310.6 246.6-127.1 128c-7.1 6.3-15.3 9.4-23.5 9.4s-16.38-3.125-22.63-9.375l-127.1-128C.224 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75s3.12 25.75-6.08 34.85z\"/></svg>');\n \n --md-status--updated: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><title>cellphone-arrow-down</title><path d=\"M17,1H7A2,2 0 0,0 5,3V21A2,2 0 0,0 7,23H17A2,2 0 0,0 19,21V3A2,2 0 0,0 17,1M17,19H7V5H17V19M16,13H13V8H11V13H8L12,17L16,13Z\" /></svg>');\n --md-status: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M11 9h2V7h-2m1 13c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m-1 15h2v-6h-2v6Z\"/></svg>');\n --md-status--new: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m23 12-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12m-10 5h-2v-2h2v2m0-4h-2V7h2v6Z\"/></svg>');\n --md-status--deprecated: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 3v1H4v2h1v13a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6h1V4h-5V3H9m0 5h2v9H9V8m4 0h2v9h-2V8Z\"/></svg>');\n --md-status--encrypted: url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 1 3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4m0 6c1.4 0 2.8 1.1 2.8 2.5V11c.6 0 1.2.6 1.2 1.3v3.5c0 .6-.6 1.2-1.3 1.2H9.2c-.6 0-1.2-.6-1.2-1.3v-3.5c0-.6.6-1.2 1.2-1.2V9.5C9.2 8.1 10.6 7 12 7m0 1.2c-.8 0-1.5.5-1.5 1.3V11h3V9.5c0-.8-.7-1.3-1.5-1.3Z\"/></svg>');\n}\n\n:host > * {\n /* CODE */\n --md-code-fg-color: ${theme.palette.text.primary};\n --md-code-bg-color: ${\n theme.palette.code?.background ?? theme.palette.background.paper\n };\n --md-code-hl-color: ${alpha(theme.palette.warning.main, 0.5)};\n --md-code-hl-color--light: var(--md-code-hl-color);\n --md-code-hl-keyword-color: ${\n theme.palette.type === 'dark'\n ? theme.palette.primary.light\n : theme.palette.primary.dark\n };\n --md-code-hl-function-color: ${\n theme.palette.type === 'dark'\n ? theme.palette.secondary.light\n : theme.palette.secondary.dark\n };\n --md-code-hl-string-color: ${\n theme.palette.type === 'dark'\n ? theme.palette.success.light\n : theme.palette.success.dark\n };\n --md-code-hl-number-color: ${\n theme.palette.type === 'dark'\n ? theme.palette.error.light\n : theme.palette.error.dark\n };\n --md-code-hl-constant-color: var(--md-code-hl-function-color);\n --md-code-hl-special-color: var(--md-code-hl-function-color);\n --md-code-hl-name-color: var(--md-code-fg-color);\n --md-code-hl-comment-color: var(--md-default-fg-color--light);\n --md-code-hl-generic-color: var(--md-default-fg-color--light);\n --md-code-hl-variable-color: var(--md-default-fg-color--light);\n --md-code-hl-operator-color: var(--md-default-fg-color--light);\n --md-code-hl-punctuation-color: var(--md-default-fg-color--light);\n\n /* TYPESET */\n --md-typeset-font-size: 1rem;\n --md-typeset-color: var(--md-default-fg-color);\n --md-typeset-a-color: ${theme.palette.link};\n --md-typeset-table-color: ${alpha(theme.palette.text.primary, 0.15)};\n --md-typeset-table-color--light: ${alpha(theme.palette.text.primary, 0.05)};\n --md-typeset-del-color: ${\n theme.palette.type === 'dark'\n ? alpha(theme.palette.error.dark, 0.5)\n : alpha(theme.palette.error.light, 0.5)\n };\n --md-typeset-ins-color: ${\n theme.palette.type === 'dark'\n ? alpha(theme.palette.success.dark, 0.5)\n : alpha(theme.palette.success.light, 0.5)\n };\n --md-typeset-mark-color: ${\n theme.palette.type === 'dark'\n ? alpha(theme.palette.warning.dark, 0.5)\n : alpha(theme.palette.warning.light, 0.5)\n };\n --md-typeset-kbd-color: var(--md-code-bg-color);\n --md-typeset-kbd-accent-color var(--md-code-bg-color);\n --md-typeset-kbd-border-color: var(--md-default-fg-color--light);\n}\n\n@media screen and (max-width: 76.1875em) {\n :host > * {\n /* TYPESET */\n --md-typeset-font-size: .9rem;\n }\n}\n\n@media screen and (max-width: 600px) {\n :host > * {\n /* TYPESET */\n --md-typeset-font-size: .7rem;\n }\n}\n\n --md-footer-bg-color: var(--md-default-bg-color);\n --md-footer-bg-color--dark: var(--md-default-bg-color);\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 { RuleOptions } from './types';\n\nexport default ({ theme }: RuleOptions) => `\n/*================== Reset ==================*/\n\nbody {\n --md-text-color: var(--md-default-fg-color);\n --md-text-link-color: var(--md-accent-fg-color);\n --md-text-font-family: ${theme.typography.fontFamily};\n font-family: var(--md-text-font-family);\n background-color: unset;\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\nexport default () => `\n/*================== Animations ==================*/\n/*\n Disable CSS animations on link colors as they lead to issues in dark mode.\n The dark mode color theme is applied later and theirfore there is always an animation from light to dark mode when navigation between pages.\n*/\n.md-dialog, .md-nav__link, .md-footer__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink {\n transition: none;\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 { RuleOptions } from './types';\n\nexport default ({ theme }: RuleOptions) => `\n/*================== Extensions ==================*/\n\n/* HIGHLIGHT */\n.highlight .md-clipboard:after {\n content: unset;\n}\n\n.highlight .nx {\n color: ${theme.palette.type === 'dark' ? '#ff53a3' : '#ec407a'};\n}\n\n/* CODE HILITE */\n.codehilite .gd {\n background-color: ${\n theme.palette.type === 'dark' ? 'rgba(248,81,73,0.65)' : '#fdd'\n };\n}\n\n.codehilite .gi {\n background-color: ${\n theme.palette.type === 'dark' ? 'rgba(46,160,67,0.65)' : '#dfd'\n };\n}\n\n/* TABBED */\n.tabbed-set>input:nth-child(1):checked~.tabbed-labels>:nth-child(1),\n.tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),\n.tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),\n.tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),\n.tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),\n.tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),\n.tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),\n.tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),\n.tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),\n.tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),\n.tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),\n.tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),\n.tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),\n.tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),\n.tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),\n.tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),\n.tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),\n.tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),\n.tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),\n.tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20) {\n color: var(--md-accent-fg-color);\n border-color: var(--md-accent-fg-color);\n}\n\n/* TASK-LIST */\n.task-list-control .task-list-indicator::before {\n background-color: ${theme.palette.action.disabledBackground};\n}\n.task-list-control [type=\"checkbox\"]:checked + .task-list-indicator:before {\n background-color: ${theme.palette.success.main};\n}\n\n/* ADMONITION */\n.admonition {\n font-size: var(--md-typeset-font-size) !important;\n}\n.admonition .admonition-title {\n padding-left: 2.5rem !important;\n}\n\n.admonition .admonition-title:before {\n top: 50% !important;\n width: 20px !important;\n height: 20px !important;\n transform: translateY(-50%) !important;\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\nexport type Transformer = (dom: Element) => Element | Promise<Element>;\n\nexport const transform = async (\n html: string | Element,\n transformers: Transformer[],\n): Promise<Element> => {\n let dom: Element;\n\n if (typeof html === 'string') {\n dom = new DOMParser().parseFromString(html, 'text/html').documentElement;\n } else if (html instanceof Element) {\n dom = html;\n } else {\n throw new Error('dom is not a recognized type');\n }\n\n for (const transformer of transformers) {\n dom = await transformer(dom);\n }\n\n return dom;\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 */\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { TechDocsStorageApi } from '../../api';\nimport type { Transformer } from './transformer';\n\ntype AddBaseUrlOptions = {\n techdocsStorageApi: TechDocsStorageApi;\n entityId: CompoundEntityRef;\n path: string;\n};\n\n/**\n * TechDocs backend serves SVGs with text/plain content-type for security. This\n * helper determines if an SVG is being loaded from the backend, and thus needs\n * inlining to be displayed properly.\n */\nconst isSvgNeedingInlining = (\n attrName: string,\n attrVal: string,\n apiOrigin: string,\n) => {\n // Let's let the URL object do automatic parsing of the pathname for us\n const pathname = new URL(attrVal, 'https://ignored.com').pathname;\n const isSrcToSvg = attrName === 'src' && pathname.endsWith('.svg');\n\n const isRelativeUrl = !attrVal.match(/^([a-z]*:)?\\/\\//i);\n const pointsToOurBackend = attrVal.startsWith(apiOrigin);\n return isSrcToSvg && (isRelativeUrl || pointsToOurBackend);\n};\n\nexport const addBaseUrl = ({\n techdocsStorageApi,\n entityId,\n path,\n}: AddBaseUrlOptions): Transformer => {\n return async dom => {\n const apiOrigin = await techdocsStorageApi.getApiOrigin();\n\n const updateDom = async <T extends Element>(\n list: HTMLCollectionOf<T> | NodeListOf<T>,\n attributeName: string,\n ) => {\n for (const elem of list) {\n if (elem.hasAttribute(attributeName)) {\n const elemAttribute = elem.getAttribute(attributeName);\n if (!elemAttribute) return;\n\n // Special handling for SVG images.\n const newValue = await techdocsStorageApi.getBaseUrl(\n elemAttribute,\n entityId,\n path,\n );\n\n if (isSvgNeedingInlining(attributeName, elemAttribute, apiOrigin)) {\n try {\n const svg = await fetch(newValue, { credentials: 'include' });\n const svgContent = await svg.text();\n elem.setAttribute(\n attributeName,\n `data:image/svg+xml;base64,${btoa(\n unescape(encodeURIComponent(svgContent)),\n )}`,\n );\n } catch (e) {\n elem.setAttribute('alt', `Error: ${elemAttribute}`);\n }\n } else {\n elem.setAttribute(attributeName, newValue);\n }\n }\n }\n };\n\n await Promise.all([\n updateDom<HTMLImageElement>(dom.querySelectorAll('img'), 'src'),\n updateDom<HTMLScriptElement>(dom.querySelectorAll('script'), 'src'),\n updateDom<HTMLSourceElement>(dom.querySelectorAll('source'), 'src'),\n updateDom<HTMLLinkElement>(dom.querySelectorAll('link'), 'href'),\n updateDom<HTMLAnchorElement>(dom.querySelectorAll('a[download]'), 'href'),\n ]);\n\n return dom;\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 type { Transformer } from './transformer';\n\nexport const rewriteDocLinks = (): Transformer => {\n return dom => {\n const updateDom = <T extends Element>(\n list: Array<T>,\n attributeName: string,\n ): void => {\n Array.from(list)\n .filter(elem => elem.hasAttribute(attributeName))\n .forEach((elem: T) => {\n const elemAttribute = elem.getAttribute(attributeName);\n if (elemAttribute) {\n // if link is external, add target to open in a new window or tab\n if (elemAttribute.match(/^https?:\\/\\//i)) {\n elem.setAttribute('target', '_blank');\n }\n\n try {\n const normalizedWindowLocation = normalizeUrl(\n window.location.href,\n );\n elem.setAttribute(\n attributeName,\n new URL(elemAttribute, normalizedWindowLocation).toString(),\n );\n } catch (_e) {\n // Non-parseable links should be re-written as plain text.\n elem.replaceWith(elem.textContent || elemAttribute);\n }\n }\n });\n };\n\n updateDom(Array.from(dom.getElementsByTagName('a')), 'href');\n\n return dom;\n };\n};\n\n/** Make sure that the input url always ends with a '/' */\nexport function normalizeUrl(input: string): string {\n const url = new URL(input);\n\n if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {\n url.pathname += '/';\n }\n\n return url.toString();\n}\n","/*\n * Copyright 2024 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 { makeStyles } from '@material-ui/core/styles';\nimport { useState } from 'react';\nimport Snackbar from '@material-ui/core/Snackbar';\nimport Button from '@material-ui/core/Button';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../../translation';\n\ntype TechDocsRedirectNotificationProps = {\n handleButtonClick: () => void;\n message: string;\n autoHideDuration: number;\n};\n\nconst useStyles = makeStyles(theme => ({\n button: {\n color: theme.palette.primary.light,\n textDecoration: 'underline',\n },\n}));\n\nexport const TechDocsRedirectNotification = ({\n message,\n handleButtonClick,\n autoHideDuration,\n}: TechDocsRedirectNotificationProps) => {\n const classes = useStyles();\n const [open, setOpen] = useState(true);\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n const handleClose = () => setOpen(false);\n\n return (\n <Snackbar\n open={open}\n anchorOrigin={{ vertical: 'top', horizontal: 'right' }}\n autoHideDuration={autoHideDuration}\n color=\"primary\"\n onClose={handleClose}\n message={message}\n action={\n <Button\n classes={{ root: classes.button }}\n size=\"small\"\n onClick={() => {\n handleClose();\n handleButtonClick();\n }}\n >\n {t('redirectNotification.redirectNow')}\n </Button>\n }\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 { useState, useCallback } from 'react';\nimport { renderReactElement } from './renderReactElement';\nimport { ThemeProvider } from '@material-ui/core/styles';\nimport SvgIcon from '@material-ui/core/SvgIcon';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { withStyles, Theme } from '@material-ui/core/styles';\nimport IconButton from '@material-ui/core/IconButton';\nimport type { Transformer } from './transformer';\nimport useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\n\nconst CopyToClipboardTooltip = withStyles(theme => ({\n tooltip: {\n fontSize: 'inherit',\n color: theme.palette.text.primary,\n margin: 0,\n padding: theme.spacing(0.5),\n backgroundColor: 'transparent',\n boxShadow: 'none',\n },\n}))(Tooltip);\n\nconst CopyToClipboardIcon = () => (\n <SvgIcon>\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </SvgIcon>\n);\n\ntype CopyToClipboardButtonProps = {\n text: string;\n};\n\nconst CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => {\n const [open, setOpen] = useState(false);\n const [, copyToClipboard] = useCopyToClipboard();\n\n const handleClick = useCallback(() => {\n copyToClipboard(text);\n setOpen(true);\n }, [text, copyToClipboard]);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n return (\n <CopyToClipboardTooltip\n title=\"Copied to clipboard\"\n placement=\"left\"\n open={open}\n onClose={handleClose}\n leaveDelay={1000}\n >\n <IconButton\n style={{\n position: 'absolute',\n // top & right was removed from upstream .md-clipboard in mkdocs-material 9.7.0\n top: '0.5rem',\n right: '0.5rem',\n }}\n className=\"md-clipboard md-icon\"\n onClick={handleClick}\n aria-label=\"Copy to clipboard\"\n >\n <CopyToClipboardIcon />\n </IconButton>\n </CopyToClipboardTooltip>\n );\n};\n\n/**\n * Recreates copy-to-clipboard functionality attached to <code> snippets that\n * is native to mkdocs-material theme.\n *\n * Unlike native mkdocs-material theme, this is always enabled and does not respect the mkdocs's config `theme.features` `content.code.copy` setting.\n */\nexport const copyToClipboard = (theme: Theme): Transformer => {\n return dom => {\n const codes = dom.querySelectorAll('pre > code');\n for (const code of codes) {\n const text = code.textContent || '';\n const container = document.createElement('div');\n code?.parentElement?.prepend(container);\n renderReactElement(\n <ThemeProvider theme={theme}>\n <CopyToClipboardButton text={text} />\n </ThemeProvider>,\n container,\n );\n }\n return dom;\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 { SHADOW_DOM_STYLE_LOAD_EVENT } from '@backstage/plugin-techdocs-react';\nimport type { Transformer } from './transformer';\n\ntype OnCssReadyOptions = {\n onLoading: () => void;\n onLoaded: () => void;\n};\n\nexport const onCssReady = ({\n onLoading,\n onLoaded,\n}: OnCssReadyOptions): Transformer => {\n return dom => {\n onLoading();\n dom.addEventListener(\n SHADOW_DOM_STYLE_LOAD_EVENT,\n function handleShadowDomStyleLoad() {\n onLoaded();\n dom.removeEventListener(\n SHADOW_DOM_STYLE_LOAD_EVENT,\n handleShadowDomStyleLoad,\n );\n },\n );\n return dom;\n };\n};\n","/*\n * Copyright 2026 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 { useCallback, useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport {\n useShadowDomStylesLoading,\n useShadowRootElements,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\nimport { useApp } from '@backstage/core-plugin-api';\nimport { useTechDocsReaderDom } from '../reader/components/TechDocsReaderPageContent/dom';\nimport { useTechDocsReader } from '../reader/components/TechDocsReaderProvider';\n\n/**\n * Shared hook for TechDocs reader content data.\n * Encapsulates DOM setup, hash scrolling, shadow root handling,\n * 404 detection, and loading state.\n */\nexport function useTechDocsReaderContentData(options: {\n defaultPath?: string;\n onReady?: () => void;\n}) {\n const { defaultPath, onReady } = options;\n\n const {\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n entityRef,\n setShadowRoot,\n } = useTechDocsReaderPage();\n const { state } = useTechDocsReader();\n const dom = useTechDocsReaderDom(entityRef, defaultPath);\n const location = useLocation();\n const path = location.pathname;\n const hash = location.hash;\n const isStyleLoading = useShadowDomStylesLoading(dom);\n const [hashElement] = useShadowRootElements([`[id=\"${hash.slice(1)}\"]`]);\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\n\n useEffect(() => {\n if (isStyleLoading) return;\n\n if (hash) {\n if (hashElement) {\n hashElement.scrollIntoView();\n const link = hashElement.querySelector<HTMLElement>('a.headerlink');\n if (link) {\n link.focus();\n }\n }\n } else {\n document?.querySelector('header')?.scrollIntoView();\n }\n }, [path, hash, hashElement, isStyleLoading]);\n\n const handleAppend = useCallback(\n (newShadowRoot: ShadowRoot) => {\n setShadowRoot(newShadowRoot);\n if (onReady instanceof Function) {\n onReady();\n }\n },\n [setShadowRoot, onReady],\n );\n\n const isNotFound = entityMetadataLoading === false && !entityMetadata;\n const isDomReady = !!dom;\n const showProgress = state === 'CHECKING' || isStyleLoading;\n\n return {\n entityRef,\n entityMetadata,\n dom,\n handleAppend,\n isNotFound,\n isDomReady,\n showProgress,\n NotFoundErrorPage,\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 useCallback,\n useEffect,\n useLayoutEffect,\n // useRef,\n useState,\n} from 'react';\n\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { useTheme } from '@material-ui/core/styles';\n\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { configApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\n\nimport {\n techdocsStorageApiRef,\n useShadowDomStylesLoading,\n} from '@backstage/plugin-techdocs-react';\n\nimport { useTechDocsReader } from '../TechDocsReaderProvider';\n\nimport {\n addBaseUrl,\n addGitFeedbackLink,\n addLinkClickListener,\n addSidebarToggle,\n onCssReady,\n removeMkdocsHeader,\n rewriteDocLinks,\n simplifyMkdocsFooter,\n scrollIntoNavigation,\n transform as transformer,\n copyToClipboard,\n useSanitizerTransformer,\n useStylesTransformer,\n handleMetaRedirects,\n addNavLinkKeyboardToggle,\n} from '../../transformers';\nimport { useNavigateUrl } from './useNavigateUrl';\nimport { useLocation, useNavigate, useParams } from 'react-router-dom';\n\nconst MOBILE_MEDIA_QUERY = 'screen and (max-width: 76.1875em)';\n\n// If a defaultPath is specified then we should navigate to that path replacing the\n// current location in the history. This should only happen on the initial load so\n// navigating to the root of the docs doesn't also redirect.\nexport const useInitialRedirect = (defaultPath?: string) => {\n const location = useLocation();\n const navigate = useNavigate();\n const { '*': currPath = '' } = useParams();\n\n useLayoutEffect(() => {\n if (currPath === '' && defaultPath) {\n navigate(`${location.pathname}${defaultPath}`, { replace: true });\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n};\n\n/**\n * Hook that encapsulates the behavior of getting raw HTML and applying\n * transforms to it in order to make it function at a basic level in the\n * Backstage UI.\n */\nexport const useTechDocsReaderDom = (\n entityRef: CompoundEntityRef,\n defaultPath?: string,\n): Element | null => {\n const navigate = useNavigateUrl();\n const theme = useTheme();\n const isMobileMedia = useMediaQuery(MOBILE_MEDIA_QUERY);\n const sanitizerTransformer = useSanitizerTransformer();\n const stylesTransformer = useStylesTransformer();\n const analytics = useAnalytics();\n\n const techdocsStorageApi = useApi(techdocsStorageApiRef);\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const configApi = useApi(configApiRef);\n\n const { state, path, content: rawPage } = useTechDocsReader();\n const { '*': currPath = '' } = useParams();\n\n const [dom, setDom] = useState<HTMLElement | null>(null);\n const isStyleLoading = useShadowDomStylesLoading(dom);\n\n useInitialRedirect(defaultPath);\n\n const updateSidebarPositionAndHeight = useCallback(() => {\n if (!dom) return;\n\n const sidebars = dom.querySelectorAll<HTMLElement>('.md-sidebar');\n\n sidebars.forEach(element => {\n // set sidebar position to render in correct position\n if (isMobileMedia) {\n element.style.top = '0px';\n } else {\n const page = document?.querySelector('.techdocs-reader-page');\n const pageTop = page?.getBoundingClientRect().top ?? 0;\n let domTop = dom.getBoundingClientRect().top ?? 0;\n\n const tabs = dom.querySelector('.md-container > .md-tabs');\n const tabsHeight = tabs?.getBoundingClientRect().height ?? 0;\n\n // the sidebars should not scroll beyond the total height of the header and tabs\n if (domTop < pageTop) {\n domTop = pageTop;\n }\n\n const scrollbarTopPx = Math.max(domTop, 0) + tabsHeight;\n\n element.style.top = `${scrollbarTopPx}px`;\n\n // set scrollbar height to ensure all links can be seen when content is small\n const footer = dom.querySelector('.md-container > .md-footer');\n // if no footer, fallback to using the bottom of the window\n const scrollbarEndPx =\n footer?.getBoundingClientRect().top ?? window.innerHeight;\n\n element.style.height = `${scrollbarEndPx - scrollbarTopPx}px`;\n }\n\n // show the sidebar only after updating its position\n element.style.setProperty('opacity', '1');\n });\n }, [dom, isMobileMedia]);\n\n useEffect(() => {\n window.addEventListener('resize', updateSidebarPositionAndHeight);\n window.addEventListener('scroll', updateSidebarPositionAndHeight, true);\n return () => {\n window.removeEventListener('resize', updateSidebarPositionAndHeight);\n window.removeEventListener(\n 'scroll',\n updateSidebarPositionAndHeight,\n true,\n );\n };\n }, [dom, updateSidebarPositionAndHeight]);\n\n // dynamically set width of footer to accommodate for pinning of the sidebar\n const updateFooterWidth = useCallback(() => {\n if (!dom) return;\n const footer = dom.querySelector<HTMLElement>('.md-footer');\n if (footer) {\n footer.style.width = `${dom.getBoundingClientRect().width}px`;\n }\n }, [dom]);\n\n useEffect(() => {\n window.addEventListener('resize', updateFooterWidth);\n return () => {\n window.removeEventListener('resize', updateFooterWidth);\n };\n }, [dom, updateFooterWidth]);\n\n // an update to \"state\" might lead to an updated UI so we include it as a trigger\n useEffect(() => {\n if (!isStyleLoading) {\n updateFooterWidth();\n updateSidebarPositionAndHeight();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n state,\n isStyleLoading,\n updateFooterWidth,\n updateSidebarPositionAndHeight,\n ]);\n\n // a function that performs transformations that are executed prior to adding it to the DOM\n const preRender = useCallback(\n (rawContent: string, contentPath: string) =>\n transformer(rawContent, [\n sanitizerTransformer,\n addBaseUrl({\n techdocsStorageApi,\n entityId: entityRef,\n path: contentPath,\n }),\n rewriteDocLinks(),\n addSidebarToggle(),\n removeMkdocsHeader(),\n simplifyMkdocsFooter(),\n addGitFeedbackLink(scmIntegrationsApi),\n stylesTransformer,\n ]),\n [\n // only add dependencies that are in state or memorized variables to avoid unnecessary calls between re-renders\n entityRef,\n scmIntegrationsApi,\n techdocsStorageApi,\n sanitizerTransformer,\n stylesTransformer,\n ],\n );\n\n // a function that performs transformations that are executed after adding it to the DOM\n const postRender = useCallback(\n async (transformedElement: Element) =>\n transformer(transformedElement, [\n handleMetaRedirects(navigate, entityRef.name),\n scrollIntoNavigation(),\n copyToClipboard(theme),\n addLinkClickListener({\n baseUrl:\n configApi.getOptionalString('app.baseUrl') ||\n window.location.origin,\n onClick: (event: MouseEvent, url: string) => {\n // detect if CTRL or META keys are pressed so that links can be opened in a new tab with `window.open`\n const modifierActive = event.ctrlKey || event.metaKey;\n const parsedUrl = new URL(url);\n\n // capture link clicks within documentation\n const linkText =\n (event.target as HTMLAnchorElement | undefined)?.innerText || url;\n const to = url.replace(window.location.origin, '');\n analytics.captureEvent('click', linkText, { attributes: { to } });\n\n // hash exists when anchor is clicked on secondary sidebar\n if (parsedUrl.hash) {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n // If it's in a different page, we navigate to it\n if (window.location.pathname !== parsedUrl.pathname) {\n navigate(url);\n } else {\n // If it's in the same page we avoid using navigate that causes\n // the page to rerender.\n window.history.pushState(\n null,\n document.title,\n parsedUrl.hash,\n );\n }\n // Scroll to hash if it's on the current page\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.scrollIntoView();\n\n // Focus first focusable element in the target section\n (\n transformedElement\n ?.querySelector(`[id=\"${parsedUrl.hash.slice(1)}\"]`)\n ?.querySelector('a, button, [tabindex]') as HTMLElement\n )?.focus();\n }\n } else {\n if (modifierActive) {\n window.open(url, '_blank');\n } else {\n navigate(url);\n }\n }\n },\n }),\n // disable MkDocs drawer toggling ('for' attribute => checkbox mechanism)\n onCssReady({\n onLoading: () => {},\n onLoaded: () => {\n transformedElement\n .querySelector('.md-nav__title')\n ?.removeAttribute('for');\n },\n }),\n // hide sidebars until their positions are updated\n onCssReady({\n onLoading: () => {\n const sidebars = Array.from(\n transformedElement.querySelectorAll<HTMLElement>('.md-sidebar'),\n );\n sidebars.forEach(element => {\n element.style.setProperty('opacity', '0');\n });\n },\n onLoaded: () => {},\n }),\n addNavLinkKeyboardToggle(),\n ]),\n [theme, navigate, analytics, entityRef.name, configApi],\n );\n\n useEffect(() => {\n if (!rawPage) return () => {};\n\n // if false, there is already a newer execution of this effect\n let shouldReplaceContent = true;\n\n // Pre-render\n preRender(rawPage, path).then(async preTransformedDomElement => {\n if (!preTransformedDomElement?.innerHTML) {\n return; // An unexpected error occurred\n }\n\n // don't manipulate the shadow dom if this isn't the latest effect execution\n if (!shouldReplaceContent) {\n return;\n }\n\n // Skip this update if the location's path has changed but the state\n // contains a page that isn't loaded yet.\n if (currPath !== path) {\n return;\n }\n\n // Scroll to top after render\n window.scroll({ top: 0 });\n\n // Post-render\n const postTransformedDomElement = await postRender(\n preTransformedDomElement,\n );\n\n setDom(postTransformedDomElement as HTMLElement);\n });\n\n // cancel this execution\n return () => {\n shouldReplaceContent = false;\n };\n }, [rawPage, currPath, path, preRender, postRender]);\n\n return dom;\n};\n","/*\n * Copyright 2023 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 */\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\n/**\n * Resolve a URL to a relative URL given a base URL that may or may not include subpaths.\n * @param url - URL to parse into a relative url based on the baseUrl.\n * @param baseUrl - Application base url, where the application is currently hosted.\n * @returns relative path without any subpaths from website config.\n */\nexport function resolveUrlToRelative(url: string, baseUrl: string) {\n const parsedAppUrl = new URL(baseUrl);\n const appUrlPath = `${parsedAppUrl.origin}${parsedAppUrl.pathname.replace(\n /\\/$/,\n '',\n )}`;\n\n const relativeUrl = url\n .replace(appUrlPath, '')\n // Remove any leading slashes.\n .replace(/^\\/+/, '');\n const parsedUrl = new URL(`http://localhost/${relativeUrl}`);\n return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;\n}\n\n/**\n * A helper hook that allows for full internal website urls to be processed through the navigate\n * hook provided by `react-router-dom`.\n *\n * NOTE: This does not support routing to external URLs. That should be done with a `Link` or `a`\n * element instead, or just `window.location.href`.\n *\n * TODO: Update this to use `useRouteRef` instead of `useApi`.\n *\n * @returns Navigation function that is a wrapper over `react-router-dom`'s\n * to support passing full URLs for navigation.\n *\n * @public\n */\nexport function useNavigateUrl() {\n // useRef prevents useNavigate from causing unnecessary re-renders\n const navigate = useRef(useNavigate());\n const configApi = useApi(configApiRef);\n const appBaseUrl = configApi.getOptionalString('app.baseUrl');\n const navigateFn = useCallback(\n (to: string) => {\n let url = to;\n /**\n * This should always be true when running the application, this just allows\n * test cases that do not have the configApi set up to run still.\n */\n if (appBaseUrl) {\n try {\n url = resolveUrlToRelative(to, appBaseUrl);\n } catch (err) {\n // URL passed in was relative.\n }\n }\n navigate.current(url);\n },\n [appBaseUrl],\n );\n return navigateFn;\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 DOMPurify from 'dompurify';\nimport { useCallback, useMemo } from 'react';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { Transformer } from '../transformer';\nimport {\n removeRestrictedAttributes,\n removeUnsafeIframes,\n removeUnsafeLinks,\n removeUnsafeMetaTags,\n} from './hooks';\n\n/**\n * Returns html sanitizer configuration\n */\nconst useSanitizerConfig = () => {\n const configApi = useApi(configApiRef);\n\n return useMemo(() => {\n return configApi.getOptionalConfig('techdocs.sanitizer');\n }, [configApi]);\n};\n\n/**\n * Returns a transformer that sanitizes the dom\n */\nexport const useSanitizerTransformer = (): Transformer => {\n const config = useSanitizerConfig();\n\n const purify = useMemo(() => {\n // eslint-disable-next-line new-cap\n const instance = DOMPurify();\n\n instance.addHook('beforeSanitizeElements', removeUnsafeLinks);\n\n const hosts = config?.getOptionalStringArray('allowedIframeHosts');\n if (hosts) {\n instance.addHook('beforeSanitizeElements', removeUnsafeIframes(hosts));\n }\n\n instance.addHook('uponSanitizeElement', removeUnsafeMetaTags);\n\n instance.addHook('uponSanitizeAttribute', removeRestrictedAttributes);\n\n return instance;\n }, [config]);\n\n return useCallback(\n async (dom: Element) => {\n const hosts = config?.getOptionalStringArray('allowedIframeHosts');\n const tags = ['link', 'meta'];\n\n if (hosts) {\n tags.push('iframe');\n }\n\n const tagNameCheck = config?.getOptionalString(\n 'allowedCustomElementTagNameRegExp',\n );\n const attributeNameCheck = config?.getOptionalString(\n 'allowedCustomElementAttributeNameRegExp',\n );\n const additionalAllowedURIProtocols =\n config?.getOptionalStringArray('additionalAllowedURIProtocols') || [];\n\n // Define allowed URI protocols, including any additional ones from the config.\n // The default protocols are based on the DOMPurify defaults.\n const allowedURIProtocols = [\n 'callto',\n 'cid',\n 'ftp',\n 'ftps',\n 'http',\n 'https',\n 'mailto',\n 'matrix',\n 'sms',\n 'tel',\n 'xmpp',\n ...additionalAllowedURIProtocols,\n ].filter(Boolean);\n\n const allowedURIRegExp = new RegExp(\n // This regex is not exposed by DOMPurify, so we need to define it ourselves.\n // It is possible for this to drift from the default in future versions of DOMPurify.\n // See: https://raw.githubusercontent.com/cure53/DOMPurify/master/src/regexp.ts\n `^(?:${allowedURIProtocols.join(\n '|',\n )}:|[^a-z]|[a-z+.-]+(?:[^a-z+.\\\\-:]|$))`,\n 'i',\n );\n\n // using outerHTML as we want to preserve the html tag attributes (lang)\n return purify.sanitize(dom.outerHTML, {\n ADD_TAGS: tags,\n FORBID_TAGS: ['style'],\n ADD_ATTR: ['http-equiv', 'content', 'dominant-baseline'],\n WHOLE_DOCUMENT: true,\n RETURN_DOM: true,\n ALLOWED_URI_REGEXP: allowedURIRegExp,\n CUSTOM_ELEMENT_HANDLING: {\n tagNameCheck: tagNameCheck ? new RegExp(tagNameCheck) : undefined,\n attributeNameCheck: attributeNameCheck\n ? new RegExp(attributeNameCheck)\n : undefined,\n },\n }) as Element;\n },\n [config, purify],\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 { useCallback, useMemo } from 'react';\nimport { useTheme } from '@material-ui/core/styles';\nimport { useSidebarPinState } from '@backstage/core-components';\nimport { Transformer } from '../transformer';\nimport { rules } from './rules';\n\n/**\n * Sidebar pinned state to be used in computing style injections.\n */\nconst useSidebar = () => useSidebarPinState();\n\n/**\n * Process all rules and concatenate their definitions into a single style.\n * @returns a string containing all processed style definitions.\n */\nconst useRuleStyles = () => {\n const sidebar = useSidebar();\n const theme = useTheme();\n\n return useMemo(() => {\n const options = { theme, sidebar };\n return rules.reduce<string>((styles, rule) => styles + rule(options), '');\n }, [theme, sidebar]);\n};\n\n/**\n * Returns a transformer that inserts all style rules into the given element's head tag.\n */\nexport const useStylesTransformer = (): Transformer => {\n const styles = useRuleStyles();\n\n return useCallback(\n (dom: Element) => {\n dom\n .getElementsByTagName('head')[0]\n .insertAdjacentHTML('beforeend', `<style>${styles}</style>`);\n return dom;\n },\n [styles],\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 { isElement } from '../utils';\n\n/**\n * Checks whether a node is iframe or not.\n * @param node - can be any element.\n * @returns true when node is iframe.\n */\nconst isIframe = (node: Element) => node.nodeName === 'IFRAME';\n\n/**\n * Checks whether a iframe is safe or not.\n * @param node - is an iframe element.\n * @param hosts - list of allowed hosts.\n * @returns true when iframe is included in hosts.\n */\nconst isSafe = (node: Element, hosts: string[]) => {\n const src = node.getAttribute('src') || '';\n try {\n const { host } = new URL(src);\n return hosts.includes(host);\n } catch {\n return false;\n }\n};\n\n/**\n * Returns a function that removes unsafe iframe nodes.\n * @param node - can be any element.\n * @param hosts - list of allowed hosts.\n */\nexport const removeUnsafeIframes = (hosts: string[]) => (node: Node) => {\n if (!isElement(node)) return;\n\n if (isIframe(node) && !isSafe(node, hosts)) {\n node.remove();\n }\n};\n","/*\n * Copyright 2021 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 type { Transformer } from './transformer';\nimport MenuIcon from '@material-ui/icons/Menu';\nimport { createElement } from 'react';\nimport { renderReactElement } from './renderReactElement';\n\nexport const addSidebarToggle = (): Transformer => {\n return dom => {\n // attempting to use selectors that are more likely to be static as MkDocs updates over time\n const mkdocsToggleSidebar = dom.querySelector(\n '.md-header label[for=\"__drawer\"]',\n ) as HTMLLabelElement;\n const article = dom.querySelector('article') as HTMLElement;\n\n // Fail gracefully\n if (!mkdocsToggleSidebar || !article) {\n return dom;\n }\n\n const toggleSidebar = mkdocsToggleSidebar.cloneNode() as HTMLLabelElement;\n renderReactElement(createElement(MenuIcon), toggleSidebar);\n toggleSidebar.id = 'toggle-sidebar';\n toggleSidebar.title = 'Toggle Sidebar';\n toggleSidebar.classList.add('md-content__button');\n toggleSidebar.style.setProperty('padding', '0 0 0 5px');\n toggleSidebar.style.setProperty('margin', '0.4rem 0 0.4rem 0.4rem');\n article?.prepend(toggleSidebar);\n return dom;\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 type { Transformer } from './transformer';\n\nexport const removeMkdocsHeader = (): Transformer => {\n return dom => {\n // Remove the header\n dom.querySelector('.md-header')?.remove();\n\n return dom;\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 type { Transformer } from './transformer';\n\nexport const simplifyMkdocsFooter = (): Transformer => {\n return dom => {\n // Remove new mkdocs copyright\n dom.querySelector('.md-footer .md-copyright')?.remove();\n // Remove old mkdocs copyright\n dom.querySelector('.md-footer-copyright')?.remove();\n return dom;\n };\n};\n","/*\n * Copyright 2021 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 type { Transformer } from './transformer';\nimport {\n replaceGithubUrlType,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined';\nimport { createElement } from 'react';\nimport parseGitUrl from 'git-url-parse';\nimport { renderReactElement } from './renderReactElement';\n\n// requires repo\nexport const addGitFeedbackLink = (\n scmIntegrationsApi: ScmIntegrationRegistry,\n): Transformer => {\n return dom => {\n // attempting to use selectors that are more likely to be static as MkDocs updates over time\n const sourceAnchor = dom.querySelector(\n '[title=\"Edit this page\"]',\n ) as HTMLAnchorElement;\n\n // don't show if edit link not available in raw page\n if (!sourceAnchor || !sourceAnchor.href) {\n return dom;\n }\n\n const sourceURL = new URL(sourceAnchor.href);\n const integration = scmIntegrationsApi.byUrl(sourceURL);\n\n // don't show if can't identify edit link hostname as a gitlab/github hosting\n if (integration?.type !== 'github' && integration?.type !== 'gitlab') {\n return dom;\n }\n\n // topmost h1 only contains title for whole page\n const title =\n (dom.querySelector('article>h1') as HTMLElement)?.childNodes[0]\n .textContent || '';\n const issueTitle = encodeURIComponent(`Documentation Feedback: ${title}`);\n const issueDesc = encodeURIComponent(\n `Page source:\\n${sourceAnchor.href}\\n\\nFeedback:`,\n );\n\n // Convert GitHub edit url to blob type so it can be parsed by git-url-parse correctly\n const gitUrl =\n integration?.type === 'github'\n ? replaceGithubUrlType(sourceURL.href, 'blob')\n : sourceURL.href;\n const gitInfo = parseGitUrl(gitUrl);\n const repoPath = `/${gitInfo.organization}/${gitInfo.name}`;\n\n const feedbackLink = sourceAnchor.cloneNode() as HTMLAnchorElement;\n switch (integration?.type) {\n case 'gitlab':\n feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?issue[title]=${issueTitle}&issue[description]=${issueDesc}`;\n break;\n case 'github':\n feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?title=${issueTitle}&body=${issueDesc}`;\n break;\n default:\n return dom;\n }\n renderReactElement(createElement(FeedbackOutlinedIcon), feedbackLink);\n feedbackLink.style.paddingLeft = '5px';\n feedbackLink.title = 'Leave feedback for this page';\n feedbackLink.id = 'git-feedback-link';\n sourceAnchor?.insertAdjacentElement('beforebegin', feedbackLink);\n return dom;\n };\n};\n","/*\n * Copyright 2024 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 { Transformer } from './transformer';\nimport { normalizeUrl } from './rewriteDocLinks';\nimport { renderReactElement } from './renderReactElement';\nimport { TechDocsRedirectNotification } from '../components/TechDocsRedirectNotification';\n\nexport const handleMetaRedirects = (\n navigate: (to: string) => void,\n entityName: string,\n): Transformer => {\n const redirectAfterMs = 3000;\n\n const determineRedirectURL = (metaUrl: string) => {\n const normalizedCurrentUrl = normalizeUrl(window.location.href);\n // When creating URL object, if the metaUrl is relative, it will be resolved with base href. If it is absolute, it will replace the base href.\n const absoluteRedirectObj = new URL(metaUrl, normalizedCurrentUrl);\n const isExternalRedirect =\n absoluteRedirectObj.hostname !== window.location.hostname;\n\n if (isExternalRedirect) {\n const currentTechDocPath = window.location.pathname;\n const indexOfSiteHome = currentTechDocPath.indexOf(entityName);\n const siteHomePath = currentTechDocPath.slice(\n 0,\n indexOfSiteHome + entityName.length,\n );\n return new URL(siteHomePath, normalizedCurrentUrl).href;\n }\n return absoluteRedirectObj.href;\n };\n\n return dom => {\n for (const elem of Array.from(dom.querySelectorAll('meta'))) {\n if (elem.getAttribute('http-equiv') === 'refresh') {\n const metaContentParameters = elem\n .getAttribute('content')\n ?.split('url=');\n\n if (!metaContentParameters || metaContentParameters.length < 2) {\n return dom;\n }\n\n const metaUrl = metaContentParameters[1];\n const redirectURL = determineRedirectURL(metaUrl);\n\n // If the current URL is the same as the redirect URL, do not proceed with the redirect.\n if (window.location.href === redirectURL) {\n return dom;\n }\n\n const container = document.createElement('div');\n\n renderReactElement(\n <TechDocsRedirectNotification\n message=\"This TechDocs page is no longer maintained. Will automatically redirect to the designated replacement.\"\n handleButtonClick={() => navigate(redirectURL)}\n autoHideDuration={redirectAfterMs}\n />,\n container,\n );\n document.body.appendChild(container);\n\n setTimeout(() => {\n navigate(redirectURL);\n }, redirectAfterMs);\n\n return dom;\n }\n }\n return dom;\n };\n};\n","/*\n * Copyright 2021 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 type { Transformer } from './transformer';\n\nexport const scrollIntoNavigation = (): Transformer => {\n return dom => {\n setTimeout(() => {\n const activeNavItems = dom?.querySelectorAll(`li.md-nav__item--active`);\n if (activeNavItems.length !== 0) {\n // expand all navigation items that are active\n activeNavItems.forEach(activeNavItem => {\n const checkbox = activeNavItem?.querySelector('input');\n if (!checkbox?.checked) {\n checkbox?.click();\n }\n });\n\n const lastItem = activeNavItems[activeNavItems.length - 1];\n lastItem.scrollIntoView();\n }\n }, 200);\n return dom;\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 type { Transformer } from './transformer';\n\ntype AddLinkClickListenerOptions = {\n baseUrl: string;\n onClick: (e: MouseEvent, newUrl: string) => void;\n};\n\nexport const addLinkClickListener = ({\n baseUrl,\n onClick,\n}: AddLinkClickListenerOptions): Transformer => {\n return dom => {\n Array.from(dom.getElementsByTagName('a')).forEach(elem => {\n elem.addEventListener('click', (e: MouseEvent) => {\n const target = elem as HTMLAnchorElement;\n const href = target.getAttribute('href');\n\n if (!href) return;\n if (href.startsWith(baseUrl) && !elem.hasAttribute('download')) {\n e.preventDefault();\n onClick(e, href);\n }\n });\n });\n\n return dom;\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\nexport function addNavLinkKeyboardToggle() {\n return (element: Element) => {\n const navLabels = element.querySelectorAll('label.md-nav__link[for]');\n navLabels.forEach(label => {\n label.setAttribute('tabIndex', '0');\n label.addEventListener('keydown', event => {\n const keyboardEvent = event as KeyboardEvent;\n if (keyboardEvent.key === 'Enter' || keyboardEvent.key === ' ') {\n const forId = label.getAttribute('for');\n if (!forId) return;\n const checkbox = element.querySelector(\n `#${forId}`,\n ) as HTMLInputElement | null;\n if (checkbox && checkbox.type === 'checkbox') {\n checkbox.checked = !checkbox.checked;\n checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n event.preventDefault();\n event.stopPropagation();\n }\n }\n });\n });\n return element;\n };\n}\n","/*\n * Copyright 2026 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 { useEffect } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n useTechDocsAddons,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\nimport { entityPresentationApiRef } from '@backstage/plugin-catalog-react';\nimport capitalize from 'lodash/capitalize';\n\n/**\n * Shared hook for TechDocs reader header data.\n * Encapsulates title/subtitle sync, tab title computation,\n * 404 detection, and source link visibility.\n */\nexport function useTechDocsReaderHeaderData() {\n const addons = useTechDocsAddons();\n const configApi = useApi(configApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const { '*': path = '' } = useParams();\n\n const {\n title,\n setTitle,\n subtitle,\n setSubtitle,\n entityRef,\n metadata: { value: metadata, loading: metadataLoading },\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n useEffect(() => {\n if (!metadata) return;\n setTitle(metadata.site_name);\n setSubtitle(() => {\n let { site_description } = metadata;\n if (!site_description || site_description === 'None') {\n site_description = '';\n }\n return site_description;\n });\n }, [metadata, setTitle, setSubtitle]);\n\n const appTitle = configApi.getOptionalString('app.title') || 'Backstage';\n const locationMetadata = entityMetadata?.locationMetadata;\n const showSourceLink =\n !!locationMetadata &&\n locationMetadata.type !== 'dir' &&\n locationMetadata.type !== 'file';\n\n const noEntMetadata = !entityMetadataLoading && entityMetadata === undefined;\n const noTdMetadata = !metadataLoading && metadata === undefined;\n const hidden = noEntMetadata || noTdMetadata;\n\n const removeTrailingSlash = (str: string) => str.replace(/\\/$/, '');\n const normalizeAndSpace = (str: string) =>\n str.replace(/[-_]/g, ' ').split(' ').map(capitalize).join(' ');\n\n let tabTitle = appTitle;\n if (!hidden) {\n const stringEntityRef = stringifyEntityRef(entityRef);\n const entityDisplayName =\n entityPresentationApi.forEntity(stringEntityRef).snapshot.primaryTitle;\n\n let techdocsTabTitleItems: string[] = [];\n if (path !== '')\n techdocsTabTitleItems = removeTrailingSlash(path)\n .split('/')\n .map(normalizeAndSpace);\n\n const tabTitleItems = [\n entityDisplayName,\n ...techdocsTabTitleItems,\n appTitle,\n ];\n tabTitle = tabTitleItems.join(' | ');\n }\n\n return {\n title,\n subtitle,\n entityRef,\n entityMetadata,\n tabTitle,\n hidden,\n showSourceLink,\n sourceLink: locationMetadata?.target,\n addons,\n };\n}\n","/*\n * Copyright 2026 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 { useEffect, useRef, useState } from 'react';\nimport { useSearch } from '@backstage/plugin-search-react';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { ResultHighlight } from '@backstage/plugin-search-common';\n\nexport type TechDocsDoc = {\n namespace: string;\n kind: string;\n name: string;\n path: string;\n location: string;\n title: string;\n text: string;\n};\n\nexport type TechDocsSearchResult = {\n type: string;\n document: TechDocsDoc;\n highlight?: ResultHighlight;\n};\n\n/**\n * Shared hook for TechDocs search logic.\n * Encapsulates entity filter sync, results slicing,\n * and deferred loading state.\n */\nexport function useTechDocsSearch(entityId: CompoundEntityRef) {\n const {\n setFilters,\n setTerm,\n term,\n result: { loading, value: searchVal },\n } = useSearch();\n const [results, setResults] = useState<TechDocsSearchResult[]>([]);\n const [deferredLoading, setDeferredLoading] = useState(false);\n const loadingTimer = useRef<ReturnType<typeof setTimeout>>();\n\n useEffect(() => {\n if (searchVal) {\n setResults(searchVal.results.slice(0, 10) as TechDocsSearchResult[]);\n }\n }, [loading, searchVal]);\n\n useEffect(() => {\n clearTimeout(loadingTimer.current);\n setDeferredLoading(false);\n if (loading) {\n loadingTimer.current = setTimeout(() => setDeferredLoading(true), 200);\n }\n return () => clearTimeout(loadingTimer.current);\n }, [term, loading]);\n\n const { kind, name, namespace } = entityId;\n useEffect(() => {\n setFilters(prevFilters => ({\n ...prevFilters,\n kind,\n namespace,\n name,\n }));\n }, [kind, namespace, name, setFilters]);\n\n return {\n results,\n term,\n setTerm,\n loading,\n deferredLoading,\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 { PropsWithChildren } from 'react';\nimport Helmet from 'react-helmet';\n\nimport Grid from '@material-ui/core/Grid';\nimport Skeleton from '@material-ui/lab/Skeleton';\nimport CodeIcon from '@material-ui/icons/Code';\n\nimport {\n TechDocsAddonLocations as locations,\n TechDocsEntityMetadata,\n TechDocsMetadata,\n} from '@backstage/plugin-techdocs-react';\nimport {\n EntityRefLink,\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { RELATION_OWNED_BY, CompoundEntityRef } from '@backstage/catalog-model';\nimport { Header, HeaderLabel } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport capitalize from 'lodash/capitalize';\n\nimport { rootRouteRef } from '../../../routes';\nimport { techdocsTranslationRef } from '../../../translation';\nimport { useTechDocsReaderHeaderData } from '../../../hooks/useTechDocsReaderHeaderData';\n\nconst skeleton = <Skeleton animation=\"wave\" variant=\"text\" height={40} />;\n\n/**\n * Props for {@link TechDocsReaderPageHeader}\n *\n * @public\n * @deprecated No need to pass down properties anymore. The component consumes data from `TechDocsReaderPageContext` instead. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom header.\n */\nexport type TechDocsReaderPageHeaderProps = PropsWithChildren<{\n entityRef?: CompoundEntityRef;\n entityMetadata?: TechDocsEntityMetadata;\n techDocsMetadata?: TechDocsMetadata;\n}>;\n\n/**\n * Renders the reader page header.\n * This component does not accept props, please use\n * the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageHeader = (\n props: TechDocsReaderPageHeaderProps,\n) => {\n const { children } = props;\n const { t } = useTranslationRef(techdocsTranslationRef);\n const {\n title,\n subtitle,\n entityRef,\n entityMetadata,\n tabTitle,\n hidden,\n showSourceLink,\n sourceLink,\n addons,\n } = useTechDocsReaderHeaderData();\n\n const docsRootLink = useRouteRef(rootRouteRef)();\n\n if (hidden) return null;\n\n const { spec } = entityMetadata || {};\n const lifecycle = spec?.lifecycle;\n\n const ownedByRelations = entityMetadata\n ? getEntityRelations(entityMetadata, RELATION_OWNED_BY)\n : [];\n\n const labels = (\n <>\n <HeaderLabel\n label={capitalize(entityMetadata?.kind || 'entity')}\n value={\n <EntityRefLink\n color=\"inherit\"\n entityRef={entityRef}\n defaultKind=\"Component\"\n />\n }\n />\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('readerPageHeader.owner')}\n value={\n <EntityRefLinks\n color=\"inherit\"\n entityRefs={ownedByRelations}\n defaultKind=\"group\"\n />\n }\n />\n )}\n {lifecycle ? (\n <HeaderLabel\n label={t('readerPageHeader.lifecycle')}\n value={String(lifecycle)}\n />\n ) : null}\n {showSourceLink ? (\n <HeaderLabel\n label=\"\"\n value={\n <Grid container direction=\"column\" alignItems=\"center\">\n <Grid style={{ padding: 0 }} item>\n <CodeIcon style={{ marginTop: '-25px' }} />\n </Grid>\n <Grid style={{ padding: 0 }} item>\n {t('readerPageHeader.source')}\n </Grid>\n </Grid>\n }\n url={sourceLink}\n />\n ) : null}\n </>\n );\n\n return (\n <Header\n type=\"Documentation\"\n typeLink={docsRootLink}\n title={title || skeleton}\n subtitle={subtitle === '' ? undefined : subtitle || skeleton}\n >\n <Helmet titleTemplate=\"%s\">\n <title>{tabTitle}</title>\n </Helmet>\n {labels}\n {children}\n {addons.renderComponentsByLocation(locations.Header)}\n </Header>\n );\n};\n","/*\n * Copyright 2024 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 { ReactNode } from 'react';\nimport { ErrorPanel } from '@backstage/core-components';\nimport { useApp } from '@backstage/core-plugin-api';\nimport Button from '@material-ui/core/Button';\nimport { useCookieAuthRefresh } from '../../hooks';\n\n/**\n * @public\n * Props for the {@link CookieAuthRefreshProvider} component.\n */\nexport type CookieAuthRefreshProviderProps = {\n // The plugin ID used for discovering the API origin\n pluginId: string;\n // The children to render when the refresh is successful\n children: ReactNode;\n};\n\n/**\n * @public\n * A provider that will refresh the cookie when it is about to expire.\n */\nexport function CookieAuthRefreshProvider(\n props: CookieAuthRefreshProviderProps,\n): JSX.Element {\n const { children, ...options } = props;\n const app = useApp();\n const { Progress } = app.getComponents();\n\n const result = useCookieAuthRefresh(options);\n\n if (result.status === 'loading') {\n return <Progress />;\n }\n\n if (result.status === 'error') {\n return (\n <ErrorPanel error={result.error}>\n <Button variant=\"outlined\" onClick={result.retry}>\n Retry\n </Button>\n </ErrorPanel>\n );\n }\n\n return <>{children}</>;\n}\n","/*\n * Copyright 2024 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 { useEffect, useCallback, useMemo } from 'react';\nimport {\n discoveryApiRef,\n fetchApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { useAsync, useMountEffect } from '@react-hookz/web';\nimport { ResponseError } from '@backstage/errors';\n\nconst COOKIE_PATH = '/.backstage/auth/v1/cookie';\nconst ONE_YEAR_MS = 365 * 24 * 3600_000;\n\n/**\n * @public\n * A hook that will refresh the cookie when it is about to expire.\n * @param options - Options for configuring the refresh cookie endpoint\n */\nexport function useCookieAuthRefresh(options: {\n // The plugin id used for discovering the API origin\n pluginId: string;\n}):\n | { status: 'loading' }\n | { status: 'error'; error: Error; retry: () => void }\n | { status: 'success'; data: { expiresAt: string } } {\n const { pluginId } = options ?? {};\n const fetchApi = useApi(fetchApiRef);\n const discoveryApi = useApi(discoveryApiRef);\n\n const channel = useMemo(() => {\n return 'BroadcastChannel' in window\n ? new BroadcastChannel(`${pluginId}-auth-cookie-expires-at`)\n : null;\n }, [pluginId]);\n\n const [state, actions] = useAsync<{ expiresAt: string }>(async () => {\n const apiOrigin = await discoveryApi.getBaseUrl(pluginId);\n const requestUrl = `${apiOrigin}${COOKIE_PATH}`;\n const response = await fetchApi.fetch(`${requestUrl}`, {\n credentials: 'include',\n });\n if (!response.ok) {\n // If we get a 404 from the cookie endpoint we assume that it does not\n // exist and cookie auth is not needed. For all active tabs we don't\n // schedule another refresh for the foreseeable future, but new tabs will\n // still check if cookie auth has been added to the deployment.\n // TODO(Rugvip): Once the legacy backend system is no longer supported we should remove this check\n if (response.status === 404) {\n return { expiresAt: new Date(Date.now() + ONE_YEAR_MS) };\n }\n throw await ResponseError.fromResponse(response);\n }\n const data = await response.json();\n if (!data.expiresAt) {\n throw new Error('No expiration date found in response');\n }\n return data;\n });\n\n useMountEffect(actions.execute);\n\n const retry = useCallback(() => {\n actions.execute();\n }, [actions]);\n\n const refresh = useCallback(\n (params: { expiresAt: string }) => {\n // Randomize the refreshing margin with a margin of 1-4 minutes to avoid all tabs refreshing at the same time\n // It cannot be less than 5 minutes otherwise the backend will return the same expiration date\n const margin = (1 + 3 * Math.random()) * 60000;\n const delay = Date.parse(params.expiresAt) - Date.now() - margin;\n const timeout = setTimeout(retry, delay);\n return () => clearTimeout(timeout);\n },\n [retry],\n );\n\n useEffect(() => {\n // Only schedule a refresh if we have a successful response\n if (state.status !== 'success' || !state.result) {\n return () => {};\n }\n channel?.postMessage({\n action: 'COOKIE_REFRESH_SUCCESS',\n payload: state.result,\n });\n let cancel = refresh(state.result);\n const listener = (\n event: MessageEvent<{ action: string; payload: { expiresAt: string } }>,\n ) => {\n const { action, payload } = event.data;\n if (action === 'COOKIE_REFRESH_SUCCESS') {\n cancel();\n cancel = refresh(payload);\n }\n };\n channel?.addEventListener('message', listener);\n return () => {\n cancel();\n channel?.removeEventListener('message', listener);\n };\n }, [state, refresh, channel]);\n\n // Initialising\n if (state.status === 'not-executed') {\n return { status: 'loading' };\n }\n\n // First refresh or retrying without any success before\n // Possible state transitions:\n // e.g. not-executed -> loading (first-refresh)\n // e.g. not-executed -> loading (first-refresh) -> error -> loading (manual-retry)\n if (state.status === 'loading' && !state.result) {\n return { status: 'loading' };\n }\n\n // Retrying after having succeeding at least once\n // Current state is: { status: 'loading', result: {...}, error: undefined | Error }\n // e.g. not-executed -> loading (first-refresh) -> success -> loading (scheduled-refresh) -> error -> loading (manual-retry)\n if (state.status === 'loading' && state.error) {\n return { status: 'loading' };\n }\n\n // Something went wrong during any situation of a refresh\n if (state.status === 'error' && state.error) {\n return { status: 'error', error: state.error, retry };\n }\n\n // At this point it should be safe to assume that we have a successful refresh\n return { status: 'success', data: state.result! };\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 { Children, ReactElement, ReactNode, useMemo } from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport { Page, Progress } from '@backstage/core-components';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n TECHDOCS_ADDONS_KEY,\n TECHDOCS_ADDONS_WRAPPER_KEY,\n TechDocsReaderPageProvider,\n} from '@backstage/plugin-techdocs-react';\nimport { TechDocsReaderPageRenderFunction } from '../../../types';\nimport { TechDocsReaderPageContent } from '../TechDocsReaderPageContent';\nimport { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader';\nimport { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader';\nimport { rootDocsRouteRef } from '../../../routes';\nimport {\n getComponentData,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { CookieAuthRefreshProvider } from '@backstage/plugin-auth-react';\nimport {\n createTheme,\n styled,\n ThemeOptions,\n ThemeProvider,\n useTheme,\n} from '@material-ui/core/styles';\nimport { useExternalRedirect } from './useExternalRedirect';\n\n/* An explanation for the multiple ways of customizing the TechDocs reader page\n\nPlease refer to this page on the microsite for the latest recommended approach:\nhttps://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-reader-page\n\nThe <TechDocsReaderPage> component is responsible for rendering the <TechDocsReaderPageProvider> and\nits contained version of a <Page>, which in turn renders the <TechDocsReaderPageContent>.\n\nHistorically, there have been different approaches on how this <Page> can be customized, and how the\n<TechDocsReaderPageContent> inside could be exchanged for a custom implementation (which was not\npossible before). Also, the current implementation supports every scenario to avoid breaking default\nconfigurations of TechDocs.\n\nIn particular, there are 4 different TechDocs page configurations:\n\nCONFIGURATION 1: <TechDocsReaderPage> only, no children\n\n<Route path=\"/docs/:namespace/:kind/:name/*\" element={<TechDocsReaderPage />} >\n\nThis is the simplest way to use TechDocs. Only a full page is passed, assuming that it comes with\nits content inside. Since we allowed customizing it, we started providing <TechDocsReaderLayout> as\na default implementation (which contains <TechDocsReaderPageContent>).\n\nCONFIGURATION 2 (not advised): <TechDocsReaderPage> with element children\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {techdocsPage}\n </TechDocsReaderPage>\n }\n/>\n\nPreviously, there were two ways of passing children to <TechDocsReaderPage>: either as elements (as\nshown above), or as a render function (described below in CONFIGURATION 3). The \"techdocsPage\" is\nlocated in packages/app/src/components/techdocs and is the default implementation of the content\ninside.\n\nCONFIGURATION 3 (not advised): <TechDocsReaderPage> with render function as child\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {({ metadata, entityMetadata, onReady }) => (\n techdocsPage\n )}\n </TechDocsReaderPage>\n }\n/>\n\nSimilar to CONFIGURATION 2, the direct children will be passed to the <TechDocsReaderPage> but in\nthis case interpreted as render prop.\n\nCONFIGURATION 4: <TechDocsReaderPage> and provided content in <Route>\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n>\n {techDocsPage}\n <TechDocsAddons>\n <ExpandableNavigation />\n <ReportIssue />\n <TextSize />\n <LightBox />\n </TechDocsAddons>\n</Route>\n\nThis is the current state in packages/app/src/App.tsx and moved the location of children from inside\nthe element prop in the <Route> to the children of the <Route>. Then, in <TechDocsReaderPage> they\nare retrieved using the useOutlet hook from React Router.\n\nNOTE: Render functions are no longer supported in this approach.\n*/\n\n/**\n * Props for {@link TechDocsReaderLayout}\n * @public\n */\nexport type TechDocsReaderLayoutProps = {\n /**\n * Show or hide the header, defaults to true.\n */\n withHeader?: boolean;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\n/**\n * Default TechDocs reader page structure composed with a header and content\n * @public\n */\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <Page themeId=\"documentation\">\n {withHeader && <TechDocsReaderPageHeader />}\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent withSearch={withSearch} />\n </Page>\n );\n};\n\n/**\n * @public\n */\nexport type TechDocsReaderPageProps = {\n entityRef?: CompoundEntityRef;\n children?: TechDocsReaderPageRenderFunction | ReactNode;\n overrideThemeOptions?: Partial<ThemeOptions>;\n};\n\n/**\n * Styled Backstage Page that fills available vertical space\n */\nconst StyledPage = styled(Page)({\n height: 'inherit',\n overflowY: 'visible',\n});\n\n/**\n * An addon-aware implementation of the TechDocsReaderPage.\n *\n * @public\n */\nexport const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {\n const currentTheme = useTheme();\n\n const readerPageTheme = useMemo(\n () =>\n createTheme({\n ...currentTheme,\n ...(props.overrideThemeOptions || {}),\n }),\n [currentTheme, props.overrideThemeOptions],\n );\n\n const { kind, name, namespace } = useRouteRefParams(rootDocsRouteRef);\n const { children, entityRef = { kind, name, namespace } } = props;\n\n const outlet = useOutlet();\n\n const memoizedEntityRef = useMemo(\n () => ({\n kind: entityRef.kind,\n name: entityRef.name,\n namespace: entityRef.namespace,\n }),\n [entityRef.kind, entityRef.name, entityRef.namespace],\n );\n\n // Check for external TechDocs redirects and handle navigation\n const { shouldShowProgress } = useExternalRedirect(memoizedEntityRef);\n\n const page: ReactNode = useMemo(() => {\n if (children) {\n return null;\n }\n\n const childrenList = outlet ? Children.toArray(outlet.props.children) : [];\n\n const grandChildren = childrenList.flatMap<ReactElement>(\n child => (child as ReactElement)?.props?.children ?? [],\n );\n\n return grandChildren.find(\n grandChild =>\n !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&\n !getComponentData(grandChild, TECHDOCS_ADDONS_KEY),\n );\n }, [children, outlet]);\n\n // Show full-page loading spinner when checking for external redirects or about to redirect.\n // This replaces the entire page content (header, sidebar, and documentation).\n if (shouldShowProgress) {\n return <Progress />;\n }\n\n // As explained above, \"page\" is configuration 4 and <TechDocsReaderLayout> is 1\n if (!children) {\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {(page as JSX.Element) || <TechDocsReaderLayout />}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n }\n\n // As explained above, a render function is configuration 3 and React element is 2\n return (\n <ThemeProvider theme={readerPageTheme}>\n <CookieAuthRefreshProvider pluginId=\"techdocs\">\n <TechDocsReaderPageProvider entityRef={memoizedEntityRef}>\n {({ metadata, entityMetadata, onReady }) => (\n <StyledPage\n themeId=\"documentation\"\n className=\"techdocs-reader-page\"\n >\n {children instanceof Function\n ? children({\n entityRef: memoizedEntityRef,\n techdocsMetadataValue: metadata.value,\n entityMetadataValue: entityMetadata.value,\n onReady,\n })\n : children}\n </StyledPage>\n )}\n </TechDocsReaderPageProvider>\n </CookieAuthRefreshProvider>\n </ThemeProvider>\n );\n};\n","/*\n * Copyright 2025 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 { useEffect, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport {\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\nimport { TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport { rootDocsRouteRef } from '../../../routes';\n\n/**\n * Hook to handle external TechDocs redirects based on entity annotations.\n * Checks if an entity has the `backstage.io/techdocs-entity` annotation and\n * redirects to the external TechDocs URL if present.\n *\n * @param entityRef - The entity reference to check for external redirects\n * @returns Object containing loading state and whether a redirect is in progress\n *\n * @internal\n */\nexport function useExternalRedirect(entityRef: CompoundEntityRef): {\n loading: boolean;\n shouldShowProgress: boolean;\n} {\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const viewTechdocLink = useRouteRef(rootDocsRouteRef);\n\n // Create a stable string key for the entity to use as a dependency.\n // This ensures the useAsync hook only re-runs when the entity changes,\n // preventing redundant API calls during sub-page navigation within the same entity's documentation.\n const entityKey = stringifyEntityRef(entityRef);\n // Track which entity we've already checked to avoid redundant checks\n // when navigating between pages within the same entity's documentation.\n const checkedEntityRef = useRef<string | null>(null);\n const shouldCheckForRedirect = checkedEntityRef.current !== entityKey;\n\n // Check if this entity should redirect to external TechDocs\n const externalRedirectResult = useAsync(async () => {\n try {\n const catalogEntity = await catalogApi.getEntityByRef(entityRef);\n\n if (\n catalogEntity?.metadata?.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) {\n return buildTechDocsURL(catalogEntity, viewTechdocLink);\n }\n } catch (error) {\n // Ignore errors and allow the current entity's TechDocs to load.\n // This handles cases where the catalog API is unavailable or the entity doesn't exist.\n }\n\n return undefined;\n }, [entityKey, catalogApi]);\n\n useEffect(() => {\n // Navigate to external TechDocs if a redirect URL is available\n if (!externalRedirectResult.loading && externalRedirectResult.value) {\n navigate(externalRedirectResult.value, { replace: true });\n }\n\n // Mark entity as checked once we've determined there's no redirect needed.\n // This prevents the entire page from unmounting/remounting (showing Progress spinner)\n // on subsequent sub-page navigation within the same entity.\n if (!externalRedirectResult.loading && !externalRedirectResult.value) {\n checkedEntityRef.current = entityKey;\n }\n }, [\n externalRedirectResult.loading,\n externalRedirectResult.value,\n navigate,\n entityKey,\n ]);\n\n // Determine if we should show a loading indicator (which replaces the entire page with a Progress spinner).\n // Only show it when: 1) checking a new/unchecked entity, or 2) we have a redirect URL and are navigating.\n const shouldShowProgress =\n (shouldCheckForRedirect && externalRedirectResult.loading) ||\n !!externalRedirectResult.value;\n\n return {\n loading: externalRedirectResult.loading,\n shouldShowProgress,\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 { ChangeEvent, useCallback, useMemo } from 'react';\n\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Autocomplete, {\n AutocompleteProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\nimport {\n AutocompleteChangeDetails,\n AutocompleteChangeReason,\n} from '@material-ui/lab/useAutocomplete';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { SearchBar, SearchBarProps } from '../SearchBar';\n\nconst useStyles = makeStyles(theme => ({\n loading: {\n right: theme.spacing(1),\n position: 'absolute',\n },\n}));\n\n/**\n * Props for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteProps<Option> = Omit<\n AutocompleteProps<Option, undefined, undefined, boolean>,\n 'renderInput' | 'disableClearable' | 'multiple'\n> & {\n 'data-testid'?: string;\n inputPlaceholder?: SearchBarProps['placeholder'];\n inputDebounceTime?: SearchBarProps['debounceTime'];\n};\n\n/**\n * Type for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteComponent = <Option>(\n props: SearchAutocompleteProps<Option>,\n) => JSX.Element;\n\nconst withContext = (\n Component: SearchAutocompleteComponent,\n): SearchAutocompleteComponent => {\n return props => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} />\n </SearchContextProvider>\n );\n};\n\nconst SearchAutocompleteLoadingAdornment = () => {\n const classes = useStyles();\n return (\n <CircularProgress\n className={classes.loading}\n data-testid=\"search-autocomplete-progressbar\"\n color=\"inherit\"\n size={20}\n />\n );\n};\n\n/**\n * Recommended search autocomplete when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchAutocomplete = withContext(\n function SearchAutocompleteComponent<Option>(\n props: SearchAutocompleteProps<Option>,\n ) {\n const {\n loading,\n value,\n onChange = () => {},\n options = [],\n getOptionLabel = (option: Option) => String(option),\n inputPlaceholder,\n inputDebounceTime,\n freeSolo = true,\n fullWidth = true,\n clearOnBlur = false,\n 'data-testid': dataTestId = 'search-autocomplete',\n ...rest\n } = props;\n\n const { setTerm } = useSearch();\n\n const getInputValue = useCallback(\n (option?: null | string | Option) => {\n if (!option) return '';\n if (typeof option === 'string') return option;\n return getOptionLabel(option);\n },\n [getOptionLabel],\n );\n\n const inputValue = useMemo(\n () => getInputValue(value),\n [value, getInputValue],\n );\n\n const handleChange = useCallback(\n (\n event: ChangeEvent<{}>,\n option: null | string | Option,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<Option>,\n ) => {\n setTerm(getInputValue(option));\n onChange(event, option, reason, details);\n },\n [getInputValue, setTerm, onChange],\n );\n\n const renderInput = useCallback(\n ({\n InputProps: { ref, className, endAdornment },\n InputLabelProps,\n ...params\n }: AutocompleteRenderInputParams) => (\n <SearchBar\n {...params}\n ref={ref}\n clearButton={false}\n value={inputValue}\n placeholder={inputPlaceholder}\n debounceTime={inputDebounceTime}\n endAdornment={\n loading ? <SearchAutocompleteLoadingAdornment /> : endAdornment\n }\n InputProps={{ className }}\n />\n ),\n [loading, inputValue, inputPlaceholder, inputDebounceTime],\n );\n\n return (\n <Autocomplete\n {...rest}\n data-testid={dataTestId}\n value={value}\n onChange={handleChange}\n options={options}\n getOptionLabel={getOptionLabel}\n renderInput={renderInput}\n freeSolo={freeSolo}\n fullWidth={fullWidth}\n clearOnBlur={clearOnBlur}\n />\n );\n },\n);\n","/*\n * Copyright 2025 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 { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * @public\n */\nexport const searchReactTranslationRef = createTranslationRef({\n id: 'search-react',\n messages: {\n searchBar: {\n title: 'Search',\n placeholder: 'Search in {{org}}',\n clearButtonTitle: 'Clear',\n },\n searchFilter: {\n allOptionTitle: 'All',\n },\n searchPagination: {\n limitLabel: 'Results per page:',\n limitText: 'of {{num}}',\n },\n noResultsDescription: 'Sorry, no results were found',\n searchResultGroup: {\n linkTitle: 'See All',\n addFilterButtonTitle: 'Add filter',\n },\n searchResultPager: {\n previous: 'Previous',\n next: 'Next',\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 {\n AnalyticsContext,\n configApiRef,\n useApi,\n useApp,\n} from '@backstage/core-plugin-api';\nimport IconButton from '@material-ui/core/IconButton';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport TextField from '@material-ui/core/TextField';\nimport Button from '@material-ui/core/Button';\nimport { TextFieldProps } from '@material-ui/core/TextField';\nimport DefaultSearchIcon from '@material-ui/icons/Search';\nimport {\n ReactNode,\n ChangeEvent,\n forwardRef,\n KeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { searchReactTranslationRef } from '../../translation';\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<TextFieldProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n endAdornment?: ReactNode;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase = forwardRef((props: SearchBarBaseProps, ref) => {\n const {\n onChange,\n onKeyDown = () => {},\n onClear = () => {},\n onSubmit = () => {},\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n label,\n placeholder,\n inputProps = {},\n InputProps = {},\n endAdornment,\n ...rest\n } = props;\n\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>('');\n const forwardedValueRef = useRef<string>('');\n const { t } = useTranslationRef(searchReactTranslationRef);\n\n useEffect(() => {\n setValue(prevValue => {\n // We only update the value if our current value is the same as it was\n // for the most recent onChange call. Otherwise it means that the users\n // has continued typing and we should not replace their input.\n if (prevValue === forwardedValueRef.current) {\n return String(defaultValue);\n }\n return prevValue;\n });\n }, [defaultValue, forwardedValueRef]);\n\n useDebounce(\n () => {\n forwardedValueRef.current = value;\n onChange(value);\n },\n debounceTime,\n [value],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n forwardedValueRef.current = '';\n onChange('');\n setValue('');\n if (onClear) {\n onClear();\n }\n }, [onChange, onClear]);\n\n const ariaLabel: string | undefined = label\n ? undefined\n : t('searchBar.title');\n\n const inputPlaceholder =\n placeholder ??\n t('searchBar.placeholder', {\n org: configApi.getOptionalString('app.title') || 'Backstage',\n });\n const SearchIcon = useApp().getSystemIcon('search') || DefaultSearchIcon;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" size=\"small\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const clearButtonEndAdornment = (\n <InputAdornment position=\"end\">\n <Button\n aria-label={t('searchBar.clearButtonTitle')}\n size=\"small\"\n onClick={handleClear}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n // write your functionality here\n event.stopPropagation();\n }\n }}\n >\n {t('searchBar.clearButtonTitle')}\n </Button>\n </InputAdornment>\n );\n\n return (\n <SearchContextProvider inheritParentContextIfAvailable>\n <TextField\n id=\"search-bar-text-field\"\n data-testid=\"search-bar-next\"\n variant=\"outlined\"\n margin=\"normal\"\n inputRef={ref}\n value={value}\n label={label}\n placeholder={inputPlaceholder}\n InputProps={{\n startAdornment,\n endAdornment: clearButton ? clearButtonEndAdornment : endAdornment,\n ...InputProps,\n }}\n inputProps={{\n 'aria-label': ariaLabel,\n ...inputProps,\n }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...rest}\n />\n </SearchContextProvider>\n );\n});\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar = forwardRef((props: SearchBarProps, ref) => {\n const { value: initialValue = '', onChange, ...rest } = props;\n\n const { term, setTerm } = useSearch();\n\n useEffect(() => {\n if (initialValue) {\n setTerm(String(initialValue));\n }\n }, [initialValue, setTerm]);\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n } else {\n setTerm(newValue);\n }\n },\n [onChange, setTerm],\n );\n\n return (\n <SearchContextProvider inheritParentContextIfAvailable>\n <AnalyticsContext\n attributes={{ pluginId: 'search', extension: 'SearchBar' }}\n >\n <SearchBarBase\n {...rest}\n ref={ref}\n value={term}\n onChange={handleChange}\n />\n </AnalyticsContext>\n </SearchContextProvider>\n );\n});\n","/*\n * Copyright 2021 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 { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n SearchAutocomplete,\n SearchContextProvider,\n} from '@backstage/plugin-search-react';\nimport { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\nimport { TechDocsSearchResultListItem } from './TechDocsSearchResultListItem';\nimport {\n useTechDocsSearch,\n TechDocsSearchResult,\n} from '../../hooks/useTechDocsSearch';\n\n/**\n * Props for {@link TechDocsSearch}\n *\n * @public\n */\nexport type TechDocsSearchProps = {\n entityId: CompoundEntityRef;\n entityTitle?: string;\n debounceTime?: number;\n searchResultUrlMapper?: (url: string) => string;\n};\n\nconst isTechDocsSearchResult = (\n option: any,\n): option is TechDocsSearchResult => {\n return option?.document;\n};\n\nconst TechDocsSearchBar = (props: TechDocsSearchProps) => {\n const {\n entityId,\n entityTitle,\n debounceTime = 150,\n searchResultUrlMapper,\n } = props;\n const [open, setOpen] = useState(false);\n const navigate = useNavigate();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const { results, term, loading } = useTechDocsSearch(entityId);\n\n const handleSelection = (\n _: any,\n selection: TechDocsSearchResult | string | null,\n ) => {\n if (isTechDocsSearchResult(selection)) {\n const { location } = selection.document;\n navigate(\n searchResultUrlMapper ? searchResultUrlMapper(location) : location,\n );\n }\n };\n\n return (\n <SearchAutocomplete\n data-testid=\"techdocs-search-bar\"\n size=\"small\"\n open={open && Boolean(term)}\n getOptionLabel={() => ''}\n filterOptions={x => {\n return x; // This is needed to get renderOption to be called after options change. Bug in material-ui?\n }}\n onClose={() => {\n setOpen(false);\n }}\n onOpen={() => {\n setOpen(true);\n }}\n onChange={handleSelection}\n blurOnSelect\n noOptionsText={t('search.noResults')}\n value={null}\n options={results}\n renderOption={({ document, highlight }) => (\n <TechDocsSearchResultListItem\n result={document}\n lineClamp={3}\n asListItem={false}\n asLink={false}\n title={document.title}\n highlight={highlight}\n />\n )}\n loading={loading}\n inputDebounceTime={debounceTime}\n inputPlaceholder={t('search.placeholder', {\n entityTitle: entityTitle || entityId.name,\n })}\n freeSolo={false}\n />\n );\n};\n\n/**\n * Component used to render search bar on TechDocs page, scoped to\n *\n * @public\n */\nexport const TechDocsSearch = (props: TechDocsSearchProps) => {\n const initialState = {\n term: '',\n types: ['techdocs'],\n pageCursor: '',\n filters: props.entityId,\n };\n return (\n <SearchContextProvider initialState={initialState}>\n <TechDocsSearchBar {...props} />\n </SearchContextProvider>\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 Grid from '@material-ui/core/Grid';\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { TechDocsShadowDom } from '@backstage/plugin-techdocs-react';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { Content, Progress } from '@backstage/core-components';\n\nimport { TechDocsSearch } from '../../../search';\nimport { TechDocsStateIndicator } from '../TechDocsStateIndicator';\n\nimport { withTechDocsReaderProvider } from '../TechDocsReaderProvider';\nimport { TechDocsReaderPageContentAddons } from './TechDocsReaderPageContentAddons';\nimport { useTechDocsReaderContentData } from '../../../hooks/useTechDocsReaderContentData';\n\nconst useStyles = makeStyles({\n search: {\n width: '100%',\n '@media (min-width: 76.1875em)': {\n width: 'calc(100% - 34.4rem)',\n margin: '0 auto',\n },\n '@media print': {\n display: 'none',\n },\n },\n});\n\n/**\n * Props for {@link TechDocsReaderPageContent}\n * @public\n */\nexport type TechDocsReaderPageContentProps = {\n /**\n * @deprecated No need to pass down entityRef as property anymore. Consumes the entityName from `TechDocsReaderPageContext`. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom reader page content.\n */\n entityRef?: CompoundEntityRef;\n /**\n * Path in the docs to render by default. This should be used when rendering docs for an entity that specifies the\n * \"backstage.io/techdocs-entity-path\" annotation for deep linking into another entities docs.\n */\n defaultPath?: string;\n /**\n * Show or hide the search bar, defaults to true.\n */\n withSearch?: boolean;\n /**\n * If {@link TechDocsReaderPageContentProps.withSearch | withSearch} is true,\n * this will redirect the search result urls, e.g. turn search results into\n * links within the \"Docs\" tab of the entity page, instead of the global docs\n * page.\n */\n searchResultUrlMapper?: (url: string) => string;\n /**\n * Callback called when the content is rendered.\n */\n onReady?: () => void;\n};\n\n/**\n * Renders the reader page content\n * @public\n */\nexport const TechDocsReaderPageContent = withTechDocsReaderProvider(\n (props: TechDocsReaderPageContentProps) => {\n const { withSearch = true, searchResultUrlMapper } = props;\n const classes = useStyles();\n\n const {\n entityRef,\n entityMetadata,\n dom,\n handleAppend,\n isNotFound,\n isDomReady,\n showProgress,\n NotFoundErrorPage,\n } = useTechDocsReaderContentData({\n defaultPath: props.defaultPath,\n onReady: props.onReady,\n });\n\n if (isNotFound) return <NotFoundErrorPage />;\n\n if (!isDomReady) {\n return (\n <Content>\n <Grid container>\n <Grid xs={12} item>\n <TechDocsStateIndicator />\n </Grid>\n </Grid>\n </Content>\n );\n }\n\n return (\n <Content>\n <Grid container>\n <Grid xs={12} item>\n <TechDocsStateIndicator />\n </Grid>\n {withSearch && (\n <Grid className={classes.search} xs=\"auto\" item>\n <TechDocsSearch\n entityId={entityRef}\n entityTitle={entityMetadata?.metadata?.title}\n searchResultUrlMapper={searchResultUrlMapper}\n />\n </Grid>\n )}\n <Grid xs={12} item>\n {showProgress && <Progress />}\n\n <TechDocsShadowDom element={dom!} onAppend={handleAppend}>\n <TechDocsReaderPageContentAddons />\n </TechDocsShadowDom>\n </Grid>\n </Grid>\n </Content>\n );\n },\n);\n\n/**\n * Props for {@link Reader}\n *\n * @public\n * @deprecated use `TechDocsReaderPageContentProps` instead.\n */\nexport type ReaderProps = TechDocsReaderPageContentProps;\n\n/**\n * Component responsible for rendering TechDocs documentation\n * @public\n * @deprecated use `TechDocsReaderPageContent` component instead.\n */\nexport const Reader = TechDocsReaderPageContent;\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 Portal from '@material-ui/core/Portal';\nimport {\n useTechDocsAddons,\n TechDocsAddonLocations as locations,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\n\nexport const TechDocsReaderPageContentAddons = () => {\n const addons = useTechDocsAddons();\n\n const { shadowRoot } = useTechDocsReaderPage();\n\n const contentElement = shadowRoot?.querySelector(\n '[data-md-component=\"content\"]',\n );\n\n const primarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"navigation\"], div[data-md-component=\"navigation\"]',\n );\n let primarySidebarAddonLocation = primarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"primary sidebar\"]',\n );\n if (!primarySidebarAddonLocation) {\n primarySidebarAddonLocation = document.createElement('div');\n primarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'primary sidebar',\n );\n primarySidebarElement?.prepend(primarySidebarAddonLocation);\n }\n\n const secondarySidebarElement = shadowRoot?.querySelector(\n 'div[data-md-component=\"sidebar\"][data-md-type=\"toc\"], div[data-md-component=\"toc\"]',\n );\n let secondarySidebarAddonLocation = secondarySidebarElement?.querySelector(\n '[data-techdocs-addons-location=\"secondary sidebar\"]',\n );\n if (!secondarySidebarAddonLocation) {\n secondarySidebarAddonLocation = document.createElement('div');\n secondarySidebarAddonLocation.setAttribute(\n 'data-techdocs-addons-location',\n 'secondary sidebar',\n );\n secondarySidebarElement?.prepend(secondarySidebarAddonLocation);\n }\n\n return (\n <>\n <Portal container={primarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.PrimarySidebar)}\n </Portal>\n <Portal container={contentElement}>\n {addons.renderComponentsByLocation(locations.Content)}\n </Portal>\n <Portal container={secondarySidebarAddonLocation}>\n {addons.renderComponentsByLocation(locations.SecondarySidebar)}\n </Portal>\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 { MouseEvent, useState, useCallback } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport IconButton from '@material-ui/core/IconButton';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport { ToolbarProps } from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Menu from '@material-ui/core/Menu';\nimport Box from '@material-ui/core/Box';\nimport SettingsIcon from '@material-ui/icons/Settings';\n\nimport {\n TechDocsAddonLocations as locations,\n useTechDocsAddons,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageSubheader',\n flexDirection: 'column',\n minHeight: 'auto',\n padding: theme.spacing(3, 3, 0),\n '@media print': {\n display: 'none',\n },\n },\n}));\n\n/**\n * Renders the reader page subheader.\n * Please use the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageSubheader = (props: {\n toolbarProps?: ToolbarProps;\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const handleClick = useCallback((event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n }, []);\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const {\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n const addons = useTechDocsAddons();\n\n const subheaderAddons = addons.renderComponentsByLocation(\n locations.Subheader,\n );\n\n const settingsAddons = addons.renderComponentsByLocation(locations.Settings);\n\n if (!subheaderAddons && !settingsAddons) return null;\n\n // No entity metadata = 404. Don't render subheader on 404.\n if (entityMetadataLoading === false && !entityMetadata) return null;\n\n return (\n <Toolbar classes={classes} {...props.toolbarProps}>\n <Box\n display=\"flex\"\n justifyContent=\"flex-end\"\n width=\"100%\"\n flexWrap=\"wrap\"\n >\n {subheaderAddons}\n {settingsAddons ? (\n <>\n <Tooltip title={t('reader.settings')}>\n <IconButton\n aria-controls=\"tech-docs-reader-page-settings\"\n aria-haspopup=\"true\"\n onClick={handleClick}\n >\n <SettingsIcon />\n </IconButton>\n </Tooltip>\n <Menu\n id=\"tech-docs-reader-page-settings\"\n getContentAnchorEl={null}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n open={Boolean(anchorEl)}\n onClose={handleClose}\n keepMounted\n >\n <div>{settingsAddons}</div>\n </Menu>\n </>\n ) : null}\n </Box>\n </Toolbar>\n );\n};\n","/*\n * Copyright 2021 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 { useApi } from '@backstage/core-plugin-api';\nimport { useMemo, useReducer, useRef } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport useAsyncRetry from 'react-use/esm/useAsyncRetry';\nimport { techdocsStorageApiRef } from '@backstage/plugin-techdocs-react';\n\n/**\n * @public\n * A state representation that is used to configure the UI of <Reader />\n */\nexport type ContentStateTypes =\n /** There is nothing to display but a loading indicator */\n | 'CHECKING'\n\n /** There is no content yet -> present a full screen loading page */\n | 'INITIAL_BUILD'\n\n /** There is content, but the backend is about to update it */\n | 'CONTENT_STALE_REFRESHING'\n\n /** There is content, but after a reload, the content will be different */\n | 'CONTENT_STALE_READY'\n\n /** There is content, the backend tried to update it, but failed */\n | 'CONTENT_STALE_ERROR'\n\n /** There is nothing to see but a \"not found\" page. Is also shown on page load errors */\n | 'CONTENT_NOT_FOUND'\n\n /** There is only the latest and greatest content */\n | 'CONTENT_FRESH';\n\n/**\n * Calculate the state that should be reported to the display component.\n */\nexport function calculateDisplayState({\n contentLoading,\n content,\n activeSyncState,\n}: Pick<\n ReducerState,\n 'contentLoading' | 'content' | 'activeSyncState'\n>): ContentStateTypes {\n // we have nothing to display yet\n if (contentLoading) {\n return 'CHECKING';\n }\n\n // the build is ready, but it triggered a content reload and the content variable is not trusted\n if (activeSyncState === 'BUILD_READY_RELOAD') {\n return 'CHECKING';\n }\n\n // there is no content, but the sync process is still evaluating\n if (!content && activeSyncState === 'CHECKING') {\n return 'CHECKING';\n }\n\n // there is no content yet so we assume that we are building it for the first time\n if (!content && activeSyncState === 'BUILDING') {\n return 'INITIAL_BUILD';\n }\n\n // if there is still no content after building, it might just not exist\n if (!content) {\n return 'CONTENT_NOT_FOUND';\n }\n\n // we are still building, but we already show stale content\n if (activeSyncState === 'BUILDING') {\n return 'CONTENT_STALE_REFRESHING';\n }\n\n // the build is ready, but the content is still stale\n if (activeSyncState === 'BUILD_READY') {\n return 'CONTENT_STALE_READY';\n }\n\n // the build failed, but the content is still stale\n if (activeSyncState === 'ERROR') {\n return 'CONTENT_STALE_ERROR';\n }\n\n // seems like the content is up-to-date (or we don't know yet and the sync process is still evaluating in the background)\n return 'CONTENT_FRESH';\n}\n\n/**\n * The state of the synchronization task. It checks whether the docs are\n * up-to-date. If they aren't, it triggers a build.\n */\ntype SyncStates =\n /** Checking if it should be synced */\n | 'CHECKING'\n\n /** Building the documentation */\n | 'BUILDING'\n\n /** Finished building the documentation */\n | 'BUILD_READY'\n\n /**\n * Finished building the documentation and triggered a content reload.\n * This state is left toward UP_TO_DATE when the content loading has finished.\n */\n | 'BUILD_READY_RELOAD'\n\n /** No need for a sync. The content was already up-to-date. */\n | 'UP_TO_DATE'\n\n /** An error occurred */\n | 'ERROR';\n\ntype ReducerActions =\n | {\n type: 'sync';\n state: SyncStates;\n syncError?: Error;\n }\n | { type: 'contentLoading' }\n | {\n type: 'content';\n path?: string;\n content?: string;\n contentError?: Error;\n }\n | { type: 'buildLog'; log: string };\n\ntype ReducerState = {\n /**\n * The path of the current page\n */\n path: string;\n\n /**\n * The current sync state\n */\n activeSyncState: SyncStates;\n\n /**\n * If true, the content is downloading from the storage.\n */\n contentLoading: boolean;\n /**\n * The content that has been downloaded and should be displayed.\n */\n content?: string;\n\n contentError?: Error;\n syncError?: Error;\n\n /**\n * A list of log messages that were emitted by the build process.\n */\n buildLog: string[];\n};\n\nexport function reducer(\n oldState: ReducerState,\n action: ReducerActions,\n): ReducerState {\n const newState = { ...oldState };\n\n switch (action.type) {\n case 'sync':\n // reset the build log when a new check starts\n if (action.state === 'CHECKING') {\n newState.buildLog = [];\n }\n\n newState.activeSyncState = action.state;\n newState.syncError = action.syncError;\n break;\n\n case 'contentLoading':\n newState.contentLoading = true;\n\n // only reset errors but keep the old content until it is replaced by the 'content' action\n newState.contentError = undefined;\n break;\n\n case 'content':\n // only override the path if it is part of the action\n if (typeof action.path === 'string') {\n newState.path = action.path;\n }\n\n newState.contentLoading = false;\n newState.content = action.content;\n newState.contentError = action.contentError;\n break;\n\n case 'buildLog':\n newState.buildLog = newState.buildLog.concat(action.log);\n break;\n\n default:\n throw new Error();\n }\n\n // a content update loads fresh content so the build is updated to being up-to-date\n if (\n ['BUILD_READY', 'BUILD_READY_RELOAD'].includes(newState.activeSyncState) &&\n ['contentLoading', 'content'].includes(action.type)\n ) {\n newState.activeSyncState = 'UP_TO_DATE';\n newState.buildLog = [];\n }\n\n return newState;\n}\n/**\n * @public shared reader state\n */\nexport type ReaderState = {\n state: ContentStateTypes;\n path: string;\n contentReload: () => void;\n content?: string;\n contentErrorMessage?: string;\n syncErrorMessage?: string;\n buildLog: string[];\n};\n\nexport function useReaderState(\n kind: string,\n namespace: string,\n name: string,\n path: string,\n): ReaderState {\n const [state, dispatch] = useReducer(reducer, {\n activeSyncState: 'CHECKING',\n path,\n contentLoading: true,\n buildLog: [],\n });\n\n const techdocsStorageApi = useApi(techdocsStorageApiRef);\n\n // try to load the content. the function will fire events and we don't care for the return values\n const { retry: contentReload } = useAsyncRetry(async () => {\n dispatch({ type: 'contentLoading' });\n\n try {\n const entityDocs = await techdocsStorageApi.getEntityDocs(\n { kind, namespace, name },\n path,\n );\n\n // update content and path at the same time\n dispatch({ type: 'content', content: entityDocs, path });\n\n return entityDocs;\n } catch (e) {\n dispatch({ type: 'content', contentError: e, path });\n }\n\n return undefined;\n }, [techdocsStorageApi, kind, namespace, name, path]);\n\n // create a ref that holds the latest content. This provides a useAsync hook\n // with the latest content without restarting the useAsync hook.\n const contentRef = useRef<{ content?: string; reload: () => void }>({\n content: undefined,\n reload: () => {},\n });\n contentRef.current = { content: state.content, reload: contentReload };\n\n // try to derive the state. the function will fire events and we don't care for the return values\n useAsync(async () => {\n dispatch({ type: 'sync', state: 'CHECKING' });\n\n // should only switch to BUILDING if the request takes more than 1 seconds\n const buildingTimeout = setTimeout(() => {\n dispatch({ type: 'sync', state: 'BUILDING' });\n }, 1000);\n\n try {\n const result = await techdocsStorageApi.syncEntityDocs(\n {\n kind,\n namespace,\n name,\n },\n log => {\n dispatch({ type: 'buildLog', log });\n },\n );\n\n switch (result) {\n case 'updated':\n // if there was no content prior to building, retry the loading\n if (!contentRef.current.content) {\n contentRef.current.reload();\n dispatch({ type: 'sync', state: 'BUILD_READY_RELOAD' });\n } else {\n dispatch({ type: 'sync', state: 'BUILD_READY' });\n }\n break;\n case 'cached':\n dispatch({ type: 'sync', state: 'UP_TO_DATE' });\n break;\n\n default:\n dispatch({\n type: 'sync',\n state: 'ERROR',\n syncError: new Error('Unexpected return state'),\n });\n break;\n }\n } catch (e) {\n dispatch({ type: 'sync', state: 'ERROR', syncError: e });\n } finally {\n // Cancel the timer that sets the state \"BUILDING\"\n clearTimeout(buildingTimeout);\n }\n }, [kind, name, namespace, techdocsStorageApi, dispatch, contentRef]);\n\n const displayState = useMemo(\n () =>\n calculateDisplayState({\n activeSyncState: state.activeSyncState,\n contentLoading: state.contentLoading,\n content: state.content,\n }),\n [state.activeSyncState, state.content, state.contentLoading],\n );\n\n return useMemo(\n () => ({\n state: displayState,\n contentReload,\n path: state.path,\n content: state.content,\n contentErrorMessage: state.contentError?.toString(),\n syncErrorMessage: state.syncError?.toString(),\n buildLog: state.buildLog,\n }),\n [\n displayState,\n contentReload,\n state.path,\n state.content,\n state.contentError,\n state.syncError,\n state.buildLog,\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 { ComponentType, createContext, useContext, ReactNode } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';\n\nimport { useReaderState, ReaderState } from './useReaderState';\n\nconst TechDocsReaderContext = createContext<ReaderState>({} as ReaderState);\n\nexport const useTechDocsReader = () => useContext(TechDocsReaderContext);\n\n/**\n * @public Render function for {@link TechDocsReaderProvider}\n */\nexport type TechDocsReaderProviderRenderFunction = (\n value: ReaderState,\n) => JSX.Element;\n\n/**\n * @public Props for {@link TechDocsReaderProvider}\n */\nexport type TechDocsReaderProviderProps = {\n children: TechDocsReaderProviderRenderFunction | ReactNode;\n};\n\n/**\n * Provides shared building process state to the reader page components.\n *\n * @public\n */\nexport const TechDocsReaderProvider = (props: TechDocsReaderProviderProps) => {\n const { children } = props;\n\n const { '*': path = '' } = useParams();\n const { entityRef } = useTechDocsReaderPage();\n const { kind, namespace, name } = entityRef;\n const value = useReaderState(kind, namespace, name, path);\n\n return (\n <TechDocsReaderContext.Provider value={value}>\n {children instanceof Function ? children(value) : children}\n </TechDocsReaderContext.Provider>\n );\n};\n\nexport const withTechDocsReaderProvider =\n <T extends {}>(Component: ComponentType<T>) =>\n (props: T) =>\n (\n <TechDocsReaderProvider>\n <Component {...props} />\n </TechDocsReaderProvider>\n );\n","/*\n * Copyright 2021 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 { lazy, Suspense } from 'react';\nimport { useApp } from '@backstage/core-plugin-api';\n\nconst RealLogViewer = lazy(() =>\n import('./RealLogViewer').then(m => ({ default: m.RealLogViewer })),\n);\n\n/**\n * The properties for the LogViewer component.\n *\n * @public\n */\nexport interface LogViewerProps {\n /**\n * Callback function to handle the download log action, and show the download button.\n */\n onDownloadLog?: () => void;\n /**\n * Callback function to handle the copy log action, and show the copy button.\n */\n onCopyLog?: () => void | Promise<void>;\n /**\n * The text of the logs to display.\n *\n * The LogViewer component is optimized for appending content at the end of the text.\n */\n text: string;\n /**\n * Determines if the overflow text should be wrapped or shown via a single line in a horizontal scrollbar.\n */\n textWrap?: boolean;\n /**\n * Styling overrides for classes within the LogViewer component.\n */\n classes?: {\n root?: string;\n };\n}\n\n/**\n * A component that displays logs in a scrollable text area.\n *\n * @remarks\n * The LogViewer has support for search and filtering, as well as displaying\n * text content with ANSI color escape codes.\n *\n * Since the LogViewer uses windowing to avoid rendering all contents at once, the\n * log is sized automatically to fill the available vertical space. This means\n * it may often be needed to wrap the LogViewer in a container that provides it\n * with a fixed amount of space.\n *\n * @public\n */\nexport function LogViewer(props: LogViewerProps) {\n const { Progress } = useApp().getComponents();\n return (\n <Suspense fallback={<Progress />}>\n <RealLogViewer {...props} />\n </Suspense>\n );\n}\n","/*\n * Copyright 2021 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 { LogViewer } from '@backstage/core-components';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Grid from '@material-ui/core/Grid';\nimport IconButton from '@material-ui/core/IconButton';\nimport Typography from '@material-ui/core/Typography';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport Close from '@material-ui/icons/Close';\nimport { useState } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { techdocsTranslationRef } from '../../translation';\n\nconst useDrawerStyles = makeStyles((theme: Theme) =>\n createStyles({\n paper: {\n width: '100%',\n [theme.breakpoints.up('sm')]: {\n width: '75%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n padding: theme.spacing(2.5),\n },\n root: {\n height: '100%',\n overflow: 'hidden',\n },\n logs: {\n background: theme.palette.background.default,\n },\n }),\n);\n\nexport const TechDocsBuildLogsDrawerContent = ({\n buildLog,\n onClose,\n}: {\n buildLog: string[];\n onClose: () => void;\n}) => {\n const classes = useDrawerStyles();\n const { t } = useTranslationRef(techdocsTranslationRef);\n const logText =\n buildLog.length === 0 ? t('buildLogs.waitingForLogs') : buildLog.join('\\n');\n return (\n <Grid\n container\n direction=\"column\"\n className={classes.root}\n spacing={0}\n wrap=\"nowrap\"\n >\n <Grid\n item\n container\n justifyContent=\"space-between\"\n alignItems=\"center\"\n spacing={0}\n wrap=\"nowrap\"\n >\n <Typography variant=\"h5\">{t('buildLogs.title')}</Typography>\n <IconButton\n key=\"dismiss\"\n title={t('buildLogs.closeDrawer')}\n onClick={onClose}\n color=\"inherit\"\n >\n <Close />\n </IconButton>\n </Grid>\n <Grid item xs>\n <LogViewer text={logText} classes={{ root: classes.logs }} />\n </Grid>\n </Grid>\n );\n};\n\nexport const TechDocsBuildLogs = ({ buildLog }: { buildLog: string[] }) => {\n const classes = useDrawerStyles();\n const [open, setOpen] = useState(false);\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n return (\n <>\n <Button color=\"inherit\" onClick={() => setOpen(true)}>\n {t('buildLogs.showBuildLogs')}\n </Button>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={open}\n onClose={() => setOpen(false)}\n >\n <TechDocsBuildLogsDrawerContent\n buildLog={buildLog}\n onClose={() => setOpen(false)}\n />\n </Drawer>\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 { useEffect } from 'react';\nimport { useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { ErrorPage } from '@backstage/core-components';\nimport { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';\nimport { useLocation } from 'react-router-dom';\nimport { techdocsTranslationRef } from '../../translation';\n\ntype Props = {\n errorMessage?: string;\n};\n\nexport const TechDocsNotFound = ({ errorMessage }: Props) => {\n const techdocsBuilder =\n useApi(configApiRef).getOptionalString('techdocs.builder');\n const analyticsApi = useAnalytics();\n const { entityRef } = useTechDocsReaderPage();\n const location = useLocation();\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n useEffect(() => {\n const { pathname, search, hash } = location;\n analyticsApi.captureEvent('not-found', `${pathname}${search}${hash}`, {\n attributes: entityRef,\n });\n }, [analyticsApi, entityRef, location]);\n\n let additionalInfo = '';\n if (![undefined, 'local'].includes(techdocsBuilder)) {\n additionalInfo = t('notFound.builderNote');\n }\n\n return (\n <ErrorPage\n status=\"404\"\n statusMessage={errorMessage || t('notFound.title')}\n additionalInfo={additionalInfo}\n />\n );\n};\n","/*\n * Copyright 2021 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 CircularProgress from '@material-ui/core/CircularProgress';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Alert from '@material-ui/lab/Alert';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nimport { TechDocsBuildLogs } from './TechDocsBuildLogs';\nimport { TechDocsNotFound } from './TechDocsNotFound';\nimport { useTechDocsReader } from './TechDocsReaderProvider';\nimport { techdocsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n marginBottom: theme.spacing(2),\n },\n message: {\n // `word-break: break-word` is deprecated, but gives legacy support to browsers not supporting `overflow-wrap` yet\n // https://developer.mozilla.org/en-US/docs/Web/CSS/word-break\n wordBreak: 'break-word',\n overflowWrap: 'anywhere',\n },\n}));\n\nexport const TechDocsStateIndicator = () => {\n let StateAlert: JSX.Element | null = null;\n const classes = useStyles();\n const { t } = useTranslationRef(techdocsTranslationRef);\n\n const {\n state,\n contentReload,\n contentErrorMessage,\n syncErrorMessage,\n buildLog,\n } = useTechDocsReader();\n\n if (state === 'INITIAL_BUILD') {\n StateAlert = (\n <Alert\n classes={{ root: classes.root }}\n variant=\"outlined\"\n severity=\"info\"\n icon={<CircularProgress size=\"24px\" />}\n action={<TechDocsBuildLogs buildLog={buildLog} />}\n >\n {t('stateIndicator.initialBuild.message')}\n </Alert>\n );\n }\n\n if (state === 'CONTENT_STALE_REFRESHING') {\n StateAlert = (\n <Alert\n variant=\"outlined\"\n severity=\"info\"\n icon={<CircularProgress size=\"24px\" />}\n action={<TechDocsBuildLogs buildLog={buildLog} />}\n classes={{ root: classes.root }}\n >\n {t('stateIndicator.contentStaleRefreshing.message')}\n </Alert>\n );\n }\n\n if (state === 'CONTENT_STALE_READY') {\n StateAlert = (\n <Alert\n variant=\"outlined\"\n severity=\"success\"\n action={\n <Button color=\"inherit\" onClick={() => contentReload()}>\n {t('stateIndicator.contentStaleReady.refreshButton')}\n </Button>\n }\n classes={{ root: classes.root }}\n >\n {t('stateIndicator.contentStaleReady.message')}\n </Alert>\n );\n }\n\n if (state === 'CONTENT_STALE_ERROR') {\n StateAlert = (\n <Alert\n variant=\"outlined\"\n severity=\"error\"\n action={<TechDocsBuildLogs buildLog={buildLog} />}\n classes={{ root: classes.root, message: classes.message }}\n >\n {t('stateIndicator.contentStaleError.message')} {syncErrorMessage}\n </Alert>\n );\n }\n\n if (state === 'CONTENT_NOT_FOUND') {\n StateAlert = (\n <>\n {syncErrorMessage && (\n <Alert\n variant=\"outlined\"\n severity=\"error\"\n action={<TechDocsBuildLogs buildLog={buildLog} />}\n classes={{ root: classes.root, message: classes.message }}\n >\n {t('stateIndicator.contentStaleError.message')} {syncErrorMessage}\n </Alert>\n )}\n <TechDocsNotFound errorMessage={contentErrorMessage} />\n </>\n );\n }\n\n return StateAlert;\n};\n","/*\n * Copyright 2021 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 { PropsWithChildren, ReactNode } from 'react';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { Link } from '@backstage/core-components';\nimport { ResultHighlight } from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '@backstage/plugin-search-react';\n\nconst useStyles = makeStyles({\n flexContainer: {\n flexWrap: 'wrap',\n },\n itemText: {\n width: '100%',\n marginBottom: '1rem',\n },\n});\n\n/**\n * Props for {@link TechDocsSearchResultListItem}.\n *\n * @public\n */\nexport type TechDocsSearchResultListItemProps = {\n icon?: ReactNode | ((result: any) => ReactNode);\n result?: any;\n highlight?: ResultHighlight;\n rank?: number;\n lineClamp?: number;\n asListItem?: boolean;\n asLink?: boolean;\n title?: string;\n};\n\n/**\n * Component which renders documentation and related metadata.\n *\n * @public\n */\nexport const TechDocsSearchResultListItem = (\n props: TechDocsSearchResultListItemProps,\n) => {\n const {\n result,\n highlight,\n lineClamp = 5,\n asListItem = true,\n asLink = true,\n title,\n icon,\n } = props;\n const classes = useStyles();\n\n const LinkWrapper = ({ children }: PropsWithChildren<{}>) =>\n asLink ? (\n <Link noTrack to={result.location}>\n {children}\n </Link>\n ) : (\n <>{children}</>\n );\n\n const TextItem = () => {\n const resultTitle = highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n );\n\n const entityTitle = highlight?.fields.entityTitle ? (\n <HighlightedSearchResultText\n text={highlight.fields.entityTitle}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.entityTitle\n );\n\n const resultName = highlight?.fields.name ? (\n <HighlightedSearchResultText\n text={highlight.fields.name}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.name\n );\n\n if (!result) return null;\n\n return (\n <ListItemText\n className={classes.itemText}\n primaryTypographyProps={{ variant: 'h6' }}\n primary={\n <LinkWrapper>\n {title ? (\n title\n ) : (\n <>\n {resultTitle} | {entityTitle ?? resultName} docs\n </>\n )}\n </LinkWrapper>\n }\n secondary={\n <Typography\n component=\"span\"\n style={{\n display: '-webkit-box',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lineClamp,\n overflow: 'hidden',\n }}\n color=\"textSecondary\"\n variant=\"body2\"\n >\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </Typography>\n }\n />\n );\n };\n\n const ListItemWrapper = ({ children }: PropsWithChildren<{}>) =>\n asListItem ? (\n <>\n {icon && (\n <ListItemIcon>\n {typeof icon === 'function' ? icon(result) : icon}\n </ListItemIcon>\n )}\n <div className={classes.flexContainer}>{children}</div>\n </>\n ) : (\n <>{children}</>\n );\n\n return (\n <ListItemWrapper>\n <TextItem />\n </ListItemWrapper>\n );\n};\n"],"names":["instance","b","options","isJsonObject","value","Array","isJsonObjectDeep","seen","Set","Object","v","isJsonValueDeep","validateMetaSchema","schema","InputError","ajv","Ajv","ajvErrors","result","error","message","z","x","jsonSchemaSchema","ctx","isError","opDeclareAnnotationV1Schema","opDeclareKindV1Schema","fullKindSchema","reduceKindSchema","parsed","allOf","rest","type","allProperties","kindRest","apiVersion","kind","properties","FORBIDDEN_SCHEMA_ROOT_FIELDS","FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS","relationFieldSchema","opDeclareKindVersionV1Schema","opsFromCatalogModelAddKindVersion","definition","ops","version","jsonSchema","name","validateKindRootSchemaSemantics","field","rootProperties","fieldName","fieldSchema","specType","undefined","input","opDeclareLabelV1Schema","opDeclareRelationV1Schema","createDeclareRelationOp","opRemoveAnnotationV1Schema","opRemoveKindV1Schema","opRemoveLabelV1Schema","opRemoveTagV1Schema","opDeclareTagV1Schema","opUpdateAnnotationV1Schema","opUpdateKindV1Schema","opUpdateKindVersionV1Schema","opUpdateLabelV1Schema","opUpdateRelationV1Schema","createUpdateRelationOp","opUpdateTagV1Schema","OpaqueCatalogModelLayer","OpaqueType","DefaultCatalogModelLayerBuilder","opsFromCatalogModelUpdateKind","relation","opsFromCatalogModelRelationPair","relationPair","firstKind","secondKind","opsFromCatalogModelUpdateRelationPair","annotation","opsFromCatalogModelAnnotation","opsFromCatalogModelUpdateAnnotation","label","opsFromCatalogModelLabel","opsFromCatalogModelUpdateLabel","tag","layer","internal","RELATION_OWNED_BY","RELATION_DEPENDS_ON","RELATION_PART_OF","RELATION_HAS_PART","model","useStyles","makeStyles","EmptyStateImage","missing","classes","missingAnnotation","noInformation","createComponent","noBuild","theme","EmptyState","props","title","description","action","Grid","Typography","FavoriteToggleIcon","isFavorite","StarIcon","UnstarredIcon","FavoriteToggle","id","onChange","iconButtonProps","Tooltip","IconButton","LinkWrapper","forwardRef","ref","UnstyledLink","LinkButton","MaterialButton","createStyles","SvgIcon","BootstrapInput","withStyles","InputBase","SelectComponent","multiple","items","placeholder","selected","triggerReset","native","disabled","margin","dataTestId","setValue","useState","isOpen","setOpen","useEffect","Box","FormControl","InputLabel","Select","event","previous","HTMLElement","s","selectedValue","item","el","Chip","CancelIcon","newValue","chip","OpenedDropdown","ClosedDropdown","MenuItem","Checkbox","SupportIcon","icon","app","useApp","Icon","HelpIcon","SupportLink","link","Link","SupportListItem","ListItemIcon","ListItemText","prev","idx","SupportButton","t","useTranslationRef","coreComponentsTranslationRef","children","configItems","useSupportConfig","popoverOpen","setPopoverOpen","anchorEl","setAnchorEl","supportConfig","useApi","configApiRef","isSmallScreen","useMediaQuery","onClickHandler","popoverCloseHandler","Button","Popover","MenuList","Boolean","Children","child","i","DialogActions","useFilterStyles","Filters","onChangeFilters","selectedFilters","setSelectedFilters","reset","filter","TableLoadingBody","CircularProgress","tableIcons","AddBox","Check","Clear","DeleteOutline","ChevronRight","Edit","SaveAlt","FilterList","FirstPage","LastPage","ChevronLeft","Search","ArrowUpward","Remove","ViewColumn","extractValueByField","data","path","StyledMTableHeader","MTableHeader","StyledMTableToolbar","MTableToolbar","useTableStyles","defaultInitialState","TableToolbar","toolbarProps","toolbarRef","setSearch","hasFilters","selectedFiltersLength","toggleFilters","filtersClasses","onSearchChanged","useCallback","searchText","Table","filterConfig","dataValue","columns","emptyContent","subtitle","localization","filters","initialState","onStateChange","components","loading","style","restProps","tableClasses","useTheme","calculatedInitialState","filtersOpen","setFiltersOpen","search","state","transform","key","isEqual","defaultState","getFieldByTitle","titleValue","tableData","useMemo","selectedFiltersArray","filterValue","fieldValue","Toolbar","hasNoRows","columnCount","Body","makeBody","bodyProps","MTableBody","distinctValues","addValue","c","MTable","column","headerStyle","cellStyle","cellStyleFn","rowData","rowColumn","ClickableText","StyledBox","BreadcrumbsCurrentPage","Breadcrumbs","childrenArray","firstPage","secondPage","expandablePages","currentPage","hasHiddenBreadcrumbs","Fragment","MaterialBreadcrumbs","List","pageLink","index","ListItem","Content","className","stretch","noPadding","classNames","ContentHeaderTitle","ContentHeaderDescription","ContentHeader","TitleComponent","DescriptionComponent","textAlign","renderedTitle","renderedDescription","Helmet","TypeFragment","typeLink","pageTitle","TitleFragment","tooltip","contentRef","useContent","FinalTitle","SubtitleFragment","Header","pageTitleOverride","appTitle","configApi","documentTitle","titleTemplate","defaultTitle","alpha","HeaderLabelContent","typographyRootComponent","HeaderLabel","url","contentTypograpyRootComponent","content","Page","themeId","ThemeProvider","baseTheme","useRouteRefParams","_routeRef","useParams","ButtonLinkDefinition","defineComponent","styles","ButtonLinkView","definitionResult","navigation","forwardedRef","ownProps","dataAttributes","analytics","iconStart","iconEnd","navigationProps","getReactAriaAnchorProps","RALink","e","text","getNodeText","String","ButtonLink","useDefinition","Navigation","CardDefinition","CardHeaderDefinition","CardBodyDefinition","CardFooterDefinition","Card","utilityStyle","onPress","href","linkTarget","rel","download","isInteractive","triggerRef","useRef","handleClick","targetNode","targetElement","Element","window","MouseEvent","RAButton","CardHeader","CardBody","CardFooter","ContainerDefinition","Container","HeaderNavDefinition","HeaderNavItemDefinition","HeaderNavGroupDefinition","HeaderNavIndicators","navRef","itemRefs","activeKey","highlightedKey","prevActiveKey","prevHoveredKey","resetTimer","updateCSSVariables","container","containerRect","rect","relativeLeft","relativeTop","requestAnimationFrame","cancelAnimationFrame","handleResize","isTabGroup","tab","HeaderNavLinkView","routerOptions","active","registerRef","onHighlight","linkRef","ariaHref","linkProps","useLink","hoverProps","useHover","_href","anchorProps","mergeProps","commonProps","browserHref","HeaderNavLink","HeaderNavGroupItem","group","activeChildId","MenuTrigger","RiArrowDownSLine","Menu","HeaderNavAutoDetect","activeTabId","useAutoActiveTabId","tabs","routing","useRoutingIntegration","basePath","pathname","routeObjects","allTabs","resolvePath","matches","matchRoutes","HeaderNavInner","isFocusVisible","useFocusVisible","Map","setHighlightedKey","HeaderNav","inRouter","HeaderDefinition","customActions","breadcrumbs","tags","metadata","sticky","descriptionNodes","Lexer","token","sanitizeUrl","stickySentinelRef","isStuck","setIsStuck","sentinel","root","getScrollParent","element","parent","overflow","overflowX","overflowY","IntersectionObserver","updateStuckState","sentinelRect","rootTop","scrollTarget","observer","entry","Text","breadcrumb","RiArrowRightSLine","entityPresentationSnapshot","entityOrRef","context","entityPresentationApi","stringifyEntityRef","defaultEntityPresentation","BootstrapAutocomplete","Autocomplete","PopperComponent","Popper","TransitionProps","Grow","PaperComponent","Paper","CatalogAutocomplete","LabelProps","TextFieldProps","renderInput","params","TextField","merge","autocomplete","ExpandMoreIcon","CatalogFilterLayout","isScreenSmallerThanBreakpoint","filterDrawerOpen","setFilterDrawerOpen","catalogReactTranslationRef","FilterListIcon","Drawer","CheckBoxOutlineBlankIcon","checkedIcon","CheckBoxIcon","OptionCheckbox","EntityAutocompletePickerOption","memo","availableOptions","showCounts","FormControlLabel","EntityAutocompletePicker","Filter","InputProps","initialSelectedOptions","filtersForAvailableValues","hidden","getOptionLabel","renderOption","updateFilters","queryParameter","useEntityList","catalogApi","catalogApiRef","availableValuesFilters","f","availableValues","useAsync","facets","reduceBackendCatalogFilters","count","queryParameters","filteredOptions","selectedOptions","setSelectedOptions","shouldAddFilter","newSelectedOptions","_event","option","renderRow","cloneElement","OuterElementContext","createContext","OuterElementType","rrOnScroll","outerOnScroll","outerProps","useContext","VirtualizedListbox","other","itemData","itemCount","itemsToShow","Math","FixedSizeList","FixedWidthFormControlLabel","_theme","RenderOptionLabel","isGroup","useEntityPresentation","GroupIcon","PersonIcon","EntityOwnerPicker","mode","apis","useApiHolder","entityPresentationApiRef","ownersParameter","setText","queryParamOwners","selectedOwners","setSelectedOwners","EntityOwnerFilter","handleFetch","cache","useFetchEntities","initialSelectedOwnersRefs","isOwnersOnlyMode","queryEntitiesResponse","useAsyncFn","request","limit","cursorRequest","response","initialRequest","facetsEntitiesResponse","useFacetsEntities","enabled","facetsPromise","facet","namespace","parseEntityRef","a","start","isFacetsResponse","JSON","atob","filteredRefs","entity","normalizedText","end","encodeCursor","entities","payload","btoa","useSelectedOwners","allEntities","initialSelectedEntities","useMountEffect","entityRef","useDebouncedEffect","availableOwners","o","_","owners","_e","inputValue","hasReachedEnd","EntityRefLinks","entityRefs","hideIcons","r","entityRefString","EntityRefLink","EntityTagPicker","EntityTagFilter","UserListPicker","initialFilter","availableFilters","alwaysKeepFilters","orgName","userParameter","kindParameter","userAndGroupFilterIds","filterGroups","getFilterGroups","SettingsIcon","filterGroup","ownedEntitiesCount","loadingOwnedEntities","ownedEntitiesFilter","useOwnedEntitiesCount","identityApi","identityApiRef","ownershipEntityRefs","loadingEntityRefs","user","allFilters","orderFields","catalogFilters","reduceCatalogFilters","compact","loadingEntityOwnership","fetchEntities","req","ownedClaims","getOwnedCountClaims","ownersRefs","commonOwnedBy","intersection","totalItems","useDeepCompareEffect","EntityUserFilter","allCount","useAllEntitiesCount","prevRequest","compacted","newRequest","starredEntitiesCount","starredEntitiesFilter","loadingStarredEntities","useStarredEntitiesCount","starredEntities","useStarredEntities","queryParamUserFilter","selectedUserFilter","setSelectedUserFilter","filterCounts","ListItemSecondaryAction","EntityKindFilter","EntityTypeFilter","values","EntityTextFilter","words","exactMatch","targets","partialMatch","word","m","fullRefs","err","getEntityRelations","EntityLifecycleFilter","EntityNamespaceFilter","refs","starredEntityRefs","relations","UserListFilter","isOwnedEntity","isStarredEntity","EntityOrphanFilter","orphan","EntityErrorFilter","NewEntityListContext","createVersionedContext","OldEntityListContext","EntityListProvider","isMounted","useMountedState","requestedFilters","setRequestedFilters","location","useLocation","paginationMode","paginationLimit","initialCursor","initialOffset","initialLimit","qs","queryLimit","Number","isNaN","offset","cursor","setCursor","setOffset","setLimit","backendState","setBackendState","setLoading","setError","refreshToken","setRefreshToken","lastFetchParamsRef","fetchGenRef","adjustedFilters","kindValue","refresh","fetchParams","doFetch","backendFilter","gen","useDebounce","totalItemsLoading","refreshCount","entityFilter","reduceEntityFilters","queryParams","oldParams","newParams","newUrl","document","update","prevFilters","newFilters","triggerRefresh","pageInfo","prevCursor","nextCursor","createVersionedValueMap","versionedHolder","useVersionedContext","oldContext","Error","getEntityRef","starredEntitiesApi","starredEntitiesApiRef","useObservable","toggleStarredEntity","isEntityTextFilter","isEntityOrderFilter","condensedFilters","compoundFilter","fullTextFilter","backendCatalogFilters","relationType","entityNames","HighlightedSearchResultText","preTag","postTag","terms","RegExp","searchApiRef","createApiRef","SearchContext","useSearch","defaultInitialSearchState","LocalSearchContext","useSearchContextValue","initialValue","searchApi","useAnalytics","term","setTerm","types","setTypes","setFilters","pageLimit","setPageLimit","pageCursor","setPageCursor","isFirstEmptyMount","prevTerm","usePrevious","abortControllerRef","controller","AbortController","resultSet","hasNextPage","hasPreviousPage","fetchNextPage","fetchPreviousPage","AnalyticsContext","SearchContextProvider","inheritParentContextIfAvailable","hasParentContext","configInitialSearchState","searchContextInitialState","SHADOW_DOM_STYLE_LOAD_EVENT","useShadowDomStylesLoading","handleLoad","TechDocsShadowDom","onAppend","jss","setJss","create","jssPreset","CustomEvent","shadowHost","shadowRoot","StylesProvider","techdocsPlugin","PluginImpl","config","extension","createApiFactory","techdocsStorageApiRef","discoveryApiRef","fetchApiRef","discoveryApi","fetchApi","TechDocsStorageClient","techdocsApiRef","TechDocsClient","rootRouteRef","rootDocsRouteRef","rootCatalogDocsRouteRef","createRoutableExtension","TechDocsReaderPage","createSearchResultListItemExtension","EntityPageDocs","withSearch","getCompoundEntityRef","searchResultUrlMapper","useEntityPageTechDocsRedirect","routeDocsRoot","useRouteRef","routeDocsCatalog","rootDocsPath","catalogDocsPath","suffix","TECHDOCS_EXTERNAL_ANNOTATION","defaultPath","getEntityRootTechDocsPath","TechDocsReaderPageSubheader","TechDocsReaderPageContent","MissingAnnotationEmptyState","owner","yamlText","line","lineNumbers","entityContext","useEntity","readMoreUrl","annotations","entityKind","ann","generateDescription","annotationList","curr","CodeSnippet","Router","Routes","Route","TechDocsIndexPage","TechDocsReaderRouter","useRoutes","EmbeddedDocsRouter","emptyState","TECHDOCS_ANNOTATION","LegacyEmbeddedDocsRouter","SearchAutocompleteDefinition","SearchAutocompleteItemDefinition","SearchAutocompleteEmptyState","SearchAutocomplete","ariaLabel","ariaLabelledBy","onInputChange","popoverWidth","popoverPlacement","isLoading","defaultOpen","popoverRef","hasValue","hasChildren","liveMessage","overlayState","useOverlayTriggerState","useInteractOutside","target","OverlayTriggerStateContext","RASearchField","RiSearch2Line","Input","RiCloseCircleLine","RAPopover","BgReset","ListBox","VisuallyHidden","SearchAutocompleteItemView","ListBoxItem","SearchAutocompleteItem","TechDocsReaderSearchBar","entityId","navigate","useNavigate","results","deferredLoading","useTechDocsSearch","Flex","TechDocsReaderSearch","TechDocsReaderHeader","tabTitle","showSourceLink","sourceLink","addons","useTechDocsReaderHeaderData","RiCodeLine","locations","TechDocsReaderEntityCard","entityMetadata","entityMetadataLoading","useTechDocsReaderPage","spec","lifecycle","ownedByRelations","capitalize","TechDocsReaderContent","withTechDocsReaderProvider","dom","handleAppend","isNotFound","isDomReady","showProgress","NotFoundErrorPage","useTechDocsReaderContentData","TechDocsStateIndicator","Progress","TechDocsReaderPageContentAddons","TechDocsReaderLayout","withHeader","Addons","TechDocsAddons","Addon","attachTechDocsAddonComponentData","Suspense","TechDocsEntityContent","toLowerMaybe","str","DocsTable","actions","copyToClipboard","useCopyToClipboard","getRouteToReaderPageFor","apiHolder","techdocsTranslationRef","documents","entitiesToDocsMapper","tableColumns","columnFactories","defaultActions","actionFactories","paging","pageSize","OffsetPaginatedDocsTable","page","setPage","newPage","CursorPaginatedDocsTable","next","EntityListDocsTable","WarningPanel","row","ShareIcon","isStarred","useSubvalueCellStyles","SubvalueCell","subvalue","customTitle","presentationApi","TableColumnTitle","translationKey","row1","row2","title1","title2","EntityDisplayName","resolved","DefaultTechDocsHome","ownerPickerMode","pagination","PageWrapper","CustomHeader","Wrapper","TechDocsPageWrapper","TechDocsPicker","outlet","useOutlet","PageWithHeader","CustomPageWrapper","generatedSubtitle","TechDocsFilter","CATALOG_FILTER_EXISTS","ReactDOMPromise","MKDOCS_CSS","GOOGLE_FONTS","GSTATIC_FONTS","removeUnsafeLinks","node","Node","isMkdocsCss","isGoogleFonts","isGstaticFonts","isLink","removeUnsafeMetaTags","httpEquiv","removeRestrictedAttributes","TECHDOCS_SIDEBAR_WIDTH","headings","relativeLengthUnit","cssVariable","themeHashes","rules","lighten","sidebar","heading","htmlFontSize","lineHeight","fontFamily","fontWeight","fontSize","calculate","resolvedValue","factor","hash","html","transformers","DOMParser","transformer","isSvgNeedingInlining","attrName","attrVal","apiOrigin","URL","isSrcToSvg","isRelativeUrl","pointsToOurBackend","normalizeUrl","renderReactElement","ReactDOM","TechDocsRedirectNotification","handleButtonClick","autoHideDuration","open","handleClose","Snackbar","CopyToClipboardTooltip","CopyToClipboardIcon","CopyToClipboardButton","onCssReady","onLoading","onLoaded","handleShadowDomStyleLoad","onReady","setShadowRoot","useTechDocsReader","useTechDocsReaderDom","appBaseUrl","purify","to","parsedAppUrl","appUrlPath","relativeUrl","parsedUrl","isMobileMedia","sanitizerTransformer","DOMPurify","hosts","isIframe","isSafe","src","host","tagNameCheck","attributeNameCheck","allowedURIProtocols","allowedURIRegExp","stylesTransformer","useSidebarPinState","rule","techdocsStorageApi","scmIntegrationsApi","scmIntegrationsApiRef","rawPage","currPath","setDom","isStyleLoading","useInitialRedirect","useLayoutEffect","updateSidebarPositionAndHeight","sidebars","pageTop","domTop","tabsHeight","scrollbarTopPx","footer","scrollbarEndPx","updateFooterWidth","preRender","rawContent","contentPath","addBaseUrl","updateDom","list","attributeName","elem","elemAttribute","svg","fetch","svgContent","unescape","encodeURIComponent","Promise","normalizedWindowLocation","mkdocsToggleSidebar","article","toggleSidebar","createElement","MenuIcon","sourceAnchor","sourceURL","integration","issueTitle","issueDesc","gitUrl","replaceGithubUrlType","gitInfo","parseGitUrl","repoPath","feedbackLink","FeedbackOutlinedIcon","postRender","transformedElement","entityName","determineRedirectURL","metaUrl","normalizedCurrentUrl","absoluteRedirectObj","currentTechDocPath","indexOfSiteHome","metaContentParameters","redirectURL","setTimeout","activeNavItems","activeNavItem","checkbox","lastItem","code","addLinkClickListener","baseUrl","onClick","modifierActive","linkText","navLabels","keyboardEvent","forId","Event","shouldReplaceContent","preTransformedDomElement","hashElement","useShadowRootElements","newShadowRoot","Function","useTechDocsAddons","setTitle","setSubtitle","metadataLoading","site_description","locationMetadata","noTdMetadata","noEntMetadata","stringEntityRef","entityDisplayName","techdocsTabTitleItems","removeTrailingSlash","tabTitleItems","searchVal","setResults","setDeferredLoading","loadingTimer","clearTimeout","skeleton","Skeleton","TechDocsReaderPageHeader","docsRootLink","labels","CodeIcon","CookieAuthRefreshProvider","useCookieAuthRefresh","pluginId","channel","BroadcastChannel","requestUrl","Date","ResponseError","retry","timeout","cancel","listener","ErrorPanel","StyledPage","styled","viewTechdocLink","entityKey","checkedEntityRef","shouldCheckForRedirect","externalRedirectResult","shouldShowProgress","currentTheme","readerPageTheme","createTheme","memoizedEntityRef","catalogEntity","buildTechDocsURL","grandChildren","childrenList","grandChild","getComponentData","TECHDOCS_ADDONS_WRAPPER_KEY","TECHDOCS_ADDONS_KEY","TechDocsReaderPageProvider","Component","searchReactTranslationRef","createTranslationRef","SearchBarBase","onKeyDown","onClear","onSubmit","debounceTime","clearButton","fullWidth","defaultValue","inputProps","endAdornment","forwardedValueRef","prevValue","handleChange","handleKeyDown","handleClear","inputPlaceholder","SearchIcon","DefaultSearchIcon","startAdornment","InputAdornment","clearButtonEndAdornment","SearchBar","SearchAutocompleteLoadingAdornment","inputDebounceTime","freeSolo","clearOnBlur","getInputValue","reason","details","InputLabelProps","TechDocsSearchBar","entityTitle","selection","highlight","TechDocsSearchResultListItem","TechDocsSearch","contentElement","primarySidebarElement","primarySidebarAddonLocation","secondarySidebarElement","secondarySidebarAddonLocation","Portal","subheaderAddons","settingsAddons","reducer","oldState","newState","TechDocsReaderContext","TechDocsReaderProvider","useReaderState","dispatch","useReducer","contentReload","useAsyncRetry","entityDocs","buildingTimeout","log","displayState","calculateDisplayState","contentLoading","activeSyncState","RealLogViewer","lazy","LogViewer","useDrawerStyles","TechDocsBuildLogsDrawerContent","buildLog","onClose","logText","Close","TechDocsBuildLogs","TechDocsNotFound","errorMessage","techdocsBuilder","analyticsApi","additionalInfo","ErrorPage","StateAlert","contentErrorMessage","syncErrorMessage","Alert","lineClamp","asListItem","asLink","ListItemWrapper","resultTitle","resultName","TextItem"],"mappings":"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"}