@nospt/backstage-plugin-apigee 0.1.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.
- package/README.md +19 -0
- package/dist/components/ApiCard.esm.js +146 -0
- package/dist/components/ApiCard.esm.js.map +1 -0
- package/dist/components/ApiCardGrid.esm.js +56 -0
- package/dist/components/ApiCardGrid.esm.js.map +1 -0
- package/dist/components/ApigeeApiCatalogPage.esm.js +139 -0
- package/dist/components/ApigeeApiCatalogPage.esm.js.map +1 -0
- package/dist/components/FilterToolbar.esm.js +197 -0
- package/dist/components/FilterToolbar.esm.js.map +1 -0
- package/dist/components/SearchBar.esm.js +48 -0
- package/dist/components/SearchBar.esm.js.map +1 -0
- package/dist/components/apiCardViewModel.esm.js +41 -0
- package/dist/components/apiCardViewModel.esm.js.map +1 -0
- package/dist/components/apigeeFacetFilters.esm.js +61 -0
- package/dist/components/apigeeFacetFilters.esm.js.map +1 -0
- package/dist/components/apigeeOrgFilter.esm.js +11 -0
- package/dist/components/apigeeOrgFilter.esm.js.map +1 -0
- package/dist/components/apigeeSearchParams.esm.js +20 -0
- package/dist/components/apigeeSearchParams.esm.js.map +1 -0
- package/dist/components/categoryIcons.esm.js +63 -0
- package/dist/components/categoryIcons.esm.js.map +1 -0
- package/dist/components/facetModel.esm.js +78 -0
- package/dist/components/facetModel.esm.js.map +1 -0
- package/dist/components/grouping.esm.js +31 -0
- package/dist/components/grouping.esm.js.map +1 -0
- package/dist/components/states.esm.js +95 -0
- package/dist/components/states.esm.js.map +1 -0
- package/dist/components/useApigeeFilters.esm.js +86 -0
- package/dist/components/useApigeeFilters.esm.js.map +1 -0
- package/dist/components/useDebouncedValue.esm.js +13 -0
- package/dist/components/useDebouncedValue.esm.js.map +1 -0
- package/dist/constants.esm.js +8 -0
- package/dist/constants.esm.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +33 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +6 -0
- package/dist/routes.esm.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { useSearchParams } from 'react-router-dom';
|
|
3
|
+
import { useEntityList } from '@backstage/plugin-catalog-react';
|
|
4
|
+
import { FieldFacetFilter, entityCategoryFacet, entityOwnerLabel, entityOrg, entityLifecycle, ApiSearchFilter } from './apigeeFacetFilters.esm.js';
|
|
5
|
+
import { parseSearchParams } from './apigeeSearchParams.esm.js';
|
|
6
|
+
import { useDebouncedValue } from './useDebouncedValue.esm.js';
|
|
7
|
+
|
|
8
|
+
const FACET_EXTRACT = {
|
|
9
|
+
lifecycle: entityLifecycle,
|
|
10
|
+
org: entityOrg,
|
|
11
|
+
owner: entityOwnerLabel,
|
|
12
|
+
category: entityCategoryFacet
|
|
13
|
+
};
|
|
14
|
+
const FILTER_KEY = {
|
|
15
|
+
lifecycle: "apigeeLifecycle",
|
|
16
|
+
org: "apigeeOrgFacet",
|
|
17
|
+
owner: "apigeeOwner",
|
|
18
|
+
category: "apigeeCategory"
|
|
19
|
+
};
|
|
20
|
+
function useApigeeFilters() {
|
|
21
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
22
|
+
const { updateFilters } = useEntityList();
|
|
23
|
+
const spString = searchParams.toString();
|
|
24
|
+
const state = useMemo(() => parseSearchParams(searchParams), [spString]);
|
|
25
|
+
const [inputValue, setInputValue] = useState(() => state.q);
|
|
26
|
+
const debouncedQ = useDebouncedValue(inputValue, 200);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setSearchParams(
|
|
29
|
+
(prev) => {
|
|
30
|
+
const next = new URLSearchParams(prev);
|
|
31
|
+
if (debouncedQ.trim()) {
|
|
32
|
+
next.set("q", debouncedQ.trim());
|
|
33
|
+
} else {
|
|
34
|
+
next.delete("q");
|
|
35
|
+
}
|
|
36
|
+
return next;
|
|
37
|
+
},
|
|
38
|
+
{ replace: true }
|
|
39
|
+
);
|
|
40
|
+
}, [debouncedQ, setSearchParams]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const patch = {};
|
|
43
|
+
Object.keys(FILTER_KEY).forEach((k) => {
|
|
44
|
+
patch[FILTER_KEY[k]] = state.selected[k].length ? new FieldFacetFilter(FACET_EXTRACT[k], state.selected[k]) : void 0;
|
|
45
|
+
});
|
|
46
|
+
patch.apigeeSearch = state.q.trim() ? new ApiSearchFilter(state.q) : void 0;
|
|
47
|
+
updateFilters(patch);
|
|
48
|
+
}, [spString, updateFilters]);
|
|
49
|
+
const toggleFacet = useCallback(
|
|
50
|
+
(key, value) => {
|
|
51
|
+
setSearchParams(
|
|
52
|
+
(prev) => {
|
|
53
|
+
const next = new URLSearchParams(prev);
|
|
54
|
+
const cur = next.getAll(key);
|
|
55
|
+
next.delete(key);
|
|
56
|
+
const after = cur.includes(value) ? cur.filter((v) => v !== value) : [...cur, value];
|
|
57
|
+
after.forEach((v) => next.append(key, v));
|
|
58
|
+
return next;
|
|
59
|
+
},
|
|
60
|
+
{ replace: true }
|
|
61
|
+
);
|
|
62
|
+
},
|
|
63
|
+
[setSearchParams]
|
|
64
|
+
);
|
|
65
|
+
const clearFacet = useCallback(
|
|
66
|
+
(key) => {
|
|
67
|
+
setSearchParams(
|
|
68
|
+
(prev) => {
|
|
69
|
+
const next = new URLSearchParams(prev);
|
|
70
|
+
next.delete(key);
|
|
71
|
+
return next;
|
|
72
|
+
},
|
|
73
|
+
{ replace: true }
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
[setSearchParams]
|
|
77
|
+
);
|
|
78
|
+
const clearAll = useCallback(() => {
|
|
79
|
+
setInputValue("");
|
|
80
|
+
setSearchParams(new URLSearchParams(), { replace: true });
|
|
81
|
+
}, [setSearchParams]);
|
|
82
|
+
return { state, inputValue, setInputValue, toggleFacet, clearFacet, clearAll };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { useApigeeFilters };
|
|
86
|
+
//# sourceMappingURL=useApigeeFilters.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useApigeeFilters.esm.js","sources":["../../src/components/useApigeeFilters.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\r\nimport { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { useSearchParams } from 'react-router-dom';\r\nimport { useEntityList } from '@backstage/plugin-catalog-react';\r\nimport type { Entity } from '@backstage/catalog-model';\r\nimport {\r\n ApiSearchFilter,\r\n FieldFacetFilter,\r\n entityCategoryFacet,\r\n entityLifecycle,\r\n entityOrg,\r\n entityOwnerLabel,\r\n} from './apigeeFacetFilters';\r\nimport { parseSearchParams } from './apigeeSearchParams';\r\nimport { useDebouncedValue } from './useDebouncedValue';\r\nimport type { ApigeeFilters } from './ApigeeApiCatalogPage';\r\nimport type { FacetKey } from './facetModel';\r\n\r\n/**\r\n * Value extractor per facet slot used to build the FILTER. Category uses the FACET extractor\r\n * (undefined → 'other'), so selecting the 'other' bucket matches uncategorised APIs — search uses\r\n * the real slug instead (06-01).\r\n */\r\nconst FACET_EXTRACT: Record<FacetKey, (e: Entity) => string | undefined> = {\r\n lifecycle: entityLifecycle,\r\n org: entityOrg,\r\n owner: entityOwnerLabel,\r\n category: entityCategoryFacet,\r\n};\r\n\r\n/** Facet slot → the `ApigeeFilters` key its `FieldFacetFilter` registers under. */\r\ntype FacetFilterKey =\r\n | 'apigeeLifecycle'\r\n | 'apigeeOrgFacet'\r\n | 'apigeeOwner'\r\n | 'apigeeCategory';\r\nconst FILTER_KEY: Record<FacetKey, FacetFilterKey> = {\r\n lifecycle: 'apigeeLifecycle',\r\n org: 'apigeeOrgFacet',\r\n owner: 'apigeeOwner',\r\n category: 'apigeeCategory',\r\n};\r\n\r\n/**\r\n * The `useSearchParams` ⇄ `updateFilters` bridge: the URL is the single source of truth. It parses\r\n * the clean facet + `q` keys into state, drives the provider's in-memory filters one-directionally\r\n * (URL → `updateFilters`, no re-fetch), and writes every change back with `{ replace: true }` (D-08)\r\n * so the address bar stays clean, shareable and reload-safe (UI-09). The search box keeps one local\r\n * `inputValue` (instant echo) with a single 200 ms trailing debounce (D-09) → URL; the URL never\r\n * writes back into the input, so there is no feedback loop (UI-06, UI-07).\r\n */\r\nexport function useApigeeFilters() {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const { updateFilters } = useEntityList<ApigeeFilters>();\r\n\r\n // Depend on the stable STRING, not the per-render URLSearchParams object (Pitfall 4).\r\n const spString = searchParams.toString();\r\n const state = useMemo(() => parseSearchParams(searchParams), [spString]); // eslint-disable-line\r\n\r\n // Search text is the only local state; seeded once from the URL.\r\n const [inputValue, setInputValue] = useState(() => state.q);\r\n const debouncedQ = useDebouncedValue(inputValue, 200); // D-09\r\n\r\n // E2: debounced q → URL (replace), merged with the current facet params.\r\n useEffect(() => {\r\n setSearchParams(\r\n prev => {\r\n const next = new URLSearchParams(prev);\r\n if (debouncedQ.trim()) {\r\n next.set('q', debouncedQ.trim());\r\n } else {\r\n next.delete('q');\r\n }\r\n return next;\r\n },\r\n { replace: true },\r\n );\r\n }, [debouncedQ, setSearchParams]);\r\n\r\n // E1: URL → provider filters (one-directional). Runs on mount (seeds shared links) + on change.\r\n useEffect(() => {\r\n const patch: Partial<ApigeeFilters> = {};\r\n (Object.keys(FILTER_KEY) as FacetKey[]).forEach(k => {\r\n patch[FILTER_KEY[k]] = state.selected[k].length\r\n ? new FieldFacetFilter(FACET_EXTRACT[k], state.selected[k])\r\n : undefined;\r\n });\r\n patch.apigeeSearch = state.q.trim()\r\n ? new ApiSearchFilter(state.q)\r\n : undefined;\r\n updateFilters(patch);\r\n }, [spString, updateFilters]); // eslint-disable-line\r\n\r\n const toggleFacet = useCallback(\r\n (key: FacetKey, value: string) => {\r\n setSearchParams(\r\n prev => {\r\n const next = new URLSearchParams(prev);\r\n const cur = next.getAll(key);\r\n next.delete(key);\r\n const after = cur.includes(value)\r\n ? cur.filter(v => v !== value)\r\n : [...cur, value];\r\n after.forEach(v => next.append(key, v));\r\n return next;\r\n },\r\n { replace: true },\r\n );\r\n },\r\n [setSearchParams],\r\n );\r\n\r\n const clearFacet = useCallback(\r\n (key: FacetKey) => {\r\n setSearchParams(\r\n prev => {\r\n const next = new URLSearchParams(prev);\r\n next.delete(key);\r\n return next;\r\n },\r\n { replace: true },\r\n );\r\n },\r\n [setSearchParams],\r\n );\r\n\r\n const clearAll = useCallback(() => {\r\n setInputValue('');\r\n setSearchParams(new URLSearchParams(), { replace: true });\r\n }, [setSearchParams]);\r\n\r\n return { state, inputValue, setInputValue, toggleFacet, clearFacet, clearAll };\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useDebouncedValue(value, delayMs) {
|
|
4
|
+
const [debounced, setDebounced] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const id = setTimeout(() => setDebounced(value), delayMs);
|
|
7
|
+
return () => clearTimeout(id);
|
|
8
|
+
}, [value, delayMs]);
|
|
9
|
+
return debounced;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { useDebouncedValue };
|
|
13
|
+
//# sourceMappingURL=useDebouncedValue.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebouncedValue.esm.js","sources":["../../src/components/useDebouncedValue.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\r\nimport { useEffect, useState } from 'react';\r\n\r\n/**\r\n * Trailing-edge debounce: returns `value` immediately, then re-emits the latest `value`\r\n * after `delayMs` of no change. Rapid successive changes cancel the prior timer via\r\n * `clearTimeout`, so only the trailing value is emitted. No external dependency (D-09).\r\n */\r\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\r\n const [debounced, setDebounced] = useState(value);\r\n useEffect(() => {\r\n const id = setTimeout(() => setDebounced(value), delayMs);\r\n return () => clearTimeout(id);\r\n }, [value, delayMs]);\r\n return debounced;\r\n}\r\n"],"names":[],"mappings":";;AAQO,SAAS,iBAAA,CAAqB,OAAU,OAAA,EAAoB;AACjE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,KAAK,UAAA,CAAW,MAAM,YAAA,CAAa,KAAK,GAAG,OAAO,CAAA;AACxD,IAAA,OAAO,MAAM,aAAa,EAAE,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AACnB,EAAA,OAAO,SAAA;AACT;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const ANNOTATION_APIGEE_ORGS = "apigee.com/orgs";
|
|
2
|
+
const ANNOTATION_APIGEE_ORG = "apigee.com/org";
|
|
3
|
+
const ANNOTATION_HAS_SPEC = "apigee.com/has-spec";
|
|
4
|
+
const ANNOTATION_CATEGORY = "apigee.com/category";
|
|
5
|
+
const ANNOTATION_API_HUB_VERSION = "apigee.com/api-hub-version";
|
|
6
|
+
|
|
7
|
+
export { ANNOTATION_APIGEE_ORG, ANNOTATION_APIGEE_ORGS, ANNOTATION_API_HUB_VERSION, ANNOTATION_CATEGORY, ANNOTATION_HAS_SPEC };
|
|
8
|
+
//# sourceMappingURL=constants.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.esm.js","sources":["../src/constants.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\r\n// Apigee catalog annotation keys. Authoritative source:\r\n// plugins/apigee-backend/src/lib/entity-builder.ts (verified 2026-07-09).\r\n\r\n/** Org annotation written by proxyToEntities (PLURAL, proxy-derived API entities). */\r\nexport const ANNOTATION_APIGEE_ORGS = 'apigee.com/orgs';\r\n/** Org annotation written by hubOnlyToEntity (SINGULAR, hub-only API entities). */\r\nexport const ANNOTATION_APIGEE_ORG = 'apigee.com/org';\r\n/** 'true' | 'false' — set by applyHubMetadata when a spec is embedded or linked. */\r\nexport const ANNOTATION_HAS_SPEC = 'apigee.com/has-spec';\r\n/** Comma-joined slugified categories (absent in the current seed dump). */\r\nexport const ANNOTATION_CATEGORY = 'apigee.com/category';\r\n/** Full API Hub resource name — present only on hub-only entities. */\r\nexport const ANNOTATION_API_HUB_ID = 'apigee.com/api-hub-id';\r\n/**\r\n * Best-effort API Hub version key (A3 — not yet emitted by the backend, absent in the seed).\r\n * The view-model HIDES the version line when this is absent (D-05).\r\n */\r\nexport const ANNOTATION_API_HUB_VERSION = 'apigee.com/api-hub-version';\r\n"],"names":[],"mappings":"AAKO,MAAM,sBAAA,GAAyB;AAE/B,MAAM,qBAAA,GAAwB;AAE9B,MAAM,mBAAA,GAAsB;AAE5B,MAAM,mBAAA,GAAsB;AAO5B,MAAM,0BAAA,GAA6B;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
|
+
|
|
4
|
+
declare const apigeePlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
|
|
5
|
+
root: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
6
|
+
}, {}, {
|
|
7
|
+
"nav-item:apigee": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
8
|
+
kind: "nav-item";
|
|
9
|
+
name: undefined;
|
|
10
|
+
config: {};
|
|
11
|
+
configInput: {};
|
|
12
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
13
|
+
title: string;
|
|
14
|
+
icon: _backstage_frontend_plugin_api.IconComponent;
|
|
15
|
+
routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
16
|
+
}, "core.nav-item.target", {}>;
|
|
17
|
+
inputs: {};
|
|
18
|
+
params: {
|
|
19
|
+
title: string;
|
|
20
|
+
icon: _backstage_frontend_plugin_api.IconComponent;
|
|
21
|
+
routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
24
|
+
"page:apigee": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
25
|
+
kind: "page";
|
|
26
|
+
name: undefined;
|
|
27
|
+
config: {
|
|
28
|
+
path: string | undefined;
|
|
29
|
+
title: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
configInput: {
|
|
32
|
+
title?: string | undefined;
|
|
33
|
+
path?: string | undefined;
|
|
34
|
+
};
|
|
35
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
36
|
+
optional: true;
|
|
37
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
|
|
38
|
+
optional: true;
|
|
39
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
40
|
+
optional: true;
|
|
41
|
+
}>;
|
|
42
|
+
inputs: {
|
|
43
|
+
pages: _backstage_frontend_plugin_api.ExtensionInput<_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", {
|
|
44
|
+
optional: true;
|
|
45
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
|
|
46
|
+
optional: true;
|
|
47
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
48
|
+
optional: true;
|
|
49
|
+
}>, {
|
|
50
|
+
singleton: false;
|
|
51
|
+
optional: false;
|
|
52
|
+
internal: false;
|
|
53
|
+
}>;
|
|
54
|
+
};
|
|
55
|
+
params: {
|
|
56
|
+
path: string;
|
|
57
|
+
title?: string;
|
|
58
|
+
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
59
|
+
loader?: () => Promise<react.JSX.Element>;
|
|
60
|
+
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
61
|
+
noHeader?: boolean;
|
|
62
|
+
};
|
|
63
|
+
}>;
|
|
64
|
+
}>;
|
|
65
|
+
|
|
66
|
+
export { apigeePlugin as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { PageBlueprint, NavItemBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import LayersIcon from '@material-ui/icons/Layers';
|
|
4
|
+
import { rootRouteRef } from './routes.esm.js';
|
|
5
|
+
|
|
6
|
+
const apigeePage = PageBlueprint.make({
|
|
7
|
+
params: {
|
|
8
|
+
title: "API Catalog",
|
|
9
|
+
routeRef: rootRouteRef,
|
|
10
|
+
path: "/apigee",
|
|
11
|
+
loader: () => import('./components/ApigeeApiCatalogPage.esm.js').then(
|
|
12
|
+
({ ApigeeApiCatalogPage }) => /* @__PURE__ */ jsx(ApigeeApiCatalogPage, {})
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const apigeeNavItem = NavItemBlueprint.make({
|
|
17
|
+
params: {
|
|
18
|
+
title: "API Catalog",
|
|
19
|
+
icon: LayersIcon,
|
|
20
|
+
routeRef: rootRouteRef
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const apigeePlugin = createFrontendPlugin({
|
|
24
|
+
pluginId: "apigee",
|
|
25
|
+
title: "API Catalog",
|
|
26
|
+
extensions: [apigeePage, apigeeNavItem],
|
|
27
|
+
routes: {
|
|
28
|
+
root: rootRouteRef
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export { apigeeNavItem, apigeePage, apigeePlugin };
|
|
33
|
+
//# sourceMappingURL=plugin.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\r\nimport {\r\n createFrontendPlugin,\r\n NavItemBlueprint,\r\n PageBlueprint,\r\n} from '@backstage/frontend-plugin-api';\r\nimport LayersIcon from '@material-ui/icons/Layers';\r\nimport { rootRouteRef } from './routes';\r\n\r\nexport const apigeePage = PageBlueprint.make({\r\n params: {\r\n title: 'API Catalog',\r\n routeRef: rootRouteRef,\r\n path: '/apigee',\r\n loader: () =>\r\n import('./components/ApigeeApiCatalogPage').then(\r\n ({ ApigeeApiCatalogPage }) => <ApigeeApiCatalogPage />,\r\n ),\r\n },\r\n});\r\n\r\nexport const apigeeNavItem = NavItemBlueprint.make({\r\n params: {\r\n title: 'API Catalog',\r\n icon: LayersIcon,\r\n routeRef: rootRouteRef,\r\n },\r\n});\r\n\r\nexport const apigeePlugin = createFrontendPlugin({\r\n pluginId: 'apigee',\r\n title: 'API Catalog',\r\n extensions: [apigeePage, apigeeNavItem],\r\n routes: {\r\n root: rootRouteRef,\r\n },\r\n});\r\n"],"names":[],"mappings":";;;;;AASO,MAAM,UAAA,GAAa,cAAc,IAAA,CAAK;AAAA,EAC3C,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,YAAA;AAAA,IACV,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,MACN,OAAO,0CAAmC,CAAA,CAAE,IAAA;AAAA,MAC1C,CAAC,EAAE,oBAAA,EAAqB,yBAAO,oBAAA,EAAA,EAAqB;AAAA;AACtD;AAEN,CAAC;AAEM,MAAM,aAAA,GAAgB,iBAAiB,IAAA,CAAK;AAAA,EACjD,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,aAAA;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAC;AAEM,MAAM,eAAe,oBAAA,CAAqB;AAAA,EAC/C,QAAA,EAAU,QAAA;AAAA,EACV,KAAA,EAAO,aAAA;AAAA,EACP,UAAA,EAAY,CAAC,UAAA,EAAY,aAAa,CAAA;AAAA,EACtC,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\r\nimport { createRouteRef } from '@backstage/frontend-plugin-api';\r\n\r\nexport const rootRouteRef = createRouteRef();\r\n"],"names":[],"mappings":";;AAGO,MAAM,eAAe,cAAA;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nospt/backstage-plugin-apigee",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Backstage frontend plugin bootstrap for Apigee integration",
|
|
6
|
+
"author": "NOS SGPS, S.A.",
|
|
7
|
+
"homepage": "https://github.com/nosportugal/backstage-plugin-apigee#readme",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"backstage",
|
|
10
|
+
"backstage-plugin",
|
|
11
|
+
"apigee"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/nosportugal/backstage-plugin-apigee",
|
|
16
|
+
"directory": "plugins/apigee"
|
|
17
|
+
},
|
|
18
|
+
"main": "dist/index.esm.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"main": "dist/index.esm.js",
|
|
23
|
+
"types": "dist/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"backstage": {
|
|
26
|
+
"role": "frontend-plugin",
|
|
27
|
+
"pluginId": "apigee",
|
|
28
|
+
"pluginPackages": [
|
|
29
|
+
"@nospt/backstage-plugin-apigee",
|
|
30
|
+
"@nospt/backstage-plugin-apigee-backend",
|
|
31
|
+
"@nospt/backstage-plugin-apigee-common"
|
|
32
|
+
],
|
|
33
|
+
"features": {
|
|
34
|
+
".": "@backstage/FrontendPlugin"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"sideEffects": false,
|
|
38
|
+
"scripts": {
|
|
39
|
+
"start": "backstage-cli package start",
|
|
40
|
+
"build": "backstage-cli package build",
|
|
41
|
+
"lint": "backstage-cli package lint",
|
|
42
|
+
"test": "backstage-cli package test",
|
|
43
|
+
"test:e2e": "playwright test",
|
|
44
|
+
"clean": "backstage-cli package clean",
|
|
45
|
+
"prepack": "backstage-cli package prepack",
|
|
46
|
+
"postpack": "backstage-cli package postpack"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@backstage/catalog-model": "^1.9.0",
|
|
50
|
+
"@backstage/core-components": "^0.18.8",
|
|
51
|
+
"@backstage/core-plugin-api": "^1.10.3",
|
|
52
|
+
"@backstage/frontend-plugin-api": "^0.15.1",
|
|
53
|
+
"@backstage/plugin-catalog-react": "^2.1.1",
|
|
54
|
+
"@material-ui/core": "^4.9.13",
|
|
55
|
+
"@material-ui/icons": "^4.9.1",
|
|
56
|
+
"@nospt/backstage-plugin-apigee-common": "workspace:^"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
60
|
+
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
61
|
+
"react-router-dom": "^6.0.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@backstage/cli": "^0.36.0",
|
|
65
|
+
"@backstage/frontend-defaults": "^0.5.0",
|
|
66
|
+
"@backstage/frontend-test-utils": "^0.5.1",
|
|
67
|
+
"@backstage/plugin-app-react": "^0.2.2",
|
|
68
|
+
"@backstage/plugin-catalog": "^2.0.1",
|
|
69
|
+
"@backstage/ui": "^0.13.2",
|
|
70
|
+
"@playwright/test": "^1.49.0",
|
|
71
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
72
|
+
"@testing-library/react": "^14.0.0",
|
|
73
|
+
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
74
|
+
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
75
|
+
"react-router-dom": "^6.0.0"
|
|
76
|
+
},
|
|
77
|
+
"files": [
|
|
78
|
+
"dist",
|
|
79
|
+
"README.md"
|
|
80
|
+
],
|
|
81
|
+
"typesVersions": {
|
|
82
|
+
"*": {
|
|
83
|
+
"package.json": [
|
|
84
|
+
"package.json"
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"module": "./dist/index.esm.js"
|
|
89
|
+
}
|