@backstage/plugin-techdocs 1.13.3-next.0 → 1.14.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # @backstage/plugin-techdocs
2
2
 
3
+ ## 1.14.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system.
8
+ - Updated dependencies
9
+ - @backstage/frontend-plugin-api@0.11.0-next.1
10
+ - @backstage/core-compat-api@0.5.0-next.2
11
+ - @backstage/plugin-search-react@1.9.3-next.1
12
+ - @backstage/plugin-catalog-react@1.20.0-next.2
13
+ - @backstage/core-components@0.17.5-next.1
14
+ - @backstage/catalog-client@1.11.0-next.0
15
+ - @backstage/catalog-model@1.7.5
16
+ - @backstage/config@1.3.3
17
+ - @backstage/core-plugin-api@1.10.9
18
+ - @backstage/errors@1.2.7
19
+ - @backstage/integration@1.17.1
20
+ - @backstage/integration-react@1.2.9
21
+ - @backstage/theme@0.6.8-next.0
22
+ - @backstage/plugin-auth-react@0.1.18-next.0
23
+ - @backstage/plugin-search-common@1.2.19
24
+ - @backstage/plugin-techdocs-common@0.1.1
25
+ - @backstage/plugin-techdocs-react@1.3.2-next.0
26
+
27
+ ## 1.14.0-next.1
28
+
29
+ ### Minor Changes
30
+
31
+ - cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config
32
+
33
+ ### Patch Changes
34
+
35
+ - f2f133c: Internal update to use the new variant of `ApiBlueprint`.
36
+ - Updated dependencies
37
+ - @backstage/core-compat-api@0.4.5-next.1
38
+ - @backstage/plugin-catalog-react@1.20.0-next.1
39
+ - @backstage/frontend-plugin-api@0.11.0-next.0
40
+ - @backstage/theme@0.6.8-next.0
41
+ - @backstage/catalog-client@1.11.0-next.0
42
+ - @backstage/plugin-search-react@1.9.3-next.0
43
+ - @backstage/plugin-techdocs-react@1.3.2-next.0
44
+ - @backstage/core-components@0.17.5-next.0
45
+ - @backstage/catalog-model@1.7.5
46
+ - @backstage/config@1.3.3
47
+ - @backstage/core-plugin-api@1.10.9
48
+ - @backstage/errors@1.2.7
49
+ - @backstage/integration@1.17.1
50
+ - @backstage/integration-react@1.2.9
51
+ - @backstage/plugin-auth-react@0.1.18-next.0
52
+ - @backstage/plugin-search-common@1.2.19
53
+ - @backstage/plugin-techdocs-common@0.1.1
54
+
3
55
  ## 1.13.3-next.0
4
56
 
5
57
  ### Patch Changes
package/config.d.ts CHANGED
@@ -58,6 +58,16 @@ export interface Config {
58
58
  * @visibility frontend
59
59
  */
60
60
  allowedCustomElementAttributeNameRegExp?: string;
61
+ /**
62
+ * Allows listed protocols in attributes with URI values
63
+ * Example:
64
+ * additionalAllowedURIProtocols: ['vscode']
65
+ * this will allow all attributes with URI values to have `vscode` protocol like `vscode://some/path` in addition to the default protocols
66
+ * matched by DOMPurify's IS_ALLOWED_URI RegExp:
67
+ * @see: https://raw.githubusercontent.com/cure53/DOMPurify/master/src/regexp.ts
68
+ * @visibility frontend
69
+ */
70
+ additionalAllowedURIProtocols?: string;
61
71
  };
62
72
  };
63
73
  }
package/dist/alpha.d.ts CHANGED
@@ -25,12 +25,12 @@ declare const techDocsSearchResultListItemExtension: _backstage_frontend_plugin_
25
25
  } & {
26
26
  noTrack?: boolean | undefined;
27
27
  };
28
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
28
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<{
29
29
  predicate?: _backstage_plugin_search_react_alpha.SearchResultItemExtensionPredicate;
30
30
  component: _backstage_plugin_search_react_alpha.SearchResultItemExtensionComponent;
31
31
  }, "search.search-result-list-item.item", {}>;
32
32
  inputs: {
33
- [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.AnyExtensionDataRef, {
33
+ [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ExtensionDataRef, {
34
34
  optional: boolean;
35
35
  singleton: boolean;
36
36
  }>;
@@ -54,31 +54,27 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
54
54
  name: undefined;
55
55
  config: {};
56
56
  configInput: {};
57
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
57
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
58
58
  inputs: {};
59
- params: {
60
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
61
- };
59
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
62
60
  }>;
63
61
  "api:techdocs/storage": _backstage_frontend_plugin_api.ExtensionDefinition<{
64
62
  kind: "api";
65
63
  name: "storage";
66
64
  config: {};
67
65
  configInput: {};
68
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
66
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
69
67
  inputs: {};
70
- params: {
71
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
72
- };
68
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
73
69
  }>;
74
70
  "empty-state:techdocs/entity-content": _backstage_frontend_plugin_api.ExtensionDefinition<{
75
71
  config: {};
76
72
  configInput: {};
77
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {
73
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {
78
74
  optional: true;
79
75
  }>;
80
76
  inputs: {
81
- [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.AnyExtensionDataRef, {
77
+ [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ExtensionDataRef, {
82
78
  optional: boolean;
83
79
  singleton: boolean;
84
80
  }>;
@@ -100,13 +96,13 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
100
96
  path?: string | undefined;
101
97
  group?: string | false | undefined;
102
98
  };
103
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
99
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
104
100
  optional: true;
105
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
101
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
106
102
  optional: true;
107
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
103
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-filter-expression", {
108
104
  optional: true;
109
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-content-group", {
105
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-group", {
110
106
  optional: true;
111
107
  }>;
112
108
  inputs: {
@@ -124,10 +120,13 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
124
120
  kind: "entity-content";
125
121
  name: undefined;
126
122
  params: {
123
+ defaultPath?: [Error: `Use the 'path' param instead`];
124
+ path: string;
125
+ defaultTitle?: [Error: `Use the 'title' param instead`];
126
+ title: string;
127
+ defaultGroup?: [Error: `Use the 'group' param instead`];
128
+ group?: keyof typeof _backstage_plugin_catalog_react_alpha.defaultEntityContentGroups | (string & {});
127
129
  loader: () => Promise<JSX.Element>;
128
- defaultPath: string;
129
- defaultTitle: string;
130
- defaultGroup?: keyof typeof _backstage_plugin_catalog_react_alpha.defaultEntityContentGroups | (string & {});
131
130
  routeRef?: _backstage_frontend_plugin_api.RouteRef;
132
131
  filter?: string | _backstage_plugin_catalog_react_alpha.EntityPredicate | ((entity: _backstage_catalog_model.Entity) => boolean);
133
132
  };
@@ -145,11 +144,11 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
145
144
  label?: string | undefined;
146
145
  title?: string | undefined;
147
146
  };
148
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
147
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
149
148
  optional: true;
150
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "catalog.entity-filter-expression", {
149
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-filter-expression", {
151
150
  optional: true;
152
- }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => _backstage_core_components.IconLinkVerticalProps, "entity-icon-link-props", {}>;
151
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<() => _backstage_core_components.IconLinkVerticalProps, "entity-icon-link-props", {}>;
153
152
  inputs: {};
154
153
  params: {
155
154
  useProps: () => Omit<_backstage_core_components.IconLinkVerticalProps, "color">;
@@ -161,7 +160,7 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
161
160
  name: undefined;
162
161
  config: {};
163
162
  configInput: {};
164
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
163
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<{
165
164
  title: string;
166
165
  icon: _backstage_core_plugin_api.IconComponent;
167
166
  routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
@@ -182,12 +181,13 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
182
181
  configInput: {
183
182
  path?: string | undefined;
184
183
  };
185
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
184
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
186
185
  optional: true;
187
186
  }>;
188
187
  inputs: {};
189
188
  params: {
190
- defaultPath: string;
189
+ defaultPath?: [Error: `Use the 'path' param instead`];
190
+ path: string;
191
191
  loader: () => Promise<JSX.Element>;
192
192
  routeRef?: _backstage_frontend_plugin_api.RouteRef;
193
193
  };
@@ -199,7 +199,7 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
199
199
  configInput: {
200
200
  path?: string | undefined;
201
201
  };
202
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
202
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
203
203
  optional: true;
204
204
  }>;
205
205
  inputs: {
@@ -211,7 +211,8 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
211
211
  kind: "page";
212
212
  name: "reader";
213
213
  params: {
214
- defaultPath: string;
214
+ defaultPath?: [Error: `Use the 'path' param instead`];
215
+ path: string;
215
216
  loader: () => Promise<JSX.Element>;
216
217
  routeRef?: _backstage_frontend_plugin_api.RouteRef;
217
218
  };
@@ -233,12 +234,12 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
233
234
  } & {
234
235
  noTrack?: boolean | undefined;
235
236
  };
236
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
237
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<{
237
238
  predicate?: _backstage_plugin_search_react_alpha.SearchResultItemExtensionPredicate;
238
239
  component: _backstage_plugin_search_react_alpha.SearchResultItemExtensionComponent;
239
240
  }, "search.search-result-list-item.item", {}>;
240
241
  inputs: {
241
- [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.AnyExtensionDataRef, {
242
+ [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ExtensionDataRef, {
242
243
  optional: boolean;
243
244
  singleton: boolean;
244
245
  }>;
package/dist/alpha.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import LibraryBooks from '@material-ui/icons/LibraryBooks';
3
3
  import { ApiBlueprint, PageBlueprint, createExtensionInput, coreExtensionData, createExtension, NavItemBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
4
- import { createApiFactory, configApiRef, discoveryApiRef, fetchApiRef } from '@backstage/core-plugin-api';
4
+ import { configApiRef, discoveryApiRef, fetchApiRef } from '@backstage/core-plugin-api';
5
5
  import { compatWrapper, convertLegacyRouteRef, convertLegacyRouteRefs } from '@backstage/core-compat-api';
6
6
  import { EntityIconLinkBlueprint, EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
7
7
  import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha';
@@ -33,38 +33,34 @@ const techdocsEntityIconLink = EntityIconLinkBlueprint.make({
33
33
  });
34
34
  const techDocsStorageApi = ApiBlueprint.make({
35
35
  name: "storage",
36
- params: {
37
- factory: createApiFactory({
38
- api: techdocsStorageApiRef,
39
- deps: {
40
- configApi: configApiRef,
41
- discoveryApi: discoveryApiRef,
42
- fetchApi: fetchApiRef
43
- },
44
- factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsStorageClient({
45
- configApi,
46
- discoveryApi,
47
- fetchApi
48
- })
36
+ params: (defineParams) => defineParams({
37
+ api: techdocsStorageApiRef,
38
+ deps: {
39
+ configApi: configApiRef,
40
+ discoveryApi: discoveryApiRef,
41
+ fetchApi: fetchApiRef
42
+ },
43
+ factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsStorageClient({
44
+ configApi,
45
+ discoveryApi,
46
+ fetchApi
49
47
  })
50
- }
48
+ })
51
49
  });
52
50
  const techDocsClientApi = ApiBlueprint.make({
53
- params: {
54
- factory: createApiFactory({
55
- api: techdocsApiRef,
56
- deps: {
57
- configApi: configApiRef,
58
- discoveryApi: discoveryApiRef,
59
- fetchApi: fetchApiRef
60
- },
61
- factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsClient({
62
- configApi,
63
- discoveryApi,
64
- fetchApi
65
- })
51
+ params: (defineParams) => defineParams({
52
+ api: techdocsApiRef,
53
+ deps: {
54
+ configApi: configApiRef,
55
+ discoveryApi: discoveryApiRef,
56
+ fetchApi: fetchApiRef
57
+ },
58
+ factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsClient({
59
+ configApi,
60
+ discoveryApi,
61
+ fetchApi
66
62
  })
67
- }
63
+ })
68
64
  });
69
65
  const techDocsSearchResultListItemExtension = SearchResultListItemBlueprint.makeWithOverrides({
70
66
  config: {
@@ -89,7 +85,7 @@ const techDocsSearchResultListItemExtension = SearchResultListItemBlueprint.make
89
85
  });
90
86
  const techDocsPage = PageBlueprint.make({
91
87
  params: {
92
- defaultPath: "/docs",
88
+ path: "/docs",
93
89
  routeRef: convertLegacyRouteRef(rootRouteRef),
94
90
  loader: () => import('./home/components/TechDocsIndexPage.esm.js').then(
95
91
  (m) => compatWrapper(/* @__PURE__ */ jsx(m.TechDocsIndexPage, {}))
@@ -109,7 +105,7 @@ const techDocsReaderPage = PageBlueprint.makeWithOverrides({
109
105
  return /* @__PURE__ */ jsx(Addon, {}, options.name);
110
106
  });
111
107
  return originalFactory({
112
- defaultPath: "/docs/:namespace/:kind/:name",
108
+ path: "/docs/:namespace/:kind/:name",
113
109
  routeRef: convertLegacyRouteRef(rootDocsRouteRef),
114
110
  loader: async () => await import('./Router.esm.js').then(({ TechDocsReaderRouter }) => {
115
111
  return compatWrapper(
@@ -136,8 +132,8 @@ const techDocsEntityContent = EntityContentBlueprint.makeWithOverrides({
136
132
  factory(originalFactory, context) {
137
133
  return originalFactory(
138
134
  {
139
- defaultPath: "docs",
140
- defaultTitle: "TechDocs",
135
+ path: "docs",
136
+ title: "TechDocs",
141
137
  routeRef: convertLegacyRouteRef(rootCatalogDocsRouteRef),
142
138
  loader: () => import('./Router.esm.js').then(({ EmbeddedDocsRouter }) => {
143
139
  const addons = context.inputs.addons.map((output) => {
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/alpha/index.tsx"],"sourcesContent":["/*\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 LibraryBooks from '@material-ui/icons/LibraryBooks';\nimport {\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n NavItemBlueprint,\n createExtensionInput,\n coreExtensionData,\n createExtension,\n} from '@backstage/frontend-plugin-api';\nimport {\n configApiRef,\n createApiFactory,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n compatWrapper,\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from '@backstage/core-compat-api';\nimport {\n EntityContentBlueprint,\n EntityIconLinkBlueprint,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha';\nimport { AddonBlueprint } from '@backstage/plugin-techdocs-react/alpha';\nimport { TechDocsClient, TechDocsStorageClient } from '../client';\nimport {\n rootCatalogDocsRouteRef,\n rootDocsRouteRef,\n rootRouteRef,\n} from '../routes';\nimport { TechDocsReaderLayout } from '../reader';\nimport { attachTechDocsAddonComponentData } from '@backstage/plugin-techdocs-react/alpha';\nimport {\n TechDocsAddons,\n techdocsApiRef,\n techdocsStorageApiRef,\n} from '@backstage/plugin-techdocs-react';\n\nimport { useTechdocsReaderIconLinkProps } from './hooks/useTechdocsReaderIconLinkProps';\n\n/** @alpha */\nconst techdocsEntityIconLink = EntityIconLinkBlueprint.make({\n name: 'read-docs',\n params: {\n useProps: useTechdocsReaderIconLinkProps,\n },\n});\n\n/** @alpha */\nconst techDocsStorageApi = ApiBlueprint.make({\n name: 'storage',\n params: {\n factory: 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 },\n});\n\n/** @alpha */\nconst techDocsClientApi = ApiBlueprint.make({\n params: {\n factory: 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});\n\n/** @alpha */\nexport const techDocsSearchResultListItemExtension =\n SearchResultListItemBlueprint.makeWithOverrides({\n config: {\n schema: {\n title: z => z.string().optional(),\n lineClamp: z => z.number().default(5),\n asLink: z => z.boolean().default(true),\n asListItem: z => z.boolean().default(true),\n },\n },\n factory(originalFactory, { config }) {\n return originalFactory({\n predicate: result => result.type === 'techdocs',\n component: async () => {\n const { TechDocsSearchResultListItem } = await import(\n '../search/components/TechDocsSearchResultListItem'\n );\n return props =>\n compatWrapper(\n <TechDocsSearchResultListItem {...props} {...config} />,\n );\n },\n });\n },\n });\n\n/**\n * Responsible for rendering the provided router element\n *\n * @alpha\n */\nconst techDocsPage = PageBlueprint.make({\n params: {\n defaultPath: '/docs',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n loader: () =>\n import('../home/components/TechDocsIndexPage').then(m =>\n compatWrapper(<m.TechDocsIndexPage />),\n ),\n },\n});\n\n/**\n * Component responsible for composing a TechDocs reader page experience\n *\n * @alpha\n */\nconst techDocsReaderPage = PageBlueprint.makeWithOverrides({\n name: 'reader',\n inputs: {\n addons: createExtensionInput([AddonBlueprint.dataRefs.addon]),\n },\n factory(originalFactory, { inputs }) {\n const addons = inputs.addons.map(output => {\n const options = output.get(AddonBlueprint.dataRefs.addon);\n const Addon = options.component;\n attachTechDocsAddonComponentData(Addon, options);\n return <Addon key={options.name} />;\n });\n\n return originalFactory({\n defaultPath: '/docs/:namespace/:kind/:name',\n routeRef: convertLegacyRouteRef(rootDocsRouteRef),\n loader: async () =>\n await import('../Router').then(({ TechDocsReaderRouter }) => {\n return compatWrapper(\n <TechDocsReaderRouter>\n <TechDocsReaderLayout />\n <TechDocsAddons>{addons}</TechDocsAddons>\n </TechDocsReaderRouter>,\n );\n }),\n });\n },\n});\n\n/**\n * Component responsible for rendering techdocs on entity pages\n *\n * @alpha\n */\nconst techDocsEntityContent = EntityContentBlueprint.makeWithOverrides({\n inputs: {\n addons: createExtensionInput([AddonBlueprint.dataRefs.addon]),\n emptyState: createExtensionInput(\n [coreExtensionData.reactElement.optional()],\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n factory(originalFactory, context) {\n return originalFactory(\n {\n defaultPath: 'docs',\n defaultTitle: 'TechDocs',\n routeRef: convertLegacyRouteRef(rootCatalogDocsRouteRef),\n loader: () =>\n import('../Router').then(({ EmbeddedDocsRouter }) => {\n const addons = context.inputs.addons.map(output => {\n const options = output.get(AddonBlueprint.dataRefs.addon);\n const Addon = options.component;\n attachTechDocsAddonComponentData(Addon, options);\n return <Addon key={options.name} />;\n });\n return compatWrapper(\n <EmbeddedDocsRouter\n emptyState={context.inputs.emptyState?.get(\n coreExtensionData.reactElement,\n )}\n >\n <TechDocsAddons>{addons}</TechDocsAddons>\n </EmbeddedDocsRouter>,\n );\n }),\n },\n context,\n );\n },\n});\n\nconst techDocsEntityContentEmptyState = createExtension({\n kind: 'empty-state',\n name: 'entity-content',\n attachTo: { id: 'entity-content:techdocs', input: 'emptyState' },\n output: [coreExtensionData.reactElement.optional()],\n factory: () => [],\n});\n\n/** @alpha */\nconst techDocsNavItem = NavItemBlueprint.make({\n params: {\n icon: LibraryBooks,\n title: 'Docs',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n },\n});\n\n/** @alpha */\nexport default createFrontendPlugin({\n pluginId: 'techdocs',\n info: { packageJson: () => import('../../package.json') },\n extensions: [\n techDocsClientApi,\n techDocsStorageApi,\n techDocsNavItem,\n techDocsPage,\n techDocsReaderPage,\n techdocsEntityIconLink,\n techDocsEntityContent,\n techDocsEntityContentEmptyState,\n techDocsSearchResultListItemExtension,\n ],\n routes: convertLegacyRouteRefs({\n root: rootRouteRef,\n docRoot: rootDocsRouteRef,\n entityContent: rootCatalogDocsRouteRef,\n }),\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAM,sBAAA,GAAyB,wBAAwB,IAAK,CAAA;AAAA,EAC1D,IAAM,EAAA,WAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA;AAGD,MAAM,kBAAA,GAAqB,aAAa,IAAK,CAAA;AAAA,EAC3C,IAAM,EAAA,SAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,SAAS,gBAAiB,CAAA;AAAA,MACxB,GAAK,EAAA,qBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,SAAW,EAAA,YAAA;AAAA,QACX,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,SAAA,EAAW,cAAc,QAAS,EAAA,KAC5C,IAAI,qBAAsB,CAAA;AAAA,QACxB,SAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA,OACD;AAAA,KACJ;AAAA;AAEL,CAAC,CAAA;AAGD,MAAM,iBAAA,GAAoB,aAAa,IAAK,CAAA;AAAA,EAC1C,MAAQ,EAAA;AAAA,IACN,SAAS,gBAAiB,CAAA;AAAA,MACxB,GAAK,EAAA,cAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,SAAW,EAAA,YAAA;AAAA,QACX,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,SAAA,EAAW,cAAc,QAAS,EAAA,KAC5C,IAAI,cAAe,CAAA;AAAA,QACjB,SAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA,OACD;AAAA,KACJ;AAAA;AAEL,CAAC,CAAA;AAGY,MAAA,qCAAA,GACX,8BAA8B,iBAAkB,CAAA;AAAA,EAC9C,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,KAAO,EAAA,CAAA,CAAA,KAAK,CAAE,CAAA,MAAA,GAAS,QAAS,EAAA;AAAA,MAChC,WAAW,CAAK,CAAA,KAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,MACpC,QAAQ,CAAK,CAAA,KAAA,CAAA,CAAE,OAAQ,EAAA,CAAE,QAAQ,IAAI,CAAA;AAAA,MACrC,YAAY,CAAK,CAAA,KAAA,CAAA,CAAE,OAAQ,EAAA,CAAE,QAAQ,IAAI;AAAA;AAC3C,GACF;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,SAAA,EAAW,CAAU,MAAA,KAAA,MAAA,CAAO,IAAS,KAAA,UAAA;AAAA,MACrC,WAAW,YAAY;AACrB,QAAA,MAAM,EAAE,4BAAA,EAAiC,GAAA,MAAM,OAC7C,yDACF,CAAA;AACA,QAAA,OAAO,CACL,KAAA,KAAA,aAAA;AAAA,0BACG,GAAA,CAAA,4BAAA,EAAA,EAA8B,GAAG,KAAA,EAAQ,GAAG,MAAQ,EAAA;AAAA,SACvD;AAAA;AACJ,KACD,CAAA;AAAA;AAEL,CAAC;AAOH,MAAM,YAAA,GAAe,cAAc,IAAK,CAAA;AAAA,EACtC,MAAQ,EAAA;AAAA,IACN,WAAa,EAAA,OAAA;AAAA,IACb,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,IAC5C,MAAQ,EAAA,MACN,OAAO,4CAAsC,CAAE,CAAA,IAAA;AAAA,MAAK,OAClD,aAAc,iBAAA,GAAA,CAAC,CAAE,CAAA,iBAAA,EAAF,EAAoB,CAAE;AAAA;AACvC;AAEN,CAAC,CAAA;AAOD,MAAM,kBAAA,GAAqB,cAAc,iBAAkB,CAAA;AAAA,EACzD,IAAM,EAAA,QAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,QAAQ,oBAAqB,CAAA,CAAC,cAAe,CAAA,QAAA,CAAS,KAAK,CAAC;AAAA,GAC9D;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAA,MAAM,MAAS,GAAA,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,CAAU,MAAA,KAAA;AACzC,MAAA,MAAM,OAAU,GAAA,MAAA,CAAO,GAAI,CAAA,cAAA,CAAe,SAAS,KAAK,CAAA;AACxD,MAAA,MAAM,QAAQ,OAAQ,CAAA,SAAA;AACtB,MAAA,gCAAA,CAAiC,OAAO,OAAO,CAAA;AAC/C,MAAO,uBAAA,GAAA,CAAC,KAAW,EAAA,EAAA,EAAA,OAAA,CAAQ,IAAM,CAAA;AAAA,KAClC,CAAA;AAED,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,WAAa,EAAA,8BAAA;AAAA,MACb,QAAA,EAAU,sBAAsB,gBAAgB,CAAA;AAAA,MAChD,MAAA,EAAQ,YACN,MAAM,OAAO,iBAAW,EAAE,IAAK,CAAA,CAAC,EAAE,oBAAA,EAA2B,KAAA;AAC3D,QAAO,OAAA,aAAA;AAAA,+BACJ,oBACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,oBAAqB,EAAA,EAAA,CAAA;AAAA,4BACtB,GAAA,CAAC,kBAAgB,QAAO,EAAA,MAAA,EAAA;AAAA,WAC1B,EAAA;AAAA,SACF;AAAA,OACD;AAAA,KACJ,CAAA;AAAA;AAEL,CAAC,CAAA;AAOD,MAAM,qBAAA,GAAwB,uBAAuB,iBAAkB,CAAA;AAAA,EACrE,MAAQ,EAAA;AAAA,IACN,QAAQ,oBAAqB,CAAA,CAAC,cAAe,CAAA,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,IAC5D,UAAY,EAAA,oBAAA;AAAA,MACV,CAAC,iBAAA,CAAkB,YAAa,CAAA,QAAA,EAAU,CAAA;AAAA,MAC1C;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,QAAU,EAAA;AAAA;AACZ;AACF,GACF;AAAA,EACA,OAAA,CAAQ,iBAAiB,OAAS,EAAA;AAChC,IAAO,OAAA,eAAA;AAAA,MACL;AAAA,QACE,WAAa,EAAA,MAAA;AAAA,QACb,YAAc,EAAA,UAAA;AAAA,QACd,QAAA,EAAU,sBAAsB,uBAAuB,CAAA;AAAA,QACvD,MAAA,EAAQ,MACN,OAAO,iBAAW,EAAE,IAAK,CAAA,CAAC,EAAE,kBAAA,EAAyB,KAAA;AACnD,UAAA,MAAM,MAAS,GAAA,OAAA,CAAQ,MAAO,CAAA,MAAA,CAAO,IAAI,CAAU,MAAA,KAAA;AACjD,YAAA,MAAM,OAAU,GAAA,MAAA,CAAO,GAAI,CAAA,cAAA,CAAe,SAAS,KAAK,CAAA;AACxD,YAAA,MAAM,QAAQ,OAAQ,CAAA,SAAA;AACtB,YAAA,gCAAA,CAAiC,OAAO,OAAO,CAAA;AAC/C,YAAO,uBAAA,GAAA,CAAC,KAAW,EAAA,EAAA,EAAA,OAAA,CAAQ,IAAM,CAAA;AAAA,WAClC,CAAA;AACD,UAAO,OAAA,aAAA;AAAA,4BACL,GAAA;AAAA,cAAC,kBAAA;AAAA,cAAA;AAAA,gBACC,UAAA,EAAY,OAAQ,CAAA,MAAA,CAAO,UAAY,EAAA,GAAA;AAAA,kBACrC,iBAAkB,CAAA;AAAA,iBACpB;AAAA,gBAEA,QAAA,kBAAA,GAAA,CAAC,kBAAgB,QAAO,EAAA,MAAA,EAAA;AAAA;AAAA;AAC1B,WACF;AAAA,SACD;AAAA,OACL;AAAA,MACA;AAAA,KACF;AAAA;AAEJ,CAAC,CAAA;AAED,MAAM,kCAAkC,eAAgB,CAAA;AAAA,EACtD,IAAM,EAAA,aAAA;AAAA,EACN,IAAM,EAAA,gBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,yBAAA,EAA2B,OAAO,YAAa,EAAA;AAAA,EAC/D,MAAQ,EAAA,CAAC,iBAAkB,CAAA,YAAA,CAAa,UAAU,CAAA;AAAA,EAClD,OAAA,EAAS,MAAM;AACjB,CAAC,CAAA;AAGD,MAAM,eAAA,GAAkB,iBAAiB,IAAK,CAAA;AAAA,EAC5C,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,IACN,KAAO,EAAA,MAAA;AAAA,IACP,QAAA,EAAU,sBAAsB,YAAY;AAAA;AAEhD,CAAC,CAAA;AAGD,YAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,UAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,uBAAoB,CAAE,EAAA;AAAA,EACxD,UAAY,EAAA;AAAA,IACV,iBAAA;AAAA,IACA,kBAAA;AAAA,IACA,eAAA;AAAA,IACA,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,sBAAA;AAAA,IACA,qBAAA;AAAA,IACA,+BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,QAAQ,sBAAuB,CAAA;AAAA,IAC7B,IAAM,EAAA,YAAA;AAAA,IACN,OAAS,EAAA,gBAAA;AAAA,IACT,aAAe,EAAA;AAAA,GAChB;AACH,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha/index.tsx"],"sourcesContent":["/*\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 LibraryBooks from '@material-ui/icons/LibraryBooks';\nimport {\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n NavItemBlueprint,\n createExtensionInput,\n coreExtensionData,\n createExtension,\n} from '@backstage/frontend-plugin-api';\nimport {\n configApiRef,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n compatWrapper,\n convertLegacyRouteRef,\n convertLegacyRouteRefs,\n} from '@backstage/core-compat-api';\nimport {\n EntityContentBlueprint,\n EntityIconLinkBlueprint,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha';\nimport { AddonBlueprint } from '@backstage/plugin-techdocs-react/alpha';\nimport { TechDocsClient, TechDocsStorageClient } from '../client';\nimport {\n rootCatalogDocsRouteRef,\n rootDocsRouteRef,\n rootRouteRef,\n} from '../routes';\nimport { TechDocsReaderLayout } from '../reader';\nimport { attachTechDocsAddonComponentData } from '@backstage/plugin-techdocs-react/alpha';\nimport {\n TechDocsAddons,\n techdocsApiRef,\n techdocsStorageApiRef,\n} from '@backstage/plugin-techdocs-react';\n\nimport { useTechdocsReaderIconLinkProps } from './hooks/useTechdocsReaderIconLinkProps';\n\n/** @alpha */\nconst techdocsEntityIconLink = EntityIconLinkBlueprint.make({\n name: 'read-docs',\n params: {\n useProps: useTechdocsReaderIconLinkProps,\n },\n});\n\n/** @alpha */\nconst techDocsStorageApi = ApiBlueprint.make({\n name: 'storage',\n params: defineParams =>\n defineParams({\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});\n\n/** @alpha */\nconst techDocsClientApi = ApiBlueprint.make({\n params: defineParams =>\n defineParams({\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\n/** @alpha */\nexport const techDocsSearchResultListItemExtension =\n SearchResultListItemBlueprint.makeWithOverrides({\n config: {\n schema: {\n title: z => z.string().optional(),\n lineClamp: z => z.number().default(5),\n asLink: z => z.boolean().default(true),\n asListItem: z => z.boolean().default(true),\n },\n },\n factory(originalFactory, { config }) {\n return originalFactory({\n predicate: result => result.type === 'techdocs',\n component: async () => {\n const { TechDocsSearchResultListItem } = await import(\n '../search/components/TechDocsSearchResultListItem'\n );\n return props =>\n compatWrapper(\n <TechDocsSearchResultListItem {...props} {...config} />,\n );\n },\n });\n },\n });\n\n/**\n * Responsible for rendering the provided router element\n *\n * @alpha\n */\nconst techDocsPage = PageBlueprint.make({\n params: {\n path: '/docs',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n loader: () =>\n import('../home/components/TechDocsIndexPage').then(m =>\n compatWrapper(<m.TechDocsIndexPage />),\n ),\n },\n});\n\n/**\n * Component responsible for composing a TechDocs reader page experience\n *\n * @alpha\n */\nconst techDocsReaderPage = PageBlueprint.makeWithOverrides({\n name: 'reader',\n inputs: {\n addons: createExtensionInput([AddonBlueprint.dataRefs.addon]),\n },\n factory(originalFactory, { inputs }) {\n const addons = inputs.addons.map(output => {\n const options = output.get(AddonBlueprint.dataRefs.addon);\n const Addon = options.component;\n attachTechDocsAddonComponentData(Addon, options);\n return <Addon key={options.name} />;\n });\n\n return originalFactory({\n path: '/docs/:namespace/:kind/:name',\n routeRef: convertLegacyRouteRef(rootDocsRouteRef),\n loader: async () =>\n await import('../Router').then(({ TechDocsReaderRouter }) => {\n return compatWrapper(\n <TechDocsReaderRouter>\n <TechDocsReaderLayout />\n <TechDocsAddons>{addons}</TechDocsAddons>\n </TechDocsReaderRouter>,\n );\n }),\n });\n },\n});\n\n/**\n * Component responsible for rendering techdocs on entity pages\n *\n * @alpha\n */\nconst techDocsEntityContent = EntityContentBlueprint.makeWithOverrides({\n inputs: {\n addons: createExtensionInput([AddonBlueprint.dataRefs.addon]),\n emptyState: createExtensionInput(\n [coreExtensionData.reactElement.optional()],\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n factory(originalFactory, context) {\n return originalFactory(\n {\n path: 'docs',\n title: 'TechDocs',\n routeRef: convertLegacyRouteRef(rootCatalogDocsRouteRef),\n loader: () =>\n import('../Router').then(({ EmbeddedDocsRouter }) => {\n const addons = context.inputs.addons.map(output => {\n const options = output.get(AddonBlueprint.dataRefs.addon);\n const Addon = options.component;\n attachTechDocsAddonComponentData(Addon, options);\n return <Addon key={options.name} />;\n });\n return compatWrapper(\n <EmbeddedDocsRouter\n emptyState={context.inputs.emptyState?.get(\n coreExtensionData.reactElement,\n )}\n >\n <TechDocsAddons>{addons}</TechDocsAddons>\n </EmbeddedDocsRouter>,\n );\n }),\n },\n context,\n );\n },\n});\n\nconst techDocsEntityContentEmptyState = createExtension({\n kind: 'empty-state',\n name: 'entity-content',\n attachTo: { id: 'entity-content:techdocs', input: 'emptyState' },\n output: [coreExtensionData.reactElement.optional()],\n factory: () => [],\n});\n\n/** @alpha */\nconst techDocsNavItem = NavItemBlueprint.make({\n params: {\n icon: LibraryBooks,\n title: 'Docs',\n routeRef: convertLegacyRouteRef(rootRouteRef),\n },\n});\n\n/** @alpha */\nexport default createFrontendPlugin({\n pluginId: 'techdocs',\n info: { packageJson: () => import('../../package.json') },\n extensions: [\n techDocsClientApi,\n techDocsStorageApi,\n techDocsNavItem,\n techDocsPage,\n techDocsReaderPage,\n techdocsEntityIconLink,\n techDocsEntityContent,\n techDocsEntityContentEmptyState,\n techDocsSearchResultListItemExtension,\n ],\n routes: convertLegacyRouteRefs({\n root: rootRouteRef,\n docRoot: rootDocsRouteRef,\n entityContent: rootCatalogDocsRouteRef,\n }),\n});\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  var name = "@backstage/plugin-techdocs";
2
- var version = "1.13.3-next.0";
2
+ var version = "1.14.0-next.2";
3
3
  var description = "The Backstage plugin that renders technical documentation for your components";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
@@ -42,12 +42,37 @@ const useSanitizerTransformer = () => {
42
42
  const attributeNameCheck = config?.getOptionalString(
43
43
  "allowedCustomElementAttributeNameRegExp"
44
44
  );
45
+ const additionalAllowedURIProtocols = config?.getOptionalStringArray("additionalAllowedURIProtocols") || [];
46
+ const allowedURIProtocols = [
47
+ "callto",
48
+ "cid",
49
+ "ftp",
50
+ "ftps",
51
+ "http",
52
+ "https",
53
+ "mailto",
54
+ "matrix",
55
+ "sms",
56
+ "tel",
57
+ "xmpp",
58
+ ...additionalAllowedURIProtocols
59
+ ].filter(Boolean);
60
+ const allowedURIRegExp = new RegExp(
61
+ // This regex is not exposed by DOMPurify, so we need to define it ourselves.
62
+ // It is possible for this to drift from the default in future versions of DOMPurify.
63
+ // See: https://raw.githubusercontent.com/cure53/DOMPurify/master/src/regexp.ts
64
+ `^(?:${allowedURIProtocols.join(
65
+ "|"
66
+ )}:|[^a-z]|[a-z+.-]+(?:[^a-z+.\\-:]|$))`,
67
+ "i"
68
+ );
45
69
  return DOMPurify.sanitize(dom.outerHTML, {
46
70
  ADD_TAGS: tags,
47
71
  FORBID_TAGS: ["style"],
48
72
  ADD_ATTR: ["http-equiv", "content", "dominant-baseline"],
49
73
  WHOLE_DOCUMENT: true,
50
74
  RETURN_DOM: true,
75
+ ALLOWED_URI_REGEXP: allowedURIRegExp,
51
76
  CUSTOM_ELEMENT_HANDLING: {
52
77
  tagNameCheck: tagNameCheck ? new RegExp(tagNameCheck) : void 0,
53
78
  attributeNameCheck: attributeNameCheck ? new RegExp(attributeNameCheck) : void 0
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.esm.js","sources":["../../../../src/reader/transformers/html/transformer.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport DOMPurify from 'dompurify';\nimport { useCallback, useMemo } from 'react';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { Transformer } from '../transformer';\nimport { removeUnsafeIframes, removeUnsafeLinks } 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 return useCallback(\n async (dom: Element) => {\n const hosts = config?.getOptionalStringArray('allowedIframeHosts');\n\n DOMPurify.addHook('beforeSanitizeElements', removeUnsafeLinks);\n const tags = ['link', 'meta'];\n\n if (hosts) {\n tags.push('iframe');\n DOMPurify.addHook('beforeSanitizeElements', removeUnsafeIframes(hosts));\n }\n\n // Only allow meta tags if they are used for refreshing the page. They are required for the redirect feature.\n DOMPurify.addHook('uponSanitizeElement', (currNode, data) => {\n if (data.tagName === 'meta') {\n const isMetaRefreshTag =\n currNode.getAttribute('http-equiv') === 'refresh' &&\n currNode.getAttribute('content')?.includes('url=');\n if (!isMetaRefreshTag) {\n currNode.parentNode?.removeChild(currNode);\n }\n }\n });\n\n // Only allow http-equiv and content attributes on meta tags. They are required for the redirect feature.\n DOMPurify.addHook('uponSanitizeAttribute', (currNode, data) => {\n if (currNode.tagName !== 'meta') {\n if (data.attrName === 'http-equiv' || data.attrName === 'content') {\n currNode.removeAttribute(data.attrName);\n }\n }\n });\n\n const tagNameCheck = config?.getOptionalString(\n 'allowedCustomElementTagNameRegExp',\n );\n const attributeNameCheck = config?.getOptionalString(\n 'allowedCustomElementAttributeNameRegExp',\n );\n\n // using outerHTML as we want to preserve the html tag attributes (lang)\n return DOMPurify.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 CUSTOM_ELEMENT_HANDLING: {\n tagNameCheck: tagNameCheck ? new RegExp(tagNameCheck) : undefined,\n attributeNameCheck: attributeNameCheck\n ? new RegExp(attributeNameCheck)\n : undefined,\n },\n });\n },\n [config],\n );\n};\n"],"names":[],"mappings":";;;;;;AA2BA,MAAM,qBAAqB,MAAM;AAC/B,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAErC,EAAA,OAAO,QAAQ,MAAM;AACnB,IAAO,OAAA,SAAA,CAAU,kBAAkB,oBAAoB,CAAA;AAAA,GACzD,EAAG,CAAC,SAAS,CAAC,CAAA;AAChB,CAAA;AAKO,MAAM,0BAA0B,MAAmB;AACxD,EAAA,MAAM,SAAS,kBAAmB,EAAA;AAElC,EAAO,OAAA,WAAA;AAAA,IACL,OAAO,GAAiB,KAAA;AACtB,MAAM,MAAA,KAAA,GAAQ,MAAQ,EAAA,sBAAA,CAAuB,oBAAoB,CAAA;AAEjE,MAAU,SAAA,CAAA,OAAA,CAAQ,0BAA0B,iBAAiB,CAAA;AAC7D,MAAM,MAAA,IAAA,GAAO,CAAC,MAAA,EAAQ,MAAM,CAAA;AAE5B,MAAA,IAAI,KAAO,EAAA;AACT,QAAA,IAAA,CAAK,KAAK,QAAQ,CAAA;AAClB,QAAA,SAAA,CAAU,OAAQ,CAAA,wBAAA,EAA0B,mBAAoB,CAAA,KAAK,CAAC,CAAA;AAAA;AAIxE,MAAA,SAAA,CAAU,OAAQ,CAAA,qBAAA,EAAuB,CAAC,QAAA,EAAU,IAAS,KAAA;AAC3D,QAAI,IAAA,IAAA,CAAK,YAAY,MAAQ,EAAA;AAC3B,UAAM,MAAA,gBAAA,GACJ,QAAS,CAAA,YAAA,CAAa,YAAY,CAAA,KAAM,SACxC,IAAA,QAAA,CAAS,YAAa,CAAA,SAAS,CAAG,EAAA,QAAA,CAAS,MAAM,CAAA;AACnD,UAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,YAAS,QAAA,CAAA,UAAA,EAAY,YAAY,QAAQ,CAAA;AAAA;AAC3C;AACF,OACD,CAAA;AAGD,MAAA,SAAA,CAAU,OAAQ,CAAA,uBAAA,EAAyB,CAAC,QAAA,EAAU,IAAS,KAAA;AAC7D,QAAI,IAAA,QAAA,CAAS,YAAY,MAAQ,EAAA;AAC/B,UAAA,IAAI,IAAK,CAAA,QAAA,KAAa,YAAgB,IAAA,IAAA,CAAK,aAAa,SAAW,EAAA;AACjE,YAAS,QAAA,CAAA,eAAA,CAAgB,KAAK,QAAQ,CAAA;AAAA;AACxC;AACF,OACD,CAAA;AAED,MAAA,MAAM,eAAe,MAAQ,EAAA,iBAAA;AAAA,QAC3B;AAAA,OACF;AACA,MAAA,MAAM,qBAAqB,MAAQ,EAAA,iBAAA;AAAA,QACjC;AAAA,OACF;AAGA,MAAO,OAAA,SAAA,CAAU,QAAS,CAAA,GAAA,CAAI,SAAW,EAAA;AAAA,QACvC,QAAU,EAAA,IAAA;AAAA,QACV,WAAA,EAAa,CAAC,OAAO,CAAA;AAAA,QACrB,QAAU,EAAA,CAAC,YAAc,EAAA,SAAA,EAAW,mBAAmB,CAAA;AAAA,QACvD,cAAgB,EAAA,IAAA;AAAA,QAChB,UAAY,EAAA,IAAA;AAAA,QACZ,uBAAyB,EAAA;AAAA,UACvB,YAAc,EAAA,YAAA,GAAe,IAAI,MAAA,CAAO,YAAY,CAAI,GAAA,KAAA,CAAA;AAAA,UACxD,kBAAoB,EAAA,kBAAA,GAChB,IAAI,MAAA,CAAO,kBAAkB,CAC7B,GAAA,KAAA;AAAA;AACN,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AACF;;;;"}
1
+ {"version":3,"file":"transformer.esm.js","sources":["../../../../src/reader/transformers/html/transformer.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport DOMPurify from 'dompurify';\nimport { useCallback, useMemo } from 'react';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { Transformer } from '../transformer';\nimport { removeUnsafeIframes, removeUnsafeLinks } 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 return useCallback(\n async (dom: Element) => {\n const hosts = config?.getOptionalStringArray('allowedIframeHosts');\n\n DOMPurify.addHook('beforeSanitizeElements', removeUnsafeLinks);\n const tags = ['link', 'meta'];\n\n if (hosts) {\n tags.push('iframe');\n DOMPurify.addHook('beforeSanitizeElements', removeUnsafeIframes(hosts));\n }\n\n // Only allow meta tags if they are used for refreshing the page. They are required for the redirect feature.\n DOMPurify.addHook('uponSanitizeElement', (currNode, data) => {\n if (data.tagName === 'meta') {\n const isMetaRefreshTag =\n currNode.getAttribute('http-equiv') === 'refresh' &&\n currNode.getAttribute('content')?.includes('url=');\n if (!isMetaRefreshTag) {\n currNode.parentNode?.removeChild(currNode);\n }\n }\n });\n\n // Only allow http-equiv and content attributes on meta tags. They are required for the redirect feature.\n DOMPurify.addHook('uponSanitizeAttribute', (currNode, data) => {\n if (currNode.tagName !== 'meta') {\n if (data.attrName === 'http-equiv' || data.attrName === 'content') {\n currNode.removeAttribute(data.attrName);\n }\n }\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 DOMPurify.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 });\n },\n [config],\n );\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-techdocs",
3
- "version": "1.13.3-next.0",
3
+ "version": "1.14.0-next.2",
4
4
  "description": "The Backstage plugin that renders technical documentation for your components",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -71,23 +71,23 @@
71
71
  "test": "backstage-cli package test"
72
72
  },
73
73
  "dependencies": {
74
- "@backstage/catalog-client": "1.10.2",
74
+ "@backstage/catalog-client": "1.11.0-next.0",
75
75
  "@backstage/catalog-model": "1.7.5",
76
76
  "@backstage/config": "1.3.3",
77
- "@backstage/core-compat-api": "0.4.5-next.0",
78
- "@backstage/core-components": "0.17.4",
77
+ "@backstage/core-compat-api": "0.5.0-next.2",
78
+ "@backstage/core-components": "0.17.5-next.1",
79
79
  "@backstage/core-plugin-api": "1.10.9",
80
80
  "@backstage/errors": "1.2.7",
81
- "@backstage/frontend-plugin-api": "0.10.4",
81
+ "@backstage/frontend-plugin-api": "0.11.0-next.1",
82
82
  "@backstage/integration": "1.17.1",
83
83
  "@backstage/integration-react": "1.2.9",
84
- "@backstage/plugin-auth-react": "0.1.17",
85
- "@backstage/plugin-catalog-react": "1.19.2-next.0",
84
+ "@backstage/plugin-auth-react": "0.1.18-next.0",
85
+ "@backstage/plugin-catalog-react": "1.20.0-next.2",
86
86
  "@backstage/plugin-search-common": "1.2.19",
87
- "@backstage/plugin-search-react": "1.9.2",
87
+ "@backstage/plugin-search-react": "1.9.3-next.1",
88
88
  "@backstage/plugin-techdocs-common": "0.1.1",
89
- "@backstage/plugin-techdocs-react": "1.3.1",
90
- "@backstage/theme": "0.6.7",
89
+ "@backstage/plugin-techdocs-react": "1.3.2-next.0",
90
+ "@backstage/theme": "0.6.8-next.0",
91
91
  "@material-ui/core": "^4.12.2",
92
92
  "@material-ui/icons": "^4.9.1",
93
93
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -101,12 +101,12 @@
101
101
  "react-use": "^17.2.4"
102
102
  },
103
103
  "devDependencies": {
104
- "@backstage/cli": "0.33.1",
104
+ "@backstage/cli": "0.34.0-next.1",
105
105
  "@backstage/core-app-api": "1.18.0",
106
- "@backstage/dev-utils": "1.1.13-next.0",
107
- "@backstage/plugin-catalog": "1.31.2-next.0",
108
- "@backstage/plugin-techdocs-module-addons-contrib": "1.1.26",
109
- "@backstage/test-utils": "1.7.10",
106
+ "@backstage/dev-utils": "1.1.13-next.1",
107
+ "@backstage/plugin-catalog": "1.31.2-next.2",
108
+ "@backstage/plugin-techdocs-module-addons-contrib": "1.1.27-next.0",
109
+ "@backstage/test-utils": "1.7.11-next.0",
110
110
  "@testing-library/dom": "^10.0.0",
111
111
  "@testing-library/jest-dom": "^6.0.0",
112
112
  "@testing-library/react": "^16.0.0",