1+ import { GetGrafanaCommand } from '@clevercloud/client/cc-api-commands/grafana/get-grafana-command.js' ;
12import { get as getAddon } from '@clevercloud/client/esm/api/v2/addon.js' ;
2- import { getGrafanaOrganisation } from '@clevercloud/client/esm/api/v4/saas.js' ;
33import { ONE_SECOND } from '@clevercloud/client/esm/with-cache.js' ;
44import { getDevHubUrl } from '../../lib/dev-hub-url.js' ;
55import { sendToApi } from '../../lib/send-to-api.js' ;
66
77/**
8+ * @import { CcApiClient } from '@clevercloud/client/cc-api-client.js'
89 * @import { AddonInfoStateLoaded, RawAddon } from './cc-addon-info.types.js'
9- * @import { OperatorVersionInfo, RawOperator } from '../../operators.types.js'
10+ * @import { CheckKeycloakVersionCommandOutput } from '@clevercloud/client/cc-api-commands/keycloak/check-keycloak-version-command.types.js'
11+ * @import { CheckOtoroshiVersionCommandOutput } from '@clevercloud/client/cc-api-commands/otoroshi/check-otoroshi-version-command.types.js'
12+ * @import { CheckMetabaseVersionCommandOutput } from '@clevercloud/client/cc-api-commands/metabase/check-metabase-version-command.types.js'
1013 * @import { ApiConfig } from '../../lib/send-to-api.types.js'
1114 */
1215
@@ -16,17 +19,12 @@ export class CcAddonInfoClient {
1619 * @param {ApiConfig } config.apiConfig - API configuration
1720 * @param {string } config.ownerId - Owner identifier
1821 * @param {string } config.addonId - Addon identifier
19- * @param {string } config.providerId
20- * @param {{ base: string, console: string } } [config.grafanaLink] - Base url to build a grafana link to the app
2122 * @param {AbortSignal } config.signal - Signal to abort calls
2223 */
23- constructor ( { apiConfig, ownerId, addonId, providerId , grafanaLink , signal } ) {
24+ constructor ( { apiConfig, ownerId, addonId, signal } ) {
2425 this . _apiConfig = apiConfig ;
2526 this . _ownerId = ownerId ;
2627 this . _addonId = addonId ;
27- this . providerId = providerId ;
28- this . _grafanaLink = grafanaLink ;
29- this . _realId = null ;
3028 this . _signal = signal ;
3129 }
3230
@@ -36,133 +34,10 @@ export class CcAddonInfoClient {
3634 sendToApi ( { apiConfig : this . _apiConfig , signal : this . _signal , cacheDelay : ONE_SECOND } ) ,
3735 ) ;
3836 }
39-
40- /**
41- * @param {string } providerId
42- * @param {string } realId
43- * @returns {Promise<RawOperator> }
44- */
45- _getOperator ( providerId , realId ) {
46- return getOperator ( { providerId, realId } ) . then (
47- sendToApi ( { apiConfig : this . _apiConfig , signal : this . _signal , cacheDelay : ONE_SECOND } ) ,
48- ) ;
49- }
50-
51- /** @returns {Promise<OperatorVersionInfo> } */
52- getOperatorVersionInfo ( ) {
53- return checkOperatorVersion ( { providerId : this . providerId , realId : this . _realId } ) . then (
54- sendToApi ( { apiConfig : this . _apiConfig , signal : this . _signal } ) ,
55- ) ;
56- }
57-
58- /**
59- * @param {Object } parameters
60- * @param {string } parameters.resourceId
61- * @param {AbortSignal } parameters.signal
62- * @returns {Promise<string> }
63- */
64- _getGrafanaAppLink ( { resourceId, signal } ) {
65- return getGrafanaOrganisation ( { id : this . _ownerId } )
66- . then ( sendToApi ( { apiConfig : this . _apiConfig , signal } ) )
67- . then (
68- /** @param {{id: string} } grafanaOrg*/
69- ( grafanaOrg ) => {
70- const grafanaLink = new URL ( '/d/runtime/application-runtime' , this . _grafanaLink . base ) ;
71- grafanaLink . searchParams . set ( 'orgId' , grafanaOrg . id ) ;
72- grafanaLink . searchParams . set ( 'var-SELECT_APP' , resourceId ) ;
73- return grafanaLink . toString ( ) ;
74- } ,
75- )
76- . catch (
77- /** @param {Error & { response?: { status?: number }} } error */
78- ( error ) => {
79- if ( error . response ?. status === 404 ) {
80- return this . _grafanaLink . console ;
81- }
82- throw error ;
83- } ,
84- ) ;
85- }
86-
87- /**
88- * @param {string } targetVersion
89- * @returns {Promise<RawOperator> }
90- **/
91- updateOperatorVersion ( targetVersion ) {
92- return updateOperatorVersion ( { providerId : this . providerId , realId : this . _realId } , { targetVersion } ) . then (
93- sendToApi ( { apiConfig : this . _apiConfig } ) ,
94- ) ;
95- }
96-
97- /**
98- * @return {Promise<{addonInfo: RawAddon, operator: RawOperator, operatorVersionInfo: OperatorVersionInfo, grafanaAppLink: string}> }
99- */
100- async getAddonInfo ( ) {
101- // Fetch addon to get realId,
102- const rawAddon = await this . _getAddon ( ) ;
103- this . _realId = rawAddon . realId ;
104- this . providerId = /** @type {import('../common.types.js').RawAddonProvider } */ rawAddon . provider . id ;
105- // Fetch operator with realId,
106- const [ operator , operatorVersionInfo ] = await Promise . all ( [
107- this . _getOperator ( this . providerId , this . _realId ) ,
108- this . getOperatorVersionInfo ( ) ,
109- ] ) ;
110- const grafanaAppLink =
111- this . _grafanaLink != null
112- ? await this . _getGrafanaAppLink ( { resourceId : operator . resources . entrypoint , signal : this . _signal } )
113- : null ;
114-
115- return { addonInfo : rawAddon , operator, operatorVersionInfo, grafanaAppLink } ;
116- }
11737}
11838
11939/**
120- * @param {{ providerId: string, realId: string } } params
121- */
122- function getOperator ( params ) {
123- // no multipath for /self or /organisations/{id}
124- return Promise . resolve ( {
125- method : 'get' ,
126- url : `/v4/addon-providers/addon-${ params . providerId } /addons/${ params . realId } ` ,
127- headers : { Accept : 'application/json' } ,
128- // no queryParams
129- // no body
130- } ) ;
131- }
132-
133- /**
134- * @param {{ providerId: string, realId: string } } params
135- */
136- function checkOperatorVersion ( params ) {
137- // no multipath for /self or /organisations/{id}
138- return Promise . resolve ( {
139- method : 'get' ,
140- url : `/v4/addon-providers/addon-${ params . providerId } /addons/${ params . realId } /version/check` ,
141- headers : { Accept : 'application/json' } ,
142- // no queryParams
143- // no body
144- } ) ;
145- }
146-
147- /**
148- * @param {object } params
149- * @param {string } params.providerId
150- * @param {string } params.realId
151- * @param {object } body
152- */
153- export function updateOperatorVersion ( params , body ) {
154- // no multipath for /self or /organisations/{id}
155- return Promise . resolve ( {
156- method : 'post' ,
157- url : `/v4/addon-providers/addon-${ params . providerId } /addons/${ params . realId } /version/update` ,
158- headers : { Accept : 'application/json' , 'Content-Type' : 'application/json' } ,
159- // no queryParams
160- body,
161- } ) ;
162- }
163-
164- /**
165- * @param {OperatorVersionInfo } operatorVersionInfo
40+ * @param {CheckKeycloakVersionCommandOutput | CheckOtoroshiVersionCommandOutput | CheckMetabaseVersionCommandOutput } operatorVersionInfo
16641 * @returns {AddonInfoStateLoaded['version'] }
16742 **/
16843export function formatVersionState ( operatorVersionInfo ) {
@@ -182,3 +57,36 @@ export function formatVersionState(operatorVersionInfo) {
18257 latest : operatorVersionInfo . latest ,
18358 } ;
18459}
60+
61+ /**
62+ * Resolves the Grafana app link for an addon.
63+ *
64+ * - If `grafanaLink` is `null` (Grafana disabled in the console), returns `null`.
65+ * - If the Grafana org exists, builds a dashboard URL with the given `dashboardPath` and `appId`.
66+ * - If the Grafana org does not exist, falls back to `grafanaLink.console`.
67+ *
68+ * @param {object } params
69+ * @param {{ base: string, console: string } | null } params.grafanaLink
70+ * @param {string } params.ownerId
71+ * @param {string } params.dashboardPath - Grafana dashboard path (e.g. '/d/runtime/application-runtime')
72+ * @param {string } params.appId - Value for the `var-SELECT_APP` query parameter
73+ * @param {CcApiClient } params.ccApiClient
74+ * @param {AbortSignal } params.signal
75+ * @returns {Promise<string | null> }
76+ */
77+ export async function getGrafanaAppLink ( { grafanaLink, ownerId, dashboardPath, appId, ccApiClient, signal } ) {
78+ if ( grafanaLink == null ) {
79+ return null ;
80+ }
81+
82+ const grafanaOrg = await ccApiClient . send ( new GetGrafanaCommand ( { ownerId } ) , { signal } ) ;
83+
84+ if ( grafanaOrg != null ) {
85+ const url = new URL ( dashboardPath , grafanaLink . base ) ;
86+ url . searchParams . set ( 'orgId' , String ( grafanaOrg . id ) ) ;
87+ url . searchParams . set ( 'var-SELECT_APP' , appId ) ;
88+ return url . toString ( ) ;
89+ }
90+
91+ return grafanaLink . console ;
92+ }
0 commit comments