@backstage-community/plugin-jfrog-artifactory 1.15.2 → 1.16.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/CHANGELOG.md +16 -0
- package/README.md +15 -0
- package/dist/api/index.esm.js +4 -4
- package/dist/api/index.esm.js.map +1 -1
- package/dist/components/JfrogArtifactoryDashboardPage/JfrogArtifactoryDashboardPage.esm.js +2 -2
- package/dist/components/JfrogArtifactoryDashboardPage/JfrogArtifactoryDashboardPage.esm.js.map +1 -1
- package/dist/components/JfrogArtifactoryRepository/JfrogArtifactoryRepository.esm.js +2 -2
- package/dist/components/JfrogArtifactoryRepository/JfrogArtifactoryRepository.esm.js.map +1 -1
- package/dist/components/useJfrogArtifactoryAppData.esm.js +4 -2
- package/dist/components/useJfrogArtifactoryAppData.esm.js.map +1 -1
- package/dist/plugin.esm.js +2 -2
- package/package.json +1 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
### Dependencies
|
|
2
2
|
|
|
3
|
+
## 1.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3dab416: Adds the possibility to use multiple artifactory instances
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 7f18c19: remove devDependency on '@redhat-developer/red-hat-developer-hub-theme'
|
|
12
|
+
|
|
13
|
+
## 1.15.3
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 66718a0: remove unused devDependencies
|
|
18
|
+
|
|
3
19
|
## 1.15.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -27,6 +27,18 @@ The Jfrog Artifactory plugin displays information about your container images wi
|
|
|
27
27
|
secure: true
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
If you have multiple instances of artifactory supported, you can set up multiple proxy target paths as follows:
|
|
31
|
+
|
|
32
|
+
```yaml title="app-config.yaml"
|
|
33
|
+
proxy:
|
|
34
|
+
endpoints:
|
|
35
|
+
'/jfrog-instance1': # This is a local alias for the proxy endpoint, not the actual Artifactory hostname
|
|
36
|
+
target: 'https://<hostname1>'
|
|
37
|
+
# Rest of the config for hostname1
|
|
38
|
+
'/jfrog-instance2':
|
|
39
|
+
target: 'https://<hostname2>'
|
|
40
|
+
```
|
|
41
|
+
|
|
30
42
|
1. Enable the **JFROG ARTIFACTORY** tab on the entity view page in `packages/app/src/components/catalog/EntityPage.tsx`:
|
|
31
43
|
|
|
32
44
|
```ts title="packages/app/src/components/catalog/EntityPage.tsx"
|
|
@@ -60,6 +72,9 @@ The Jfrog Artifactory plugin displays information about your container images wi
|
|
|
60
72
|
metadata:
|
|
61
73
|
annotations:
|
|
62
74
|
'jfrog-artifactory/image-name': '<IMAGE-NAME>'
|
|
75
|
+
# if your app supports multiple artifactory instances,
|
|
76
|
+
# you'll need to specify the instance proxy target path your image belongs to
|
|
77
|
+
'jfrog-artifactory/target-proxy': '/<PROXY-TARGET>' # e.g. `/jfrog-instance1` from the example above
|
|
63
78
|
```
|
|
64
79
|
|
|
65
80
|
## For users
|
package/dist/api/index.esm.js
CHANGED
|
@@ -14,9 +14,9 @@ class JfrogArtifactoryApiClient {
|
|
|
14
14
|
this.configApi = options.configApi;
|
|
15
15
|
this.identityApi = options.identityApi;
|
|
16
16
|
}
|
|
17
|
-
async getBaseUrl() {
|
|
17
|
+
async getBaseUrl(target) {
|
|
18
18
|
const proxyPath = this.configApi.getOptionalString("jfrogArtifactory.proxyPath") || DEFAULT_PROXY_PATH;
|
|
19
|
-
return `${await this.discoveryApi.getBaseUrl("proxy")}${proxyPath}`;
|
|
19
|
+
return `${await this.discoveryApi.getBaseUrl("proxy")}${target ?? proxyPath}`;
|
|
20
20
|
}
|
|
21
21
|
async fetcher(url, query) {
|
|
22
22
|
const { token: idToken } = await this.identityApi.getCredentials();
|
|
@@ -35,8 +35,8 @@ class JfrogArtifactoryApiClient {
|
|
|
35
35
|
}
|
|
36
36
|
return await response.json();
|
|
37
37
|
}
|
|
38
|
-
async getTags(repo) {
|
|
39
|
-
const proxyUrl = await this.getBaseUrl();
|
|
38
|
+
async getTags(repo, target) {
|
|
39
|
+
const proxyUrl = await this.getBaseUrl(target);
|
|
40
40
|
const tagQuery = {
|
|
41
41
|
query: "query ($filter: VersionFilter!, $first: Int, $orderBy: VersionOrder) { versions (filter: $filter, first: $first, orderBy: $orderBy) { edges { node { name, created, modified, package { id }, repos { name, type, leadFilePath }, licenses { name, source }, size, stats { downloadCount }, vulnerabilities { critical, high, medium, low, info, unknown, skipped }, files { name, lead, size, md5, sha1, sha256, mimeType } } } } }",
|
|
42
42
|
variables: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ConfigApi,\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\n\nimport { TagsResponse } from '../types';\n\nconst DEFAULT_PROXY_PATH = '/jfrog-artifactory/api';\n\nexport interface JfrogArtifactoryApiV1 {\n getTags(repo: string): Promise<TagsResponse>;\n}\n\nexport const jfrogArtifactoryApiRef = createApiRef<JfrogArtifactoryApiV1>({\n id: 'plugin.jfrog-artifactory.service',\n});\n\nexport type Options = {\n discoveryApi: DiscoveryApi;\n configApi: ConfigApi;\n identityApi: IdentityApi;\n};\n\nexport class JfrogArtifactoryApiClient implements JfrogArtifactoryApiV1 {\n // @ts-ignore\n private readonly discoveryApi: DiscoveryApi;\n\n private readonly configApi: ConfigApi;\n\n private readonly identityApi: IdentityApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n this.identityApi = options.identityApi;\n }\n\n private async getBaseUrl() {\n const proxyPath =\n this.configApi.getOptionalString('jfrogArtifactory.proxyPath') ||\n DEFAULT_PROXY_PATH;\n return `${await this.discoveryApi.getBaseUrl('proxy')}${proxyPath}`;\n }\n\n private async fetcher(url: string, query: string) {\n const { token: idToken } = await this.identityApi.getCredentials();\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(idToken && { Authorization: `Bearer ${idToken}` }),\n },\n method: 'POST',\n body: query,\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n\n async getTags(repo: string) {\n const proxyUrl = await this.getBaseUrl();\n const tagQuery = {\n query:\n 'query ($filter: VersionFilter!, $first: Int, $orderBy: VersionOrder) { versions (filter: $filter, first: $first, orderBy: $orderBy) { edges { node { name, created, modified, package { id }, repos { name, type, leadFilePath }, licenses { name, source }, size, stats { downloadCount }, vulnerabilities { critical, high, medium, low, info, unknown, skipped }, files { name, lead, size, md5, sha1, sha256, mimeType } } } } }',\n variables: {\n filter: {\n packageId: `docker://${repo}`,\n name: '*',\n ignorePreRelease: false,\n },\n first: 100,\n orderBy: {\n field: 'NAME_SEMVER',\n direction: 'DESC',\n },\n },\n };\n\n return (await this.fetcher(\n `${proxyUrl}/metadata/api/v1/query`,\n JSON.stringify(tagQuery),\n )) as TagsResponse;\n }\n}\n"],"names":[],"mappings":";;AAwBA,MAAM,kBAAqB,GAAA,wBAAA;AAMpB,MAAM,yBAAyB,YAAoC,CAAA;AAAA,EACxE,EAAI,EAAA;AACN,CAAC;AAQM,MAAM,yBAA2D,CAAA;AAAA;AAAA,EAErD,YAAA;AAAA,EAEA,SAAA;AAAA,EAEA,WAAA;AAAA,EAEjB,YAAY,OAAkB,EAAA;AAC5B,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,SAAA;AACzB,IAAA,IAAA,CAAK,cAAc,OAAQ,CAAA,WAAA;AAAA;AAC7B,EAEA,MAAc,
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ConfigApi,\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\n\nimport { TagsResponse } from '../types';\n\nconst DEFAULT_PROXY_PATH = '/jfrog-artifactory/api';\n\nexport interface JfrogArtifactoryApiV1 {\n getTags(repo: string, target?: string): Promise<TagsResponse>;\n}\n\nexport const jfrogArtifactoryApiRef = createApiRef<JfrogArtifactoryApiV1>({\n id: 'plugin.jfrog-artifactory.service',\n});\n\nexport type Options = {\n discoveryApi: DiscoveryApi;\n configApi: ConfigApi;\n identityApi: IdentityApi;\n};\n\nexport class JfrogArtifactoryApiClient implements JfrogArtifactoryApiV1 {\n // @ts-ignore\n private readonly discoveryApi: DiscoveryApi;\n\n private readonly configApi: ConfigApi;\n\n private readonly identityApi: IdentityApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n this.identityApi = options.identityApi;\n }\n\n private async getBaseUrl(target?: string) {\n const proxyPath =\n this.configApi.getOptionalString('jfrogArtifactory.proxyPath') ||\n DEFAULT_PROXY_PATH;\n return `${await this.discoveryApi.getBaseUrl('proxy')}${\n target ?? proxyPath\n }`;\n }\n\n private async fetcher(url: string, query: string) {\n const { token: idToken } = await this.identityApi.getCredentials();\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(idToken && { Authorization: `Bearer ${idToken}` }),\n },\n method: 'POST',\n body: query,\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n\n async getTags(repo: string, target?: string) {\n const proxyUrl = await this.getBaseUrl(target);\n const tagQuery = {\n query:\n 'query ($filter: VersionFilter!, $first: Int, $orderBy: VersionOrder) { versions (filter: $filter, first: $first, orderBy: $orderBy) { edges { node { name, created, modified, package { id }, repos { name, type, leadFilePath }, licenses { name, source }, size, stats { downloadCount }, vulnerabilities { critical, high, medium, low, info, unknown, skipped }, files { name, lead, size, md5, sha1, sha256, mimeType } } } } }',\n variables: {\n filter: {\n packageId: `docker://${repo}`,\n name: '*',\n ignorePreRelease: false,\n },\n first: 100,\n orderBy: {\n field: 'NAME_SEMVER',\n direction: 'DESC',\n },\n },\n };\n\n return (await this.fetcher(\n `${proxyUrl}/metadata/api/v1/query`,\n JSON.stringify(tagQuery),\n )) as TagsResponse;\n }\n}\n"],"names":[],"mappings":";;AAwBA,MAAM,kBAAqB,GAAA,wBAAA;AAMpB,MAAM,yBAAyB,YAAoC,CAAA;AAAA,EACxE,EAAI,EAAA;AACN,CAAC;AAQM,MAAM,yBAA2D,CAAA;AAAA;AAAA,EAErD,YAAA;AAAA,EAEA,SAAA;AAAA,EAEA,WAAA;AAAA,EAEjB,YAAY,OAAkB,EAAA;AAC5B,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,SAAA;AACzB,IAAA,IAAA,CAAK,cAAc,OAAQ,CAAA,WAAA;AAAA;AAC7B,EAEA,MAAc,WAAW,MAAiB,EAAA;AACxC,IAAA,MAAM,SACJ,GAAA,IAAA,CAAK,SAAU,CAAA,iBAAA,CAAkB,4BAA4B,CAC7D,IAAA,kBAAA;AACF,IAAO,OAAA,CAAA,EAAG,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,OAAO,CAAC,CACnD,EAAA,MAAA,IAAU,SACZ,CAAA,CAAA;AAAA;AACF,EAEA,MAAc,OAAQ,CAAA,GAAA,EAAa,KAAe,EAAA;AAChD,IAAA,MAAM,EAAE,KAAO,EAAA,OAAA,KAAY,MAAM,IAAA,CAAK,YAAY,cAAe,EAAA;AACjE,IAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAK,EAAA;AAAA,MAChC,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,GAAI,OAAW,IAAA,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,OAAO,CAAG,CAAA;AAAA,OACtD;AAAA,MACA,MAAQ,EAAA,MAAA;AAAA,MACR,IAAM,EAAA;AAAA,KACP,CAAA;AACD,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAgC,6BAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,OACzE;AAAA;AAEF,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,OAAQ,CAAA,IAAA,EAAc,MAAiB,EAAA;AAC3C,IAAA,MAAM,QAAW,GAAA,MAAM,IAAK,CAAA,UAAA,CAAW,MAAM,CAAA;AAC7C,IAAA,MAAM,QAAW,GAAA;AAAA,MACf,KACE,EAAA,saAAA;AAAA,MACF,SAAW,EAAA;AAAA,QACT,MAAQ,EAAA;AAAA,UACN,SAAA,EAAW,YAAY,IAAI,CAAA,CAAA;AAAA,UAC3B,IAAM,EAAA,GAAA;AAAA,UACN,gBAAkB,EAAA;AAAA,SACpB;AAAA,QACA,KAAO,EAAA,GAAA;AAAA,QACP,OAAS,EAAA;AAAA,UACP,KAAO,EAAA,aAAA;AAAA,UACP,SAAW,EAAA;AAAA;AACb;AACF,KACF;AAEA,IAAA,OAAQ,MAAM,IAAK,CAAA,OAAA;AAAA,MACjB,GAAG,QAAQ,CAAA,sBAAA,CAAA;AAAA,MACX,IAAA,CAAK,UAAU,QAAQ;AAAA,KACzB;AAAA;AAEJ;;;;"}
|
|
@@ -5,8 +5,8 @@ import { useJfrogArtifactoryAppData } from '../useJfrogArtifactoryAppData.esm.js
|
|
|
5
5
|
|
|
6
6
|
const JfrogArtifactoryDashboardPage = () => {
|
|
7
7
|
const { entity } = useEntity();
|
|
8
|
-
const { imageName } = useJfrogArtifactoryAppData({ entity });
|
|
9
|
-
return /* @__PURE__ */ jsx(JfrogArtifactoryRepository, { image: imageName });
|
|
8
|
+
const { imageName, targetProxy } = useJfrogArtifactoryAppData({ entity });
|
|
9
|
+
return /* @__PURE__ */ jsx(JfrogArtifactoryRepository, { image: imageName, target: targetProxy });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export { JfrogArtifactoryDashboardPage };
|
package/dist/components/JfrogArtifactoryDashboardPage/JfrogArtifactoryDashboardPage.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfrogArtifactoryDashboardPage.esm.js","sources":["../../../src/components/JfrogArtifactoryDashboardPage/JfrogArtifactoryDashboardPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nimport { JfrogArtifactoryRepository } from '../JfrogArtifactoryRepository';\nimport { useJfrogArtifactoryAppData } from '../useJfrogArtifactoryAppData';\n\nexport const JfrogArtifactoryDashboardPage = () => {\n const { entity } = useEntity();\n const { imageName } = useJfrogArtifactoryAppData({ entity });\n\n return <JfrogArtifactoryRepository image={imageName} />;\n};\n"],"names":[],"mappings":";;;;;AAoBO,MAAM,gCAAgC,MAAM;AACjD,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAA,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"JfrogArtifactoryDashboardPage.esm.js","sources":["../../../src/components/JfrogArtifactoryDashboardPage/JfrogArtifactoryDashboardPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nimport { JfrogArtifactoryRepository } from '../JfrogArtifactoryRepository';\nimport { useJfrogArtifactoryAppData } from '../useJfrogArtifactoryAppData';\n\nexport const JfrogArtifactoryDashboardPage = () => {\n const { entity } = useEntity();\n const { imageName, targetProxy } = useJfrogArtifactoryAppData({ entity });\n\n return <JfrogArtifactoryRepository image={imageName} target={targetProxy} />;\n};\n"],"names":[],"mappings":";;;;;AAoBO,MAAM,gCAAgC,MAAM;AACjD,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAA,MAAM,EAAE,SAAW,EAAA,WAAA,KAAgB,0BAA2B,CAAA,EAAE,QAAQ,CAAA;AAExE,EAAA,uBAAQ,GAAA,CAAA,0BAAA,EAAA,EAA2B,KAAO,EAAA,SAAA,EAAW,QAAQ,WAAa,EAAA,CAAA;AAC5E;;;;"}
|
|
@@ -19,14 +19,14 @@ const useLocalStyles = makeStyles({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
function JfrogArtifactoryRepository({ image }) {
|
|
22
|
+
function JfrogArtifactoryRepository({ image, target }) {
|
|
23
23
|
const jfrogArtifactoryClient = useApi(jfrogArtifactoryApiRef);
|
|
24
24
|
const classes = useStyles();
|
|
25
25
|
const localClasses = useLocalStyles();
|
|
26
26
|
const [edges, setEdges] = useState([]);
|
|
27
27
|
const titleprop = `Jfrog Artifactory repository: ${image}`;
|
|
28
28
|
const { loading } = useAsync(async () => {
|
|
29
|
-
const tagsResponse = await jfrogArtifactoryClient.getTags(image);
|
|
29
|
+
const tagsResponse = await jfrogArtifactoryClient.getTags(image, target);
|
|
30
30
|
setEdges(tagsResponse.data.versions.edges);
|
|
31
31
|
return tagsResponse;
|
|
32
32
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfrogArtifactoryRepository.esm.js","sources":["../../../src/components/JfrogArtifactoryRepository/JfrogArtifactoryRepository.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Link, Progress, Table } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { Box, Chip, makeStyles } from '@material-ui/core';\n\nimport { formatDate } from '@janus-idp/shared-react';\n\nimport { jfrogArtifactoryApiRef } from '../../api';\nimport { Edge } from '../../types';\nimport { columns, useStyles } from './tableHeading';\nimport { formatByteSize } from '../../utils';\n\nconst useLocalStyles = makeStyles({\n chip: {\n margin: 0,\n marginRight: '.2em',\n height: '1.5em',\n '& > span': {\n padding: '.3em',\n },\n },\n});\n\nexport function JfrogArtifactoryRepository({ image }: RepositoryProps) {\n const jfrogArtifactoryClient = useApi(jfrogArtifactoryApiRef);\n const classes = useStyles();\n const localClasses = useLocalStyles();\n const [edges, setEdges] = useState<Edge[]>([]);\n const titleprop = `Jfrog Artifactory repository: ${image}`;\n\n const { loading } = useAsync(async () => {\n const tagsResponse = await jfrogArtifactoryClient.getTags(image);\n\n setEdges(tagsResponse.data.versions.edges);\n\n return tagsResponse;\n });\n\n if (loading) {\n return <Progress />;\n }\n\n const data = edges?.map((edge: Edge) => {\n const shortHash = edge.node.files\n .find(manifest => manifest.name === 'manifest.json')\n ?.sha256.substring(0, 12);\n return {\n name: edge.node.name,\n last_modified: formatDate(edge.node.modified),\n size: formatByteSize(Number(edge.node.size)),\n manifest_digest: (\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <Chip label=\"sha256\" className={localClasses.chip} />\n {shortHash}\n </Box>\n ),\n repositories:\n `${edge.node.repos.length}` +\n ' | ' +\n `${edge.node.repos.map(repo => repo.name).join('| ')}`,\n };\n });\n\n return (\n <div style={{ border: '1px solid #ddd' }}>\n <Table\n title={titleprop}\n options={{ paging: true, padding: 'dense' }}\n data={data}\n columns={columns}\n emptyContent={\n <div className={classes.empty}>\n No data was added yet, \n <Link to=\"https://backstage.io/\">learn how to add data</Link>.\n </div>\n }\n />\n </div>\n );\n}\n\ninterface RepositoryProps {\n image: string;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA8BA,MAAM,iBAAiB,UAAW,CAAA;AAAA,EAChC,IAAM,EAAA;AAAA,IACJ,MAAQ,EAAA,CAAA;AAAA,IACR,WAAa,EAAA,MAAA;AAAA,IACb,MAAQ,EAAA,OAAA;AAAA,IACR,UAAY,EAAA;AAAA,MACV,OAAS,EAAA;AAAA;AACX;AAEJ,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"JfrogArtifactoryRepository.esm.js","sources":["../../../src/components/JfrogArtifactoryRepository/JfrogArtifactoryRepository.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Link, Progress, Table } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { Box, Chip, makeStyles } from '@material-ui/core';\n\nimport { formatDate } from '@janus-idp/shared-react';\n\nimport { jfrogArtifactoryApiRef } from '../../api';\nimport { Edge } from '../../types';\nimport { columns, useStyles } from './tableHeading';\nimport { formatByteSize } from '../../utils';\n\nconst useLocalStyles = makeStyles({\n chip: {\n margin: 0,\n marginRight: '.2em',\n height: '1.5em',\n '& > span': {\n padding: '.3em',\n },\n },\n});\n\nexport function JfrogArtifactoryRepository({ image, target }: RepositoryProps) {\n const jfrogArtifactoryClient = useApi(jfrogArtifactoryApiRef);\n const classes = useStyles();\n const localClasses = useLocalStyles();\n const [edges, setEdges] = useState<Edge[]>([]);\n const titleprop = `Jfrog Artifactory repository: ${image}`;\n\n const { loading } = useAsync(async () => {\n const tagsResponse = await jfrogArtifactoryClient.getTags(image, target);\n\n setEdges(tagsResponse.data.versions.edges);\n\n return tagsResponse;\n });\n\n if (loading) {\n return <Progress />;\n }\n\n const data = edges?.map((edge: Edge) => {\n const shortHash = edge.node.files\n .find(manifest => manifest.name === 'manifest.json')\n ?.sha256.substring(0, 12);\n return {\n name: edge.node.name,\n last_modified: formatDate(edge.node.modified),\n size: formatByteSize(Number(edge.node.size)),\n manifest_digest: (\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <Chip label=\"sha256\" className={localClasses.chip} />\n {shortHash}\n </Box>\n ),\n repositories:\n `${edge.node.repos.length}` +\n ' | ' +\n `${edge.node.repos.map(repo => repo.name).join('| ')}`,\n };\n });\n\n return (\n <div style={{ border: '1px solid #ddd' }}>\n <Table\n title={titleprop}\n options={{ paging: true, padding: 'dense' }}\n data={data}\n columns={columns}\n emptyContent={\n <div className={classes.empty}>\n No data was added yet, \n <Link to=\"https://backstage.io/\">learn how to add data</Link>.\n </div>\n }\n />\n </div>\n );\n}\n\ninterface RepositoryProps {\n image: string;\n target?: string;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA8BA,MAAM,iBAAiB,UAAW,CAAA;AAAA,EAChC,IAAM,EAAA;AAAA,IACJ,MAAQ,EAAA,CAAA;AAAA,IACR,WAAa,EAAA,MAAA;AAAA,IACb,MAAQ,EAAA,OAAA;AAAA,IACR,UAAY,EAAA;AAAA,MACV,OAAS,EAAA;AAAA;AACX;AAEJ,CAAC,CAAA;AAEM,SAAS,0BAA2B,CAAA,EAAE,KAAO,EAAA,MAAA,EAA2B,EAAA;AAC7E,EAAM,MAAA,sBAAA,GAAyB,OAAO,sBAAsB,CAAA;AAC5D,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,eAAe,cAAe,EAAA;AACpC,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAiB,EAAE,CAAA;AAC7C,EAAM,MAAA,SAAA,GAAY,iCAAiC,KAAK,CAAA,CAAA;AAExD,EAAA,MAAM,EAAE,OAAA,EAAY,GAAA,QAAA,CAAS,YAAY;AACvC,IAAA,MAAM,YAAe,GAAA,MAAM,sBAAuB,CAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAEvE,IAAS,QAAA,CAAA,YAAA,CAAa,IAAK,CAAA,QAAA,CAAS,KAAK,CAAA;AAEzC,IAAO,OAAA,YAAA;AAAA,GACR,CAAA;AAED,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2BAAQ,QAAS,EAAA,EAAA,CAAA;AAAA;AAGnB,EAAA,MAAM,IAAO,GAAA,KAAA,EAAO,GAAI,CAAA,CAAC,IAAe,KAAA;AACtC,IAAA,MAAM,SAAY,GAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CACzB,IAAK,CAAA,CAAA,QAAA,KAAY,QAAS,CAAA,IAAA,KAAS,eAAe,CAAA,EACjD,MAAO,CAAA,SAAA,CAAU,GAAG,EAAE,CAAA;AAC1B,IAAO,OAAA;AAAA,MACL,IAAA,EAAM,KAAK,IAAK,CAAA,IAAA;AAAA,MAChB,aAAe,EAAA,UAAA,CAAW,IAAK,CAAA,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC5C,MAAM,cAAe,CAAA,MAAA,CAAO,IAAK,CAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MAC3C,eAAA,uBACG,GAAI,EAAA,EAAA,EAAA,EAAI,EAAE,OAAS,EAAA,MAAA,EAAQ,UAAY,EAAA,QAAA,EACtC,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAM,QAAS,EAAA,SAAA,EAAW,aAAa,IAAM,EAAA,CAAA;AAAA,QAClD;AAAA,OACH,EAAA,CAAA;AAAA,MAEF,cACE,CAAG,EAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAM,MAAM,CAEtB,GAAA,EAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAM,IAAI,CAAQ,IAAA,KAAA,IAAA,CAAK,IAAI,CAAE,CAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACxD;AAAA,GACD,CAAA;AAED,EAAA,2BACG,KAAI,EAAA,EAAA,KAAA,EAAO,EAAE,MAAA,EAAQ,kBACpB,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAO,EAAA,SAAA;AAAA,MACP,OAAS,EAAA,EAAE,MAAQ,EAAA,IAAA,EAAM,SAAS,OAAQ,EAAA;AAAA,MAC1C,IAAA;AAAA,MACA,OAAA;AAAA,MACA,YACE,kBAAA,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,KAAO,EAAA,QAAA,EAAA;AAAA,QAAA,4BAAA;AAAA,wBAE5B,GAAA,CAAA,IAAA,EAAA,EAAK,EAAG,EAAA,uBAAA,EAAwB,QAAqB,EAAA,uBAAA,EAAA,CAAA;AAAA,QAAO;AAAA,OAC/D,EAAA;AAAA;AAAA,GAGN,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME = "jfrog-artifactory/image-name";
|
|
2
|
+
const JFROG_ARTIFACTORY_ANNOTATION_TARGET_PROXY = "jfrog-artifactory/target-proxy";
|
|
2
3
|
const useJfrogArtifactoryAppData = ({ entity }) => {
|
|
3
4
|
const imageName = entity?.metadata.annotations?.[JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME] ?? "";
|
|
5
|
+
const targetProxy = entity?.metadata.annotations?.[JFROG_ARTIFACTORY_ANNOTATION_TARGET_PROXY];
|
|
4
6
|
if (!imageName) {
|
|
5
7
|
throw new Error("'Jfrog Artifactory' annotations are missing");
|
|
6
8
|
}
|
|
7
|
-
return { imageName };
|
|
9
|
+
return { imageName, targetProxy };
|
|
8
10
|
};
|
|
9
11
|
|
|
10
|
-
export { JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME, useJfrogArtifactoryAppData };
|
|
12
|
+
export { JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME, JFROG_ARTIFACTORY_ANNOTATION_TARGET_PROXY, useJfrogArtifactoryAppData };
|
|
11
13
|
//# sourceMappingURL=useJfrogArtifactoryAppData.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useJfrogArtifactoryAppData.esm.js","sources":["../../src/components/useJfrogArtifactoryAppData.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\n\nexport const JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME =\n 'jfrog-artifactory/image-name';\n\nexport const useJfrogArtifactoryAppData = ({ entity }: { entity: Entity }) => {\n const imageName =\n entity?.metadata.annotations?.[JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME] ??\n '';\n\n if (!imageName) {\n throw new Error(\"'Jfrog Artifactory' annotations are missing\");\n }\n return { imageName };\n};\n"],"names":[],"mappings":"AAiBO,MAAM,uCACX,GAAA;AAEK,MAAM,0BAA6B,GAAA,CAAC,EAAE,MAAA,EAAiC,KAAA;AAC5E,EAAA,MAAM,SACJ,GAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAc,uCAAuC,CACtE,IAAA,EAAA;AAEF,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAM,MAAA,IAAI,MAAM,6CAA6C,CAAA;AAAA;AAE/D,
|
|
1
|
+
{"version":3,"file":"useJfrogArtifactoryAppData.esm.js","sources":["../../src/components/useJfrogArtifactoryAppData.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\n\nexport const JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME =\n 'jfrog-artifactory/image-name';\n\nexport const JFROG_ARTIFACTORY_ANNOTATION_TARGET_PROXY =\n 'jfrog-artifactory/target-proxy';\n\nexport const useJfrogArtifactoryAppData = ({ entity }: { entity: Entity }) => {\n const imageName =\n entity?.metadata.annotations?.[JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME] ??\n '';\n\n const targetProxy =\n entity?.metadata.annotations?.[JFROG_ARTIFACTORY_ANNOTATION_TARGET_PROXY];\n\n if (!imageName) {\n throw new Error(\"'Jfrog Artifactory' annotations are missing\");\n }\n return { imageName, targetProxy };\n};\n"],"names":[],"mappings":"AAiBO,MAAM,uCACX,GAAA;AAEK,MAAM,yCACX,GAAA;AAEK,MAAM,0BAA6B,GAAA,CAAC,EAAE,MAAA,EAAiC,KAAA;AAC5E,EAAA,MAAM,SACJ,GAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAc,uCAAuC,CACtE,IAAA,EAAA;AAEF,EAAA,MAAM,WACJ,GAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAc,yCAAyC,CAAA;AAE1E,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAM,MAAA,IAAI,MAAM,6CAA6C,CAAA;AAAA;AAE/D,EAAO,OAAA,EAAE,WAAW,WAAY,EAAA;AAClC;;;;"}
|
package/dist/plugin.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createPlugin, createApiFactory,
|
|
2
|
-
import {
|
|
1
|
+
import { createPlugin, createApiFactory, identityApiRef, configApiRef, discoveryApiRef, createComponentExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { JfrogArtifactoryApiClient, jfrogArtifactoryApiRef } from './api/index.esm.js';
|
|
3
3
|
import { JFROG_ARTIFACTORY_ANNOTATION_IMAGE_NAME } from './components/useJfrogArtifactoryAppData.esm.js';
|
|
4
4
|
import { rootRouteRef } from './routes.esm.js';
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage-community/plugin-jfrog-artifactory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"main": "dist/index.esm.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -46,15 +46,11 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@backstage/cli": "^0.32.1",
|
|
49
|
-
"@backstage/core-app-api": "^1.17.0",
|
|
50
49
|
"@backstage/dev-utils": "^1.1.10",
|
|
51
50
|
"@backstage/test-utils": "^1.7.8",
|
|
52
|
-
"@redhat-developer/red-hat-developer-hub-theme": "0.4.0",
|
|
53
51
|
"@testing-library/jest-dom": "6.6.3",
|
|
54
52
|
"@testing-library/react": "14.3.1",
|
|
55
|
-
"@testing-library/user-event": "14.6.1",
|
|
56
53
|
"cross-fetch": "4.0.0",
|
|
57
|
-
"msw": "1.3.5",
|
|
58
54
|
"react-router-dom": "^6.26.2"
|
|
59
55
|
},
|
|
60
56
|
"files": [
|