@kartverket/backstage-plugin-risk-scorecard 6.12.1 → 8.0.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/config.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export interface Config {
2
+ riskScorecard?: {
3
+ appliesTo?: {
4
+ /**
5
+ * Whether the applies-to picker should include all catalog entities, not
6
+ * only entities in the current system.
7
+ */
8
+ includeAllEntities?: boolean;
9
+ };
10
+ };
11
+ }
@@ -12,7 +12,7 @@ function ChangeSetTrackedProperty({
12
12
  emphasised = false,
13
13
  valueFormatter = (value) => value
14
14
  }) {
15
- if (property === void 0) return /* @__PURE__ */ jsx(Fragment, {});
15
+ if (property === void 0 || property === null) return /* @__PURE__ */ jsx(Fragment, {});
16
16
  if (property.type === "UNCHANGED")
17
17
  return /* @__PURE__ */ jsx(
18
18
  ChangeSetProperty,
@@ -1 +1 @@
1
- {"version":3,"file":"ChangeSetTrackedProperty.esm.js","sources":["../../../../../src/components/riScInfo/changeset/components/ChangeSetTrackedProperty.tsx"],"sourcesContent":["import { SimpleTrackedProperty } from '../../../../utils/types.ts';\nimport { ChangeSetProperty } from './ChangeSetProperty.tsx';\nimport { ChangeSetChangedProperty } from './ChangeSetChangedProperty.tsx';\n\ninterface IChangeSetTrackedProperty {\n title: string;\n property?: SimpleTrackedProperty<any>;\n multiline?: boolean;\n stringOnUndefinedProperty?: string;\n compact?: boolean;\n unit?: string;\n emphasised?: boolean;\n valueFormatter?: (value: any) => any;\n}\n\nexport function ChangeSetTrackedProperty({\n title,\n property,\n multiline = false,\n compact = false,\n unit = undefined,\n stringOnUndefinedProperty,\n emphasised = false,\n valueFormatter = (value: string) => value,\n}: IChangeSetTrackedProperty) {\n if (property === undefined) return <></>;\n\n if (property.type === 'UNCHANGED')\n return (\n <ChangeSetProperty\n title={title}\n value={\n property.value\n ? valueFormatter(property.value)\n : stringOnUndefinedProperty\n }\n compact={compact}\n unit={unit}\n emphasised={emphasised}\n />\n );\n if (property.type === 'CHANGED')\n return (\n <ChangeSetChangedProperty\n propertyName={title}\n oldValue={\n property.oldValue ? (\n valueFormatter(property.oldValue)\n ) : (\n <i>{stringOnUndefinedProperty}</i>\n )\n }\n newValue={\n property.newValue ? (\n valueFormatter(property.newValue)\n ) : (\n <i>{stringOnUndefinedProperty}</i>\n )\n }\n compact={compact}\n unit={unit}\n multiline={multiline}\n />\n );\n\n return <></>;\n}\n"],"names":[],"mappings":";;;;AAeO,SAAS,wBAAA,CAAyB;AAAA,EACvC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,MAAA;AAAA,EACP,yBAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,cAAA,GAAiB,CAAC,KAAA,KAAkB;AACtC,CAAA,EAA8B;AAC5B,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAE,CAAA;AAErC,EAAA,IAAI,SAAS,IAAA,KAAS,WAAA;AACpB,IAAA,uBACE,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,OACE,QAAA,CAAS,KAAA,GACL,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,GAC7B,yBAAA;AAAA,QAEN,OAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA;AAAA,KACF;AAEJ,EAAA,IAAI,SAAS,IAAA,KAAS,SAAA;AACpB,IAAA,uBACE,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAc,KAAA;AAAA,QACd,QAAA,EACE,SAAS,QAAA,GACP,cAAA,CAAe,SAAS,QAAQ,CAAA,mBAEhC,GAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,yBAAA,EAA0B,CAAA;AAAA,QAGlC,QAAA,EACE,SAAS,QAAA,GACP,cAAA,CAAe,SAAS,QAAQ,CAAA,mBAEhC,GAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,yBAAA,EAA0B,CAAA;AAAA,QAGlC,OAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA;AAAA,KACF;AAGJ,EAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAE,CAAA;AACX;;;;"}
1
+ {"version":3,"file":"ChangeSetTrackedProperty.esm.js","sources":["../../../../../src/components/riScInfo/changeset/components/ChangeSetTrackedProperty.tsx"],"sourcesContent":["import { SimpleTrackedProperty } from '../../../../utils/types.ts';\nimport { ChangeSetProperty } from './ChangeSetProperty.tsx';\nimport { ChangeSetChangedProperty } from './ChangeSetChangedProperty.tsx';\n\ninterface IChangeSetTrackedProperty {\n title: string;\n property?: SimpleTrackedProperty<any>;\n multiline?: boolean;\n stringOnUndefinedProperty?: string;\n compact?: boolean;\n unit?: string;\n emphasised?: boolean;\n valueFormatter?: (value: any) => any;\n}\n\nexport function ChangeSetTrackedProperty({\n title,\n property,\n multiline = false,\n compact = false,\n unit = undefined,\n stringOnUndefinedProperty,\n emphasised = false,\n valueFormatter = (value: string) => value,\n}: IChangeSetTrackedProperty) {\n if (property === undefined || property === null) return <></>;\n\n if (property.type === 'UNCHANGED')\n return (\n <ChangeSetProperty\n title={title}\n value={\n property.value\n ? valueFormatter(property.value)\n : stringOnUndefinedProperty\n }\n compact={compact}\n unit={unit}\n emphasised={emphasised}\n />\n );\n if (property.type === 'CHANGED')\n return (\n <ChangeSetChangedProperty\n propertyName={title}\n oldValue={\n property.oldValue ? (\n valueFormatter(property.oldValue)\n ) : (\n <i>{stringOnUndefinedProperty}</i>\n )\n }\n newValue={\n property.newValue ? (\n valueFormatter(property.newValue)\n ) : (\n <i>{stringOnUndefinedProperty}</i>\n )\n }\n compact={compact}\n unit={unit}\n multiline={multiline}\n />\n );\n\n return <></>;\n}\n"],"names":[],"mappings":";;;;AAeO,SAAS,wBAAA,CAAyB;AAAA,EACvC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,MAAA;AAAA,EACP,yBAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,cAAA,GAAiB,CAAC,KAAA,KAAkB;AACtC,CAAA,EAA8B;AAC5B,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,QAAA,KAAa,IAAA,yBAAa,GAAA,CAAA,QAAA,EAAA,EAAE,CAAA;AAE1D,EAAA,IAAI,SAAS,IAAA,KAAS,WAAA;AACpB,IAAA,uBACE,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,OACE,QAAA,CAAS,KAAA,GACL,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,GAC7B,yBAAA;AAAA,QAEN,OAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA;AAAA,KACF;AAEJ,EAAA,IAAI,SAAS,IAAA,KAAS,SAAA;AACpB,IAAA,uBACE,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAc,KAAA;AAAA,QACd,QAAA,EACE,SAAS,QAAA,GACP,cAAA,CAAe,SAAS,QAAQ,CAAA,mBAEhC,GAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,yBAAA,EAA0B,CAAA;AAAA,QAGlC,QAAA,EACE,SAAS,QAAA,GACP,cAAA,CAAe,SAAS,QAAQ,CAAA,mBAEhC,GAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,yBAAA,EAA0B,CAAA;AAAA,QAGlC,OAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA;AAAA,KACF;AAGJ,EAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAE,CAAA;AACX;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as react from 'react';
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
3
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
4
4
 
5
- declare function PluginRoot(): react_jsx_runtime.JSX.Element;
5
+ declare function PluginRoot(): react.JSX.Element;
6
6
 
7
7
  declare const riScPlugin: _backstage_core_plugin_api.BackstagePlugin<{
8
8
  root: _backstage_core_plugin_api.RouteRef<undefined>;
@@ -18,6 +18,24 @@ const BACKEND_URLS = {
18
18
  // (1)
19
19
  fetchDefaultRiScTypeDescriptors: "/api/proxy/risc-proxy/api/initrisc"
20
20
  };
21
+ function buildNativeBackendUrls({
22
+ baseUrl,
23
+ owner,
24
+ repo,
25
+ version
26
+ }) {
27
+ const riScUri = `${baseUrl}/risc/${owner}/${repo}`;
28
+ return {
29
+ riScUri,
30
+ uriToFetchAllRiScs: `${riScUri}/${version}/all`,
31
+ uriToFetchDifference: (id) => `${riScUri}/${id}/difference`,
32
+ uriToFetchRiSc: (id) => `${riScUri}/${id}`,
33
+ uriToDeleteRiSc: (id) => `${riScUri}/${id}`,
34
+ uriToPublishRiSc: (id) => `${riScUri}/publish/${id}`,
35
+ uriToFetchGcpCryptoKeys: `${baseUrl}/google/gcpCryptoKeys`,
36
+ uriToFetchDefaultRiScDescriptors: `${baseUrl}/initrisc`
37
+ };
38
+ }
21
39
 
22
- export { BACKEND_URLS };
40
+ export { BACKEND_URLS, buildNativeBackendUrls };
23
41
  //# sourceMappingURL=backend.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"backend.esm.js","sources":["../../src/urls/backend.ts"],"sourcesContent":["// prettier-ignore\n\n// (1) Requires a method to inject tokens. Not yet implemented.\n// (2) Temporary primitive url until method (1) is implemented.\n\nexport const BACKEND_URLS = {\n\tgoogle_gcpCryptoKeys: '/api/proxy/risc-proxy/api/google/gcpCryptoKeys',\n\triScUri: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName', // (1)\n\triScUri_temp: '/api/proxy/risc-proxy/api/risc', // (2)\n\topen_pr: '/api/proxy/risc-proxy/api/sops/:repoOwner/:repoName/openPullRequest/:branch', // (1)\n\tfetchAllRiScs: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:version/all', // (1)\n\tfetchDifference: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id/difference', // (1)\n\tfetchRiSc: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id', // (1)\n deleteRiSc: 'api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id', // (1)\n\tpublishRiSc: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/publish/:id', // (1)\n fetchDefaultRiScTypeDescriptors: '/api/proxy/risc-proxy/api/initrisc'\n};\n"],"names":[],"mappings":"AAKO,MAAM,YAAA,GAAe;AAAA,EAC3B,oBAAA,EAAsB,gDAAA;AAAA,EACtB,OAAA,EAAS,qDAAA;AAAA;AAAA,EACT,YAAA,EAAc,gCAAA;AAAA;AAAA,EACd,OAAA,EAAS,6EAAA;AAAA;AAAA,EACT,aAAA,EAAe,kEAAA;AAAA;AAAA,EACf,eAAA,EAAiB,oEAAA;AAAA;AAAA,EACjB,SAAA,EAAW,yDAAA;AAAA;AAAA,EACV,UAAA,EAAY,wDAAA;AAAA;AAAA,EACb,WAAA,EAAa,iEAAA;AAAA;AAAA,EACZ,+BAAA,EAAiC;AACnC;;;;"}
1
+ {"version":3,"file":"backend.esm.js","sources":["../../src/urls/backend.ts"],"sourcesContent":["// prettier-ignore\n\n// (1) Requires a method to inject tokens. Not yet implemented.\n// (2) Temporary primitive url until method (1) is implemented.\n\nexport const BACKEND_URLS = {\n\tgoogle_gcpCryptoKeys: '/api/proxy/risc-proxy/api/google/gcpCryptoKeys',\n\triScUri: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName', // (1)\n\triScUri_temp: '/api/proxy/risc-proxy/api/risc', // (2)\n\topen_pr: '/api/proxy/risc-proxy/api/sops/:repoOwner/:repoName/openPullRequest/:branch', // (1)\n\tfetchAllRiScs: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:version/all', // (1)\n\tfetchDifference: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id/difference', // (1)\n\tfetchRiSc: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id', // (1)\n deleteRiSc: 'api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/:id', // (1)\n\tpublishRiSc: '/api/proxy/risc-proxy/api/risc/:repoOwner/:repoName/publish/:id', // (1)\n fetchDefaultRiScTypeDescriptors: '/api/proxy/risc-proxy/api/initrisc'\n};\n\nexport type RiScBackendUrls = {\n riScUri: string;\n uriToFetchAllRiScs: string;\n uriToFetchDifference: (id: string) => string;\n uriToFetchRiSc: (id: string) => string;\n uriToDeleteRiSc: (id: string) => string;\n uriToPublishRiSc: (id: string) => string;\n uriToFetchGcpCryptoKeys: string;\n uriToFetchDefaultRiScDescriptors: string;\n};\n\ntype BuildRiScBackendUrlsOptions = {\n baseUrl: string;\n owner: string;\n repo: string;\n version: string;\n};\n\n/** Native mode routes directly to the ros backend plugin. */\nexport function buildNativeBackendUrls({\n baseUrl,\n owner,\n repo,\n version,\n}: BuildRiScBackendUrlsOptions): RiScBackendUrls {\n const riScUri = `${baseUrl}/risc/${owner}/${repo}`;\n\n return {\n riScUri,\n uriToFetchAllRiScs: `${riScUri}/${version}/all`,\n uriToFetchDifference: (id: string) => `${riScUri}/${id}/difference`,\n uriToFetchRiSc: (id: string) => `${riScUri}/${id}`,\n uriToDeleteRiSc: (id: string) => `${riScUri}/${id}`,\n uriToPublishRiSc: (id: string) => `${riScUri}/publish/${id}`,\n uriToFetchGcpCryptoKeys: `${baseUrl}/google/gcpCryptoKeys`,\n uriToFetchDefaultRiScDescriptors: `${baseUrl}/initrisc`,\n };\n}\n"],"names":[],"mappings":"AAKO,MAAM,YAAA,GAAe;AAAA,EAC3B,oBAAA,EAAsB,gDAAA;AAAA,EACtB,OAAA,EAAS,qDAAA;AAAA;AAAA,EACT,YAAA,EAAc,gCAAA;AAAA;AAAA,EACd,OAAA,EAAS,6EAAA;AAAA;AAAA,EACT,aAAA,EAAe,kEAAA;AAAA;AAAA,EACf,eAAA,EAAiB,oEAAA;AAAA;AAAA,EACjB,SAAA,EAAW,yDAAA;AAAA;AAAA,EACV,UAAA,EAAY,wDAAA;AAAA;AAAA,EACb,WAAA,EAAa,iEAAA;AAAA;AAAA,EACZ,+BAAA,EAAiC;AACnC;AAqBO,SAAS,sBAAA,CAAuB;AAAA,EACrC,OAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAAiD;AAC/C,EAAA,MAAM,UAAU,CAAA,EAAG,OAAO,CAAA,MAAA,EAAS,KAAK,IAAI,IAAI,CAAA,CAAA;AAEhD,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,kBAAA,EAAoB,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,IAAA,CAAA;AAAA,IACzC,sBAAsB,CAAC,EAAA,KAAe,CAAA,EAAG,OAAO,IAAI,EAAE,CAAA,WAAA,CAAA;AAAA,IACtD,gBAAgB,CAAC,EAAA,KAAe,CAAA,EAAG,OAAO,IAAI,EAAE,CAAA,CAAA;AAAA,IAChD,iBAAiB,CAAC,EAAA,KAAe,CAAA,EAAG,OAAO,IAAI,EAAE,CAAA,CAAA;AAAA,IACjD,kBAAkB,CAAC,EAAA,KAAe,CAAA,EAAG,OAAO,YAAY,EAAE,CAAA,CAAA;AAAA,IAC1D,uBAAA,EAAyB,GAAG,OAAO,CAAA,qBAAA,CAAA;AAAA,IACnC,gCAAA,EAAkC,GAAG,OAAO,CAAA,SAAA;AAAA,GAC9C;AACF;;;;"}
@@ -1,17 +1,26 @@
1
1
  import { useApi, featureFlagsApiRef } from '@backstage/core-plugin-api';
2
2
 
3
3
  const systemRiScsFeatureFlag = "system-riscs";
4
+ const nativeRiScBackendFeatureFlag = "native-risc-backend";
4
5
  const riScFeatureFlags = [
5
6
  // {
6
7
  // name: systemRiScsFeatureFlag,
7
8
  // description:
8
9
  // 'Testing av system-RoS for Team SKVIS. Bruk på eget ansvar. UNNGÅ lagring av System-RoSer i åpne repoer.',
9
10
  // },
11
+ // {
12
+ // name: nativeRiScBackendFeatureFlag,
13
+ // description: 'Testing av ny backend for RoS skrevet i typescript.',
14
+ // },
10
15
  ];
11
16
  function useSystemRiScsFeatureFlag() {
12
17
  const featureFlagsApi = useApi(featureFlagsApiRef);
13
18
  return featureFlagsApi.isActive(systemRiScsFeatureFlag);
14
19
  }
20
+ function useNativeRiScBackendFeatureFlag() {
21
+ const featureFlagsApi = useApi(featureFlagsApiRef);
22
+ return featureFlagsApi.isActive(nativeRiScBackendFeatureFlag);
23
+ }
15
24
 
16
- export { riScFeatureFlags, systemRiScsFeatureFlag, useSystemRiScsFeatureFlag };
25
+ export { nativeRiScBackendFeatureFlag, riScFeatureFlags, systemRiScsFeatureFlag, useNativeRiScBackendFeatureFlag, useSystemRiScsFeatureFlag };
17
26
  //# sourceMappingURL=featureFlags.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"featureFlags.esm.js","sources":["../../src/utils/featureFlags.ts"],"sourcesContent":["import {\n featureFlagsApiRef,\n type PluginFeatureFlagConfig,\n useApi,\n} from '@backstage/core-plugin-api';\n\nexport const systemRiScsFeatureFlag = 'system-riscs';\n\nexport const riScFeatureFlags: PluginFeatureFlagConfig[] = [\n // {\n // name: systemRiScsFeatureFlag,\n // description:\n // 'Testing av system-RoS for Team SKVIS. Bruk på eget ansvar. UNNGÅ lagring av System-RoSer i åpne repoer.',\n // },\n];\n\nexport function useSystemRiScsFeatureFlag(): boolean {\n const featureFlagsApi = useApi(featureFlagsApiRef);\n return featureFlagsApi.isActive(systemRiScsFeatureFlag);\n}\n"],"names":[],"mappings":";;AAMO,MAAM,sBAAA,GAAyB;AAE/B,MAAM,gBAAA,GAA8C;AAAA;AAAA;AAAA;AAAA;AAAA;AAM3D;AAEO,SAAS,yBAAA,GAAqC;AACnD,EAAA,MAAM,eAAA,GAAkB,OAAO,kBAAkB,CAAA;AACjD,EAAA,OAAO,eAAA,CAAgB,SAAS,sBAAsB,CAAA;AACxD;;;;"}
1
+ {"version":3,"file":"featureFlags.esm.js","sources":["../../src/utils/featureFlags.ts"],"sourcesContent":["import {\n featureFlagsApiRef,\n type PluginFeatureFlagConfig,\n useApi,\n} from '@backstage/core-plugin-api';\n\nexport const systemRiScsFeatureFlag = 'system-riscs';\nexport const nativeRiScBackendFeatureFlag = 'native-risc-backend';\n\nexport const riScFeatureFlags: PluginFeatureFlagConfig[] = [\n // {\n // name: systemRiScsFeatureFlag,\n // description:\n // 'Testing av system-RoS for Team SKVIS. Bruk på eget ansvar. UNNGÅ lagring av System-RoSer i åpne repoer.',\n // },\n // {\n // name: nativeRiScBackendFeatureFlag,\n // description: 'Testing av ny backend for RoS skrevet i typescript.',\n // },\n];\n\nexport function useSystemRiScsFeatureFlag(): boolean {\n const featureFlagsApi = useApi(featureFlagsApiRef);\n return featureFlagsApi.isActive(systemRiScsFeatureFlag);\n}\n\nexport function useNativeRiScBackendFeatureFlag(): boolean {\n const featureFlagsApi = useApi(featureFlagsApiRef);\n return featureFlagsApi.isActive(nativeRiScBackendFeatureFlag);\n}\n"],"names":[],"mappings":";;AAMO,MAAM,sBAAA,GAAyB;AAC/B,MAAM,4BAAA,GAA+B;AAErC,MAAM,gBAAA,GAA8C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU3D;AAEO,SAAS,yBAAA,GAAqC;AACnD,EAAA,MAAM,eAAA,GAAkB,OAAO,kBAAkB,CAAA;AACjD,EAAA,OAAO,eAAA,CAAgB,SAAS,sBAAsB,CAAA;AACxD;AAEO,SAAS,+BAAA,GAA2C;AACzD,EAAA,MAAM,eAAA,GAAkB,OAAO,kBAAkB,CAAA;AACjD,EAAA,OAAO,eAAA,CAAgB,SAAS,4BAA4B,CAAA;AAC9D;;;;"}
@@ -2,11 +2,12 @@ import { useApi, identityApiRef, fetchApiRef, configApiRef, googleAuthApiRef, gi
2
2
  import { useEntity } from '@backstage/plugin-catalog-react';
3
3
  import { useState, useEffect, useRef, useCallback } from 'react';
4
4
  import { URLS } from '../urls/index.esm.js';
5
+ import { buildNativeBackendUrls } from '../urls/backend.esm.js';
5
6
  import { riScToDTOString, profileInfoToDTOString } from './DTOs.esm.js';
6
7
  import { latestSupportedVersion } from './constants.esm.js';
7
8
  import { ProcessingStatus } from './types.esm.js';
8
9
  import { stringifyEntityRef } from '@backstage/catalog-model';
9
- import { useSystemRiScsFeatureFlag } from './featureFlags.esm.js';
10
+ import { useSystemRiScsFeatureFlag, useNativeRiScBackendFeatureFlag } from './featureFlags.esm.js';
10
11
 
11
12
  function useGithubRepositoryInformation() {
12
13
  const [, org, repo] = useEntity().entity.metadata.annotations?.["backstage.io/view-url"].match(
@@ -55,6 +56,7 @@ function useAuthenticatedFetch() {
55
56
  const identityApi = useApi(identityApiRef);
56
57
  const { fetch } = useApi(fetchApiRef);
57
58
  const backendUrl = configApi.getString("backend.baseUrl");
59
+ const isNativeBackendEnabled = useNativeRiScBackendFeatureFlag();
58
60
  const riScUri = `${backendUrl}${URLS.backend.riScUri_temp}/${repoInformation.owner}/${repoInformation.name}`;
59
61
  const uriToFetchAllRiScs = `${riScUri}/${latestSupportedVersion}/all`;
60
62
  const uriToFetchDefaultRiScDescriptors = `${backendUrl}${URLS.backend.fetchDefaultRiScTypeDescriptors}`;
@@ -70,6 +72,12 @@ function useAuthenticatedFetch() {
70
72
  function uriToPublishRiSc(id) {
71
73
  return `${riScUri}/publish/${id}`;
72
74
  }
75
+ const nativeBackendUrls = buildNativeBackendUrls({
76
+ baseUrl: `${backendUrl}/api/ros`,
77
+ owner: repoInformation.owner,
78
+ repo: repoInformation.name,
79
+ version: latestSupportedVersion
80
+ });
73
81
  function isDevelopment() {
74
82
  return configApi.getString("auth.environment") === "development";
75
83
  }
@@ -157,7 +165,7 @@ function useAuthenticatedFetch() {
157
165
  function fetchDifference(selectedRiSc, onSuccess, onError) {
158
166
  return identityApi.getProfileInfo().then((profile) => {
159
167
  fullyAuthenticatedFetch(
160
- uriToFetchDifference(selectedRiSc.id),
168
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchDifference(selectedRiSc.id) : uriToFetchDifference(selectedRiSc.id),
161
169
  "POST",
162
170
  onSuccess,
163
171
  (_, rejectedLogin) => {
@@ -175,7 +183,7 @@ function useAuthenticatedFetch() {
175
183
  function fetchRiScs(onSuccess, onError) {
176
184
  if (isDevelopment()) {
177
185
  fullyAuthenticatedFetch(
178
- uriToFetchAllRiScs,
186
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchAllRiScs : uriToFetchAllRiScs,
179
187
  "GET",
180
188
  onSuccess,
181
189
  (error, rejectedLogin) => {
@@ -184,7 +192,7 @@ function useAuthenticatedFetch() {
184
192
  );
185
193
  } else {
186
194
  googleAuthenticatedFetch(
187
- uriToFetchAllRiScs,
195
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchAllRiScs : uriToFetchAllRiScs,
188
196
  "GET",
189
197
  onSuccess,
190
198
  (error, rejectedLogin) => {
@@ -196,7 +204,7 @@ function useAuthenticatedFetch() {
196
204
  function postFeedback(feedback) {
197
205
  return new Promise((resolve, reject) => {
198
206
  fullyAuthenticatedFetch(
199
- `${riScUri}/feedback`,
207
+ isNativeBackendEnabled ? `${nativeBackendUrls.riScUri}/feedback` : `${riScUri}/feedback`,
200
208
  "POST",
201
209
  () => resolve(),
202
210
  (error) => reject(error),
@@ -206,7 +214,7 @@ function useAuthenticatedFetch() {
206
214
  }
207
215
  function fetchGcpCryptoKeys(onSuccess, onError) {
208
216
  googleAuthenticatedFetch(
209
- `${backendUrl}/api/proxy/risc-proxy/api/google/gcpCryptoKeys`,
217
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchGcpCryptoKeys : `${backendUrl}/api/proxy/risc-proxy/api/google/gcpCryptoKeys`,
210
218
  // URL
211
219
  "GET",
212
220
  (res) => onSuccess(res),
@@ -218,7 +226,7 @@ function useAuthenticatedFetch() {
218
226
  function publishRiScs(riScId, onSuccess, onError) {
219
227
  return identityApi.getProfileInfo().then(
220
228
  (profile) => fullyAuthenticatedFetch(
221
- uriToPublishRiSc(riScId),
229
+ isNativeBackendEnabled ? nativeBackendUrls.uriToPublishRiSc(riScId) : uriToPublishRiSc(riScId),
222
230
  "POST",
223
231
  (res) => {
224
232
  if (onSuccess) onSuccess(res);
@@ -233,7 +241,7 @@ function useAuthenticatedFetch() {
233
241
  function postRiScs(riSc, generateDefault, sopsConfig, defaultRiScId, onSuccess, onError) {
234
242
  return identityApi.getProfileInfo().then(
235
243
  (profile) => fullyAuthenticatedFetch(
236
- `${riScUri}?generateDefault=${generateDefault}`,
244
+ isNativeBackendEnabled ? `${nativeBackendUrls.riScUri}?generateDefault=${generateDefault}` : `${riScUri}?generateDefault=${generateDefault}`,
237
245
  "POST",
238
246
  (res) => {
239
247
  if (onSuccess) onSuccess(res);
@@ -248,7 +256,7 @@ function useAuthenticatedFetch() {
248
256
  function putRiScs(riSc, onSuccess, onError) {
249
257
  return identityApi.getProfileInfo().then(
250
258
  (profile) => fullyAuthenticatedFetch(
251
- uriToFetchRiSc(riSc.id),
259
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchRiSc(riSc.id) : uriToFetchRiSc(riSc.id),
252
260
  "PUT",
253
261
  (res) => {
254
262
  if (onSuccess) onSuccess(res);
@@ -267,7 +275,7 @@ function useAuthenticatedFetch() {
267
275
  }
268
276
  function deleteRiScs(riScId, onSuccess, onError) {
269
277
  fullyAuthenticatedFetch(
270
- uriToDeleteRiSc(riScId),
278
+ isNativeBackendEnabled ? nativeBackendUrls.uriToDeleteRiSc(riScId) : uriToDeleteRiSc(riScId),
271
279
  "DELETE",
272
280
  (res) => {
273
281
  if (onSuccess) onSuccess(res);
@@ -279,7 +287,7 @@ function useAuthenticatedFetch() {
279
287
  }
280
288
  function fetchDefaultRiScTypeDescriptors(onSuccess) {
281
289
  fullyAuthenticatedFetch(
282
- uriToFetchDefaultRiScDescriptors,
290
+ isNativeBackendEnabled ? nativeBackendUrls.uriToFetchDefaultRiScDescriptors : uriToFetchDefaultRiScDescriptors,
283
291
  "GET",
284
292
  (res) => onSuccess(res),
285
293
  () => {
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.esm.js","sources":["../../src/utils/hooks.ts"],"sourcesContent":["import {\n configApiRef,\n fetchApiRef,\n githubAuthApiRef,\n googleAuthApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { URLS } from '../urls';\nimport {\n CreateRiScResultDTO,\n DeleteRiScResultDTO,\n GcpCryptoKeyObject,\n ProcessRiScResultDTO,\n profileInfoToDTOString,\n PublishRiScResultDTO,\n RiScContentResultDTO,\n riScToDTOString,\n SopsConfigDTO,\n} from './DTOs';\nimport { latestSupportedVersion } from './constants';\nimport {\n DefaultRiScTypeDescriptor,\n DifferenceDTO,\n GithubRepoInfo,\n ProcessingStatus,\n RiSc,\n RiScWithMetadata,\n SystemRiSc,\n} from './types';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { useSystemRiScsFeatureFlag } from './featureFlags';\n\nexport function useGithubRepositoryInformation(): GithubRepoInfo {\n const [, org, repo] =\n useEntity().entity.metadata.annotations?.['backstage.io/view-url'].match(\n /github\\.com\\/([^\\/]+)\\/([^\\/]+)/,\n ) || [];\n\n return {\n owner: org,\n name: repo,\n };\n}\n\n/**\n * Backstage has a bug where multiple tabs using the GitHub access token can each\n * fetch a new token and invalidate tokens cached in older tabs. To mitigate this\n * we patch an internal refresh predicate so a token verified as invalid can be\n * refreshed before retrying the request.\n */\nlet invalidGitHubAccessToken = '';\nfunction patchGithubApiToEnableForcedRefresh<T>(\n gitHubApi: T,\n isDevelopment: boolean,\n): T {\n const sessionManager = (gitHubApi as any)?.sessionManager;\n if (!sessionManager?.originalSessionShouldRefreshFunc) {\n if (typeof sessionManager?.sessionShouldRefreshFunc === 'function') {\n sessionManager.originalSessionShouldRefreshFunc =\n sessionManager.sessionShouldRefreshFunc;\n sessionManager.sessionShouldRefreshFunc =\n function sessionShouldRefreshFuncOverride(session: any) {\n const accessToken = session?.providerInfo?.accessToken;\n if (isDevelopment && invalidGitHubAccessToken && !accessToken) {\n throw new Error(\n 'The expected location of the accessToken was empty. This workaround is no longer working',\n );\n }\n if (accessToken === invalidGitHubAccessToken) {\n invalidGitHubAccessToken = '';\n return true;\n }\n return sessionManager.originalSessionShouldRefreshFunc(session);\n };\n } else if (isDevelopment) {\n throw new Error(\n 'The expected function \"sessionShouldRefreshFunc\" does not exist. This workaround is no longer working',\n );\n }\n }\n\n return gitHubApi;\n}\n\nexport function useAuthenticatedFetch() {\n const configApi = useApi(configApiRef);\n const repoInformation = useGithubRepositoryInformation();\n const googleApi = useApi(googleAuthApiRef);\n const gitHubApi = patchGithubApiToEnableForcedRefresh(\n useApi(githubAuthApiRef),\n isDevelopment(),\n );\n const identityApi = useApi(identityApiRef);\n const { fetch } = useApi(fetchApiRef);\n const backendUrl = configApi.getString('backend.baseUrl');\n const riScUri = `${backendUrl}${URLS.backend.riScUri_temp}/${repoInformation.owner}/${repoInformation.name}`; // URLS.backend.riScUri\n\n const uriToFetchAllRiScs = `${riScUri}/${latestSupportedVersion}/all`; // URLS.backend.fetchAllRiScs\n const uriToFetchDefaultRiScDescriptors = `${backendUrl}${URLS.backend.fetchDefaultRiScTypeDescriptors}`;\n\n function uriToFetchDifference(id: string) {\n // URLS.backend.fetchDifference\n return `${riScUri}/${id}/difference`;\n }\n\n function uriToFetchRiSc(id: string) {\n // URLS.backend.fetchRiSc\n return `${riScUri}/${id}`;\n }\n\n function uriToDeleteRiSc(id: string) {\n // URLS.backend.deleteRiSc\n return `${riScUri}/${id}`;\n }\n\n function uriToPublishRiSc(id: string) {\n // URLS.backend.publishRiSc\n return `${riScUri}/publish/${id}`;\n }\n\n function isDevelopment() {\n return configApi.getString('auth.environment') === 'development';\n }\n\n async function fullyAuthenticatedFetch<T, K>(\n uri: string,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n onSuccess: (response: T) => void,\n onError: (error: K, rejectedLogin: boolean) => void,\n body?: string,\n ) {\n try {\n const [idToken, googleAccessToken, gitHubAccessToken] = await Promise.all(\n [\n identityApi.getCredentials(),\n googleApi.getAccessToken([\n URLS.external.www_googleapis_com__cloudkms,\n URLS.external.www_googleapis_com__cloud_platform,\n URLS.external.www_googleapis_com__cloudplatformprojects_readonly,\n ]),\n gitHubApi.getAccessToken(['repo']),\n ],\n );\n const headers = {\n Authorization: `Bearer ${idToken.token}`,\n 'GCP-Access-Token': googleAccessToken,\n 'GitHub-Access-Token': gitHubAccessToken,\n 'Content-Type': 'application/json',\n };\n let res = await fetch(uri, {\n method: method,\n headers,\n body: body,\n });\n\n let json = await res.json();\n\n if (\n res.status === 401 &&\n (json as ProcessRiScResultDTO)?.status ===\n ProcessingStatus.InvalidGitHubAccessToken\n ) {\n invalidGitHubAccessToken = headers['GitHub-Access-Token'];\n headers['GitHub-Access-Token'] = await gitHubApi.getAccessToken([\n 'repo',\n ]);\n res = await fetch(uri, {\n method: method,\n headers: headers,\n body: body,\n });\n json = await res.json();\n }\n\n if (!res.ok) {\n return onError(json as K, false);\n }\n\n return onSuccess(json as T);\n } catch (error: any) {\n if (error.name === 'RejectedError') {\n onError(error, true);\n } else {\n onError(error, false);\n }\n return Promise.resolve(null);\n }\n }\n\n function googleAuthenticatedFetch<T, K>(\n uri: string,\n method: 'GET',\n onSuccess: (response: T) => void,\n onError: (error: K, rejectedLogin: boolean) => void,\n body?: string,\n ) {\n Promise.all([\n identityApi.getCredentials(),\n googleApi.getAccessToken([\n URLS.external.www_googleapis_com__cloudkms,\n URLS.external.www_googleapis_com__cloud_platform,\n URLS.external.www_googleapis_com__cloudplatformprojects_readonly,\n ]),\n ])\n .then(([idToken, googleAccessToken]) => {\n fetch(uri, {\n method: method,\n headers: {\n Authorization: `Bearer ${idToken.token}`,\n 'GCP-Access-Token': googleAccessToken,\n 'Content-Type': 'application/json',\n },\n body: body,\n }).then(res => {\n if (!res.ok) {\n return res\n .json()\n .then(json => json as K)\n .then(typedJson => onError(typedJson, false))\n .catch(error => onError(error, false));\n }\n return res\n .json()\n .then(json => json as T)\n .then(typedJson => onSuccess(typedJson));\n });\n })\n .catch(error => {\n if (error.name === 'RejectedError') {\n onError(error, true);\n } else {\n onError(error, false);\n }\n });\n }\n\n function fetchDifference(\n selectedRiSc: RiScWithMetadata,\n onSuccess: (response: DifferenceDTO) => void,\n onError?: (loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile => {\n fullyAuthenticatedFetch<DifferenceDTO, DifferenceDTO>(\n uriToFetchDifference(selectedRiSc.id),\n 'POST',\n onSuccess,\n (_, rejectedLogin) => {\n if (onError) onError(rejectedLogin);\n },\n riScToDTOString(\n selectedRiSc.content,\n false,\n profile,\n selectedRiSc.sopsConfig,\n ),\n );\n });\n }\n\n function fetchRiScs(\n onSuccess: (response: RiScContentResultDTO[]) => void,\n onError?: (error: any, loginRejected: boolean) => void,\n ) {\n if (isDevelopment()) {\n fullyAuthenticatedFetch<RiScContentResultDTO[], RiScContentResultDTO[]>(\n uriToFetchAllRiScs,\n 'GET',\n onSuccess,\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n } else {\n googleAuthenticatedFetch<RiScContentResultDTO[], RiScContentResultDTO[]>(\n uriToFetchAllRiScs,\n 'GET',\n onSuccess,\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n }\n\n function postFeedback(feedback: string): Promise<void> {\n return new Promise((resolve, reject) => {\n fullyAuthenticatedFetch<void, any>(\n `${riScUri}/feedback`,\n 'POST',\n () => resolve(),\n error => reject(error),\n feedback,\n );\n });\n }\n\n function fetchGcpCryptoKeys(\n onSuccess: (response: GcpCryptoKeyObject[]) => void,\n onError?: (error: GcpCryptoKeyObject[], loginRejected: boolean) => void,\n ) {\n googleAuthenticatedFetch<GcpCryptoKeyObject[], GcpCryptoKeyObject[]>(\n `${backendUrl}/api/proxy/risc-proxy/api/google/gcpCryptoKeys`, // URL\n 'GET',\n res => onSuccess(res),\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n\n function publishRiScs(\n riScId: string,\n onSuccess?: (response: PublishRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<PublishRiScResultDTO, ProcessRiScResultDTO>(\n uriToPublishRiSc(riScId),\n 'POST',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n profileInfoToDTOString(profile),\n ),\n );\n }\n\n function postRiScs(\n riSc: RiSc,\n generateDefault: boolean,\n sopsConfig: SopsConfigDTO,\n defaultRiScId: string | undefined,\n onSuccess?: (response: CreateRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<CreateRiScResultDTO, ProcessRiScResultDTO>(\n `${riScUri}?generateDefault=${generateDefault}`,\n 'POST',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n riScToDTOString(riSc, true, profile, sopsConfig, defaultRiScId),\n ),\n );\n }\n\n function putRiScs(\n riSc: RiScWithMetadata,\n onSuccess?: (response: ProcessRiScResultDTO | PublishRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<\n ProcessRiScResultDTO | PublishRiScResultDTO,\n ProcessRiScResultDTO\n >(\n uriToFetchRiSc(riSc.id),\n 'PUT',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n riScToDTOString(\n riSc.content,\n riSc.isRequiresNewApproval!!,\n profile,\n riSc.sopsConfig,\n ),\n ),\n );\n }\n\n function deleteRiScs(\n riScId: string,\n onSuccess?: (response: DeleteRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n fullyAuthenticatedFetch<DeleteRiScResultDTO, ProcessRiScResultDTO>(\n uriToDeleteRiSc(riScId),\n 'DELETE',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n\n function fetchDefaultRiScTypeDescriptors(\n onSuccess: (response: DefaultRiScTypeDescriptor[]) => void,\n ) {\n fullyAuthenticatedFetch<DefaultRiScTypeDescriptor[], void>(\n uriToFetchDefaultRiScDescriptors,\n 'GET',\n res => onSuccess(res),\n () => {},\n );\n }\n return {\n fetchRiScs,\n fetchGcpCryptoKeys,\n postRiScs,\n putRiScs,\n deleteRiScs,\n publishRiScs,\n fetchDifference,\n postFeedback,\n fetchDefaultRiScTypeDescriptors,\n };\n}\n\nexport const useDebouncedValue = <T>(value: T, delay = 500) => {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timeout = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => clearTimeout(timeout);\n }, [value, delay]);\n\n return debouncedValue;\n};\n\ntype RiScIndexState = {\n riScs: SystemRiSc[];\n isFetching: boolean;\n error: Error | undefined;\n};\n\nexport function useSystemRiScsForCurrentEntity(): RiScIndexState {\n const isSystemRiScsEnabled = useSystemRiScsFeatureFlag();\n const { entity } = useEntity();\n const identityApi = useApi(identityApiRef);\n const { fetch } = useApi(fetchApiRef);\n const backendUrl = useApi(configApiRef).getString('backend.baseUrl');\n const entityRef = stringifyEntityRef(entity);\n\n const [state, setState] = useState<RiScIndexState>({\n riScs: [],\n isFetching: isSystemRiScsEnabled,\n error: undefined,\n });\n\n useEffect(() => {\n if (!isSystemRiScsEnabled) {\n setState({\n riScs: [],\n isFetching: false,\n error: undefined,\n });\n return undefined;\n }\n\n let cancelled = false;\n\n setState(previous => ({\n ...previous,\n isFetching: true,\n error: undefined,\n }));\n\n identityApi\n .getCredentials()\n .then(credentials => {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n };\n\n if (credentials.token) {\n headers.Authorization = `Bearer ${credentials.token}`;\n }\n\n return fetch(\n `${backendUrl}/api/risk-scorecard/riscs?entityRef=${encodeURIComponent(\n entityRef,\n )}`,\n {\n method: 'GET',\n headers,\n },\n );\n })\n .then(async response => {\n if (!response.ok) {\n throw new Error(`Failed to fetch RiSc index: ${response.status}`);\n }\n\n const responseBody = (await response.json()) as SystemRiSc[];\n const systemRiScs = responseBody.filter(x => x.appliesTo.length > 1);\n\n if (!cancelled) {\n setState({\n riScs: systemRiScs,\n isFetching: false,\n error: undefined,\n });\n }\n })\n .catch(error => {\n if (!cancelled) {\n setState({\n riScs: [],\n isFetching: false,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [backendUrl, entityRef, fetch, identityApi, isSystemRiScsEnabled]);\n\n return state;\n}\n\nexport function useDebounce<T>(\n value: T,\n delay: number,\n callback: (value: T) => void,\n) {\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const latestValueRef = useRef<T>(value);\n const latestCallbackRef = useRef<(v: T) => void>(callback);\n\n useEffect(() => {\n latestValueRef.current = value;\n }, [value]);\n\n useEffect(() => {\n latestCallbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n latestCallbackRef.current(latestValueRef.current);\n timeoutRef.current = null;\n }, delay);\n\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [value, delay]);\n\n const flush = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n const v = latestValueRef.current;\n const hasValue = Array.isArray(v) ? v.length > 0 : v !== null;\n if (hasValue) {\n latestCallbackRef.current(v);\n }\n }, []);\n return { flush };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.esm.js","sources":["../../src/utils/hooks.ts"],"sourcesContent":["import {\n configApiRef,\n fetchApiRef,\n githubAuthApiRef,\n googleAuthApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { URLS } from '../urls';\nimport { buildNativeBackendUrls } from '../urls/backend';\nimport {\n CreateRiScResultDTO,\n DeleteRiScResultDTO,\n GcpCryptoKeyObject,\n ProcessRiScResultDTO,\n profileInfoToDTOString,\n PublishRiScResultDTO,\n RiScContentResultDTO,\n riScToDTOString,\n SopsConfigDTO,\n} from './DTOs';\nimport { latestSupportedVersion } from './constants';\nimport {\n DefaultRiScTypeDescriptor,\n DifferenceDTO,\n GithubRepoInfo,\n ProcessingStatus,\n RiSc,\n RiScWithMetadata,\n SystemRiSc,\n} from './types';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n useNativeRiScBackendFeatureFlag,\n useSystemRiScsFeatureFlag,\n} from './featureFlags';\n\nexport function useGithubRepositoryInformation(): GithubRepoInfo {\n const [, org, repo] =\n useEntity().entity.metadata.annotations?.['backstage.io/view-url'].match(\n /github\\.com\\/([^\\/]+)\\/([^\\/]+)/,\n ) || [];\n\n return {\n owner: org,\n name: repo,\n };\n}\n\n/**\n * Backstage has a bug where multiple tabs using the GitHub access token can each\n * fetch a new token and invalidate tokens cached in older tabs. To mitigate this\n * we patch an internal refresh predicate so a token verified as invalid can be\n * refreshed before retrying the request.\n */\nlet invalidGitHubAccessToken = '';\nfunction patchGithubApiToEnableForcedRefresh<T>(\n gitHubApi: T,\n isDevelopment: boolean,\n): T {\n const sessionManager = (gitHubApi as any)?.sessionManager;\n if (!sessionManager?.originalSessionShouldRefreshFunc) {\n if (typeof sessionManager?.sessionShouldRefreshFunc === 'function') {\n sessionManager.originalSessionShouldRefreshFunc =\n sessionManager.sessionShouldRefreshFunc;\n sessionManager.sessionShouldRefreshFunc =\n function sessionShouldRefreshFuncOverride(session: any) {\n const accessToken = session?.providerInfo?.accessToken;\n if (isDevelopment && invalidGitHubAccessToken && !accessToken) {\n throw new Error(\n 'The expected location of the accessToken was empty. This workaround is no longer working',\n );\n }\n if (accessToken === invalidGitHubAccessToken) {\n invalidGitHubAccessToken = '';\n return true;\n }\n return sessionManager.originalSessionShouldRefreshFunc(session);\n };\n } else if (isDevelopment) {\n throw new Error(\n 'The expected function \"sessionShouldRefreshFunc\" does not exist. This workaround is no longer working',\n );\n }\n }\n\n return gitHubApi;\n}\n\nexport function useAuthenticatedFetch() {\n const configApi = useApi(configApiRef);\n const repoInformation = useGithubRepositoryInformation();\n const googleApi = useApi(googleAuthApiRef);\n const gitHubApi = patchGithubApiToEnableForcedRefresh(\n useApi(githubAuthApiRef),\n isDevelopment(),\n );\n const identityApi = useApi(identityApiRef);\n const { fetch } = useApi(fetchApiRef);\n const backendUrl = configApi.getString('backend.baseUrl');\n const isNativeBackendEnabled = useNativeRiScBackendFeatureFlag();\n\n const riScUri = `${backendUrl}${URLS.backend.riScUri_temp}/${repoInformation.owner}/${repoInformation.name}`; // URLS.backend.riScUri\n\n const uriToFetchAllRiScs = `${riScUri}/${latestSupportedVersion}/all`; // URLS.backend.fetchAllRiScs\n const uriToFetchDefaultRiScDescriptors = `${backendUrl}${URLS.backend.fetchDefaultRiScTypeDescriptors}`;\n\n function uriToFetchDifference(id: string) {\n // URLS.backend.fetchDifference\n return `${riScUri}/${id}/difference`;\n }\n\n function uriToFetchRiSc(id: string) {\n // URLS.backend.fetchRiSc\n return `${riScUri}/${id}`;\n }\n\n function uriToDeleteRiSc(id: string) {\n // URLS.backend.deleteRiSc\n return `${riScUri}/${id}`;\n }\n\n function uriToPublishRiSc(id: string) {\n // URLS.backend.publishRiSc\n return `${riScUri}/publish/${id}`;\n }\n\n // TODO: Revisit discoveryApi.getBaseUrl('ros') when we are ready to validate\n // native backend routing across deployments.\n const nativeBackendUrls = buildNativeBackendUrls({\n baseUrl: `${backendUrl}/api/ros`,\n owner: repoInformation.owner,\n repo: repoInformation.name,\n version: latestSupportedVersion,\n });\n\n function isDevelopment() {\n return configApi.getString('auth.environment') === 'development';\n }\n\n async function fullyAuthenticatedFetch<T, K>(\n uri: string,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n onSuccess: (response: T) => void,\n onError: (error: K, rejectedLogin: boolean) => void,\n body?: string,\n ) {\n try {\n const [idToken, googleAccessToken, gitHubAccessToken] = await Promise.all(\n [\n identityApi.getCredentials(),\n googleApi.getAccessToken([\n URLS.external.www_googleapis_com__cloudkms,\n URLS.external.www_googleapis_com__cloud_platform,\n URLS.external.www_googleapis_com__cloudplatformprojects_readonly,\n ]),\n gitHubApi.getAccessToken(['repo']),\n ],\n );\n const headers = {\n Authorization: `Bearer ${idToken.token}`,\n 'GCP-Access-Token': googleAccessToken,\n 'GitHub-Access-Token': gitHubAccessToken,\n 'Content-Type': 'application/json',\n };\n let res = await fetch(uri, {\n method: method,\n headers,\n body: body,\n });\n\n let json = await res.json();\n\n if (\n res.status === 401 &&\n (json as ProcessRiScResultDTO)?.status ===\n ProcessingStatus.InvalidGitHubAccessToken\n ) {\n invalidGitHubAccessToken = headers['GitHub-Access-Token'];\n headers['GitHub-Access-Token'] = await gitHubApi.getAccessToken([\n 'repo',\n ]);\n res = await fetch(uri, {\n method: method,\n headers: headers,\n body: body,\n });\n json = await res.json();\n }\n\n if (!res.ok) {\n return onError(json as K, false);\n }\n\n return onSuccess(json as T);\n } catch (error: any) {\n if (error.name === 'RejectedError') {\n onError(error, true);\n } else {\n onError(error, false);\n }\n return Promise.resolve(null);\n }\n }\n\n function googleAuthenticatedFetch<T, K>(\n uri: string,\n method: 'GET',\n onSuccess: (response: T) => void,\n onError: (error: K, rejectedLogin: boolean) => void,\n body?: string,\n ) {\n Promise.all([\n identityApi.getCredentials(),\n googleApi.getAccessToken([\n URLS.external.www_googleapis_com__cloudkms,\n URLS.external.www_googleapis_com__cloud_platform,\n URLS.external.www_googleapis_com__cloudplatformprojects_readonly,\n ]),\n ])\n .then(([idToken, googleAccessToken]) => {\n fetch(uri, {\n method: method,\n headers: {\n Authorization: `Bearer ${idToken.token}`,\n 'GCP-Access-Token': googleAccessToken,\n 'Content-Type': 'application/json',\n },\n body: body,\n }).then(res => {\n if (!res.ok) {\n return res\n .json()\n .then(json => json as K)\n .then(typedJson => onError(typedJson, false))\n .catch(error => onError(error, false));\n }\n return res\n .json()\n .then(json => json as T)\n .then(typedJson => onSuccess(typedJson));\n });\n })\n .catch(error => {\n if (error.name === 'RejectedError') {\n onError(error, true);\n } else {\n onError(error, false);\n }\n });\n }\n\n function fetchDifference(\n selectedRiSc: RiScWithMetadata,\n onSuccess: (response: DifferenceDTO) => void,\n onError?: (loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile => {\n fullyAuthenticatedFetch<DifferenceDTO, DifferenceDTO>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchDifference(selectedRiSc.id)\n : uriToFetchDifference(selectedRiSc.id),\n 'POST',\n onSuccess,\n (_, rejectedLogin) => {\n if (onError) onError(rejectedLogin);\n },\n riScToDTOString(\n selectedRiSc.content,\n false,\n profile,\n selectedRiSc.sopsConfig,\n ),\n );\n });\n }\n\n function fetchRiScs(\n onSuccess: (response: RiScContentResultDTO[]) => void,\n onError?: (error: any, loginRejected: boolean) => void,\n ) {\n if (isDevelopment()) {\n fullyAuthenticatedFetch<RiScContentResultDTO[], RiScContentResultDTO[]>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchAllRiScs\n : uriToFetchAllRiScs,\n 'GET',\n onSuccess,\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n } else {\n googleAuthenticatedFetch<RiScContentResultDTO[], RiScContentResultDTO[]>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchAllRiScs\n : uriToFetchAllRiScs,\n 'GET',\n onSuccess,\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n }\n\n function postFeedback(feedback: string): Promise<void> {\n return new Promise((resolve, reject) => {\n fullyAuthenticatedFetch<void, any>(\n isNativeBackendEnabled\n ? `${nativeBackendUrls.riScUri}/feedback`\n : `${riScUri}/feedback`,\n 'POST',\n () => resolve(),\n error => reject(error),\n feedback,\n );\n });\n }\n\n function fetchGcpCryptoKeys(\n onSuccess: (response: GcpCryptoKeyObject[]) => void,\n onError?: (error: GcpCryptoKeyObject[], loginRejected: boolean) => void,\n ) {\n googleAuthenticatedFetch<GcpCryptoKeyObject[], GcpCryptoKeyObject[]>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchGcpCryptoKeys\n : `${backendUrl}/api/proxy/risc-proxy/api/google/gcpCryptoKeys`, // URL\n 'GET',\n res => onSuccess(res),\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n\n function publishRiScs(\n riScId: string,\n onSuccess?: (response: PublishRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<PublishRiScResultDTO, ProcessRiScResultDTO>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToPublishRiSc(riScId)\n : uriToPublishRiSc(riScId),\n 'POST',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n profileInfoToDTOString(profile),\n ),\n );\n }\n\n function postRiScs(\n riSc: RiSc,\n generateDefault: boolean,\n sopsConfig: SopsConfigDTO,\n defaultRiScId: string | undefined,\n onSuccess?: (response: CreateRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<CreateRiScResultDTO, ProcessRiScResultDTO>(\n isNativeBackendEnabled\n ? `${nativeBackendUrls.riScUri}?generateDefault=${generateDefault}`\n : `${riScUri}?generateDefault=${generateDefault}`,\n 'POST',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n riScToDTOString(riSc, true, profile, sopsConfig, defaultRiScId),\n ),\n );\n }\n\n function putRiScs(\n riSc: RiScWithMetadata,\n onSuccess?: (response: ProcessRiScResultDTO | PublishRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n return identityApi.getProfileInfo().then(profile =>\n fullyAuthenticatedFetch<\n ProcessRiScResultDTO | PublishRiScResultDTO,\n ProcessRiScResultDTO\n >(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchRiSc(riSc.id)\n : uriToFetchRiSc(riSc.id),\n 'PUT',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n riScToDTOString(\n riSc.content,\n riSc.isRequiresNewApproval!!,\n profile,\n riSc.sopsConfig,\n ),\n ),\n );\n }\n\n function deleteRiScs(\n riScId: string,\n onSuccess?: (response: DeleteRiScResultDTO) => void,\n onError?: (error: ProcessRiScResultDTO, loginRejected: boolean) => void,\n ) {\n fullyAuthenticatedFetch<DeleteRiScResultDTO, ProcessRiScResultDTO>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToDeleteRiSc(riScId)\n : uriToDeleteRiSc(riScId),\n 'DELETE',\n res => {\n if (onSuccess) onSuccess(res);\n },\n (error, rejectedLogin) => {\n if (onError) onError(error, rejectedLogin);\n },\n );\n }\n\n function fetchDefaultRiScTypeDescriptors(\n onSuccess: (response: DefaultRiScTypeDescriptor[]) => void,\n ) {\n fullyAuthenticatedFetch<DefaultRiScTypeDescriptor[], void>(\n isNativeBackendEnabled\n ? nativeBackendUrls.uriToFetchDefaultRiScDescriptors\n : uriToFetchDefaultRiScDescriptors,\n 'GET',\n res => onSuccess(res),\n () => {},\n );\n }\n return {\n fetchRiScs,\n fetchGcpCryptoKeys,\n postRiScs,\n putRiScs,\n deleteRiScs,\n publishRiScs,\n fetchDifference,\n postFeedback,\n fetchDefaultRiScTypeDescriptors,\n };\n}\n\nexport const useDebouncedValue = <T>(value: T, delay = 500) => {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timeout = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => clearTimeout(timeout);\n }, [value, delay]);\n\n return debouncedValue;\n};\n\ntype RiScIndexState = {\n riScs: SystemRiSc[];\n isFetching: boolean;\n error: Error | undefined;\n};\n\nexport function useSystemRiScsForCurrentEntity(): RiScIndexState {\n const isSystemRiScsEnabled = useSystemRiScsFeatureFlag();\n const { entity } = useEntity();\n const identityApi = useApi(identityApiRef);\n const { fetch } = useApi(fetchApiRef);\n const backendUrl = useApi(configApiRef).getString('backend.baseUrl');\n const entityRef = stringifyEntityRef(entity);\n\n const [state, setState] = useState<RiScIndexState>({\n riScs: [],\n isFetching: isSystemRiScsEnabled,\n error: undefined,\n });\n\n useEffect(() => {\n if (!isSystemRiScsEnabled) {\n setState({\n riScs: [],\n isFetching: false,\n error: undefined,\n });\n return undefined;\n }\n\n let cancelled = false;\n\n setState(previous => ({\n ...previous,\n isFetching: true,\n error: undefined,\n }));\n\n identityApi\n .getCredentials()\n .then(credentials => {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n };\n\n if (credentials.token) {\n headers.Authorization = `Bearer ${credentials.token}`;\n }\n\n return fetch(\n `${backendUrl}/api/risk-scorecard/riscs?entityRef=${encodeURIComponent(\n entityRef,\n )}`,\n {\n method: 'GET',\n headers,\n },\n );\n })\n .then(async response => {\n if (!response.ok) {\n throw new Error(`Failed to fetch RiSc index: ${response.status}`);\n }\n\n const responseBody = (await response.json()) as SystemRiSc[];\n const systemRiScs = responseBody.filter(x => x.appliesTo.length > 1);\n\n if (!cancelled) {\n setState({\n riScs: systemRiScs,\n isFetching: false,\n error: undefined,\n });\n }\n })\n .catch(error => {\n if (!cancelled) {\n setState({\n riScs: [],\n isFetching: false,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [backendUrl, entityRef, fetch, identityApi, isSystemRiScsEnabled]);\n\n return state;\n}\n\nexport function useDebounce<T>(\n value: T,\n delay: number,\n callback: (value: T) => void,\n) {\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const latestValueRef = useRef<T>(value);\n const latestCallbackRef = useRef<(v: T) => void>(callback);\n\n useEffect(() => {\n latestValueRef.current = value;\n }, [value]);\n\n useEffect(() => {\n latestCallbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n latestCallbackRef.current(latestValueRef.current);\n timeoutRef.current = null;\n }, delay);\n\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [value, delay]);\n\n const flush = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n const v = latestValueRef.current;\n const hasValue = Array.isArray(v) ? v.length > 0 : v !== null;\n if (hasValue) {\n latestCallbackRef.current(v);\n }\n }, []);\n return { flush };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@kartverket/backstage-plugin-risk-scorecard",
3
- "version": "6.12.1",
3
+ "version": "8.0.0",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "MIT",
7
7
  "repository": {
8
- "url": "https://github.com/kartverket/backstage-plugin-risk-scorecard-frontend.git"
8
+ "url": "git+https://github.com/kartverket/backstage-plugin-risk-scorecard-frontend.git"
9
9
  },
10
10
  "publishConfig": {
11
11
  "access": "public",
@@ -15,6 +15,7 @@
15
15
  "engines": {
16
16
  "node": "24"
17
17
  },
18
+ "configSchema": "config.d.ts",
18
19
  "backstage": {
19
20
  "role": "frontend-plugin",
20
21
  "pluginId": "risk-scorecard",
@@ -28,17 +29,12 @@
28
29
  ],
29
30
  "scripts": {
30
31
  "start": "backstage-cli package start",
31
- "build": "backstage-cli package build",
32
- "lint": "backstage-cli package lint",
33
- "prettier:check": "prettier --check .",
34
- "prettier:format": "prettier --write .",
32
+ "build:types": "yarn run -T tsc",
33
+ "build": "yarn build:types && backstage-cli package build",
35
34
  "test": "backstage-cli package test",
36
35
  "clean": "backstage-cli package clean",
37
36
  "prepack": "backstage-cli package prepack",
38
- "postpack": "backstage-cli package postpack",
39
- "tsc": "tsc",
40
- "_rm-node-modules": "rm -rf node_modules/ && cp -vnr node_modules_dummy/ node_modules/",
41
- "rm-node-modules": "yarn run _rm-node-modules"
37
+ "postpack": "backstage-cli package postpack"
42
38
  },
43
39
  "dependencies": {
44
40
  "@backstage/catalog-model": "backstage:^",
@@ -63,37 +59,26 @@
63
59
  "remark-breaks": "^4.0.0",
64
60
  "remixicon": "^4.9.1"
65
61
  },
66
- "peerDependencies": {
67
- "react": "^18.0.0",
68
- "react-dom": "^18.0.0",
69
- "react-router": "^6.3.0",
70
- "react-router-dom": "^6.3.0"
71
- },
72
62
  "devDependencies": {
73
63
  "@backstage/cli": "backstage:^",
74
64
  "@backstage/core-app-api": "backstage:^",
75
65
  "@backstage/dev-utils": "backstage:^",
76
66
  "@backstage/test-utils": "backstage:^",
67
+ "@testing-library/dom": "^10.4.1",
77
68
  "@testing-library/react": "^16.3.2",
78
69
  "@types/luxon": "^3.7.1",
79
- "@types/react": "^18.3.20",
80
- "prettier": "^3.8.3"
81
- },
82
- "prettier": "@backstage/cli/config/prettier",
83
- "lint-staged": {
84
- "*.{js,jsx,ts,tsx,mjs,cjs}": [
85
- "eslint --fix",
86
- "prettier --write"
87
- ],
88
- "*.{json,md}": [
89
- "prettier --write"
90
- ]
70
+ "@types/react": "^18.3.12",
71
+ "jest": "catalog:",
72
+ "react": "18.3.1",
73
+ "react-dom": "18.3.1",
74
+ "react-router": "6.30.3",
75
+ "react-router-dom": "6.30.3"
91
76
  },
92
77
  "files": [
93
78
  "dist",
94
- "css"
79
+ "css",
80
+ "config.d.ts"
95
81
  ],
96
- "packageManager": "yarn@4.8.1+sha512.bc946f2a022d7a1a38adfc15b36a66a3807a67629789496c3714dd1703d2e6c6b1c69ff9ec3b43141ac7a1dd853b7685638eb0074300386a59c18df351ef8ff6",
97
82
  "typesVersions": {
98
83
  "*": {
99
84
  "package.json": [