@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.2.0 → 6.4.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 +26 -0
- package/README.md +28 -0
- package/config.d.ts +9 -1
- package/dist/catalog/catalogHttpClient.cjs.js +3 -0
- package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
- package/dist/catalog/catalogInfoGenerator.cjs.js +1 -0
- package/dist/catalog/catalogInfoGenerator.cjs.js.map +1 -1
- package/dist/database/migration.cjs.js +20 -0
- package/dist/database/migration.cjs.js.map +1 -0
- package/dist/database/repositoryDao.cjs.js +117 -0
- package/dist/database/repositoryDao.cjs.js.map +1 -0
- package/dist/generated/openapidocument.cjs.js +366 -38
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +222 -95
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/github/utils/orgUtils.cjs.js +2 -0
- package/dist/github/utils/orgUtils.cjs.js.map +1 -1
- package/dist/github/utils/prUtils.cjs.js +3 -0
- package/dist/github/utils/prUtils.cjs.js.map +1 -1
- package/dist/github/utils/repoUtils.cjs.js +1 -38
- package/dist/github/utils/repoUtils.cjs.js.map +1 -1
- package/dist/github/utils/utils.cjs.js +29 -18
- package/dist/github/utils/utils.cjs.js.map +1 -1
- package/dist/gitlab/GitlabAppManager.cjs.js +54 -0
- package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -0
- package/dist/gitlab/gitlabApiService.cjs.js +660 -0
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -0
- package/dist/gitlab/utils/glUtils.cjs.js +15 -0
- package/dist/gitlab/utils/glUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/orgUtils.cjs.js +72 -0
- package/dist/gitlab/utils/orgUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/prUtils.cjs.js +73 -0
- package/dist/gitlab/utils/prUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/repoUtils.cjs.js +200 -0
- package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/utils.cjs.js +131 -0
- package/dist/gitlab/utils/utils.cjs.js.map +1 -0
- package/dist/helpers/utils.cjs.js +58 -0
- package/dist/helpers/utils.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/plugin.cjs.js +6 -3
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +216 -34
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/execute-template.cjs.js +264 -0
- package/dist/service/handlers/import/execute-template.cjs.js.map +1 -0
- package/dist/service/handlers/import/importStatus.cjs.js +5 -8
- package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
- package/dist/service/handlers/organization/organizations.cjs.js +2 -2
- package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
- package/dist/service/handlers/repository/repositories.cjs.js +5 -2
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +199 -34
- package/dist/service/router.cjs.js.map +1 -1
- package/migrations/20250808122501_migrations.js +53 -0
- package/package.json +17 -11
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('@backstage/errors');
|
|
4
|
+
require('@backstage/plugin-permission-common');
|
|
5
|
+
require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
6
|
+
require('just-kebab-case');
|
|
7
|
+
var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
|
|
8
|
+
require('@backstage/catalog-model');
|
|
9
|
+
require('git-url-parse');
|
|
10
|
+
var glUtils = require('./glUtils.cjs.js');
|
|
11
|
+
var repoUtils = require('./repoUtils.cjs.js');
|
|
12
|
+
|
|
13
|
+
function createCredentialError(err) {
|
|
14
|
+
if (err) {
|
|
15
|
+
return {
|
|
16
|
+
type: "token",
|
|
17
|
+
error: {
|
|
18
|
+
name: err.name,
|
|
19
|
+
message: err.message
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
function verifyAndGetIntegrations(deps, integrations) {
|
|
26
|
+
const glConfigs = integrations.gitlab.list().map((glInit) => glInit.config);
|
|
27
|
+
if (glConfigs.length === 0) {
|
|
28
|
+
deps.logger.debug(
|
|
29
|
+
"No GitLab Integration in config => returning an empty list of repositories."
|
|
30
|
+
);
|
|
31
|
+
throw new Error(
|
|
32
|
+
"Looks like there is no GitLab Integration in config. Please add a configuration entry under 'integrations.gitlab"
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return glConfigs;
|
|
36
|
+
}
|
|
37
|
+
async function getCredentialsFromIntegrations(gitlabCredentialsProvider, glConfigs) {
|
|
38
|
+
const credentialsByConfig = /* @__PURE__ */ new Map();
|
|
39
|
+
for (const glConfig of glConfigs) {
|
|
40
|
+
const creds = await getCredentialsForConfig(
|
|
41
|
+
gitlabCredentialsProvider,
|
|
42
|
+
glConfig
|
|
43
|
+
);
|
|
44
|
+
credentialsByConfig.set(glConfig, creds);
|
|
45
|
+
}
|
|
46
|
+
return credentialsByConfig;
|
|
47
|
+
}
|
|
48
|
+
async function getCredentialsForConfig(gitlabCredentialsProvider, glConfig) {
|
|
49
|
+
return await gitlabCredentialsProvider.getAllCredentials({
|
|
50
|
+
host: glConfig.host
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function handleError(deps, desc, _credential, errors, err) {
|
|
54
|
+
loggingUtils.logErrorIfNeeded(deps.logger, `${desc} failed`, err);
|
|
55
|
+
const credentialError = createCredentialError(err);
|
|
56
|
+
if (credentialError) {
|
|
57
|
+
errors.set(-1, credentialError);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function computeTotalCountFromPaginationInfo(deps, paginationInfo, pageSize) {
|
|
61
|
+
if (isNaN(paginationInfo.total)) {
|
|
62
|
+
deps.logger.debug(
|
|
63
|
+
`Too many result, total count is NaN, returning current page size`
|
|
64
|
+
);
|
|
65
|
+
return pageSize;
|
|
66
|
+
}
|
|
67
|
+
return paginationInfo.total;
|
|
68
|
+
}
|
|
69
|
+
async function executeFunctionOnFirstSuccessfulIntegration(deps, integrations, params) {
|
|
70
|
+
const validatedRepo = await repoUtils.validateAndBuildRepoData(
|
|
71
|
+
deps.gitlabCredentialsProvider,
|
|
72
|
+
integrations,
|
|
73
|
+
deps.config,
|
|
74
|
+
params
|
|
75
|
+
);
|
|
76
|
+
for (const credential of validatedRepo.credentials) {
|
|
77
|
+
const glKit = glUtils.buildGitlab(
|
|
78
|
+
deps,
|
|
79
|
+
{ credential, owner: validatedRepo.owner },
|
|
80
|
+
validatedRepo.glConfig.baseUrl
|
|
81
|
+
);
|
|
82
|
+
const res = await params.fn(validatedRepo, glKit);
|
|
83
|
+
if (!res.successful) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
return res.result;
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
async function fetchFromAllIntegrations(deps, integrations, params) {
|
|
91
|
+
const glConfigs = verifyAndGetIntegrations(deps, integrations);
|
|
92
|
+
const credentialsByConfig = await getCredentialsFromIntegrations(
|
|
93
|
+
deps.gitlabCredentialsProvider,
|
|
94
|
+
glConfigs
|
|
95
|
+
);
|
|
96
|
+
const errors = /* @__PURE__ */ new Map();
|
|
97
|
+
const data = [];
|
|
98
|
+
const dataErrs = [];
|
|
99
|
+
let stopFetchingData = false;
|
|
100
|
+
for (const [glConfig, credentials] of credentialsByConfig) {
|
|
101
|
+
if (stopFetchingData) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
deps.logger.debug(
|
|
105
|
+
`Got ${credentials.length} credential(s) for ${glConfig.host}`
|
|
106
|
+
);
|
|
107
|
+
for (const credential of credentials) {
|
|
108
|
+
const glKit = glUtils.buildGitlab(deps, { credential, errors }, glConfig.baseUrl);
|
|
109
|
+
const res = await params.dataFetcher(glKit, credential, glConfig);
|
|
110
|
+
res.errors?.forEach((err) => dataErrs.push(err));
|
|
111
|
+
if (res.result) {
|
|
112
|
+
data.push(res.result);
|
|
113
|
+
}
|
|
114
|
+
stopFetchingData = res.stopFetchingData;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const aggregatedErrors = /* @__PURE__ */ new Map();
|
|
118
|
+
errors.forEach((err, num) => aggregatedErrors.set(num, err));
|
|
119
|
+
dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));
|
|
120
|
+
return { data, errors: aggregatedErrors };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
exports.computeTotalCountFromPaginationInfo = computeTotalCountFromPaginationInfo;
|
|
124
|
+
exports.createCredentialError = createCredentialError;
|
|
125
|
+
exports.executeFunctionOnFirstSuccessfulIntegration = executeFunctionOnFirstSuccessfulIntegration;
|
|
126
|
+
exports.fetchFromAllIntegrations = fetchFromAllIntegrations;
|
|
127
|
+
exports.getCredentialsForConfig = getCredentialsForConfig;
|
|
128
|
+
exports.getCredentialsFromIntegrations = getCredentialsFromIntegrations;
|
|
129
|
+
exports.handleError = handleError;
|
|
130
|
+
exports.verifyAndGetIntegrations = verifyAndGetIntegrations;
|
|
131
|
+
//# sourceMappingURL=utils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs.js","sources":["../../../src/gitlab/utils/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n CacheService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n ScmIntegrations,\n type GitLabIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Gitlab, OffsetPagination } from '@gitbeaker/rest';\n\nimport { logErrorIfNeeded } from '../../helpers';\nimport type { CustomGitlabCredentialsProvider } from '../GitlabAppManager';\nimport {\n type ExtendedGitlabCredentials,\n type GitlabFetchError,\n} from '../types';\nimport { buildGitlab } from './glUtils';\nimport { validateAndBuildRepoData, ValidatedRepo } from './repoUtils';\n\n// /**\n// * Creates the GitlabFetchError to be stored in the returned errors array of the returned GitlabRepositoryResponse object\n// */\nexport function createCredentialError(\n err?: Error,\n): GitlabFetchError | undefined {\n if (err) {\n return {\n type: 'token',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n return undefined;\n}\n\nexport function verifyAndGetIntegrations(\n deps: {\n logger: LoggerService;\n },\n\n integrations: ScmIntegrations,\n) {\n const glConfigs = integrations.gitlab.list().map(glInit => glInit.config);\n\n if (glConfigs.length === 0) {\n deps.logger.debug(\n 'No GitLab Integration in config => returning an empty list of repositories.',\n );\n throw new Error(\n \"Looks like there is no GitLab Integration in config. Please add a configuration entry under 'integrations.gitlab\",\n );\n }\n return glConfigs;\n}\n\nexport async function getCredentialsFromIntegrations(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n glConfigs: GitLabIntegrationConfig[],\n) {\n const credentialsByConfig = new Map<\n GitLabIntegrationConfig,\n ExtendedGitlabCredentials[]\n >();\n for (const glConfig of glConfigs) {\n const creds = await getCredentialsForConfig(\n gitlabCredentialsProvider,\n glConfig,\n );\n credentialsByConfig.set(glConfig, creds);\n }\n return credentialsByConfig;\n}\n\nexport async function getCredentialsForConfig(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n glConfig: GitLabIntegrationConfig,\n) {\n return await gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n}\n\nexport function handleError(\n deps: {\n logger: LoggerService;\n },\n desc: string,\n _credential: ExtendedGitlabCredentials,\n errors: Map<number, GitlabFetchError>,\n err: any,\n) {\n logErrorIfNeeded(deps.logger, `${desc} failed`, err);\n const credentialError = createCredentialError(err as Error);\n if (credentialError) {\n errors.set(-1, credentialError);\n }\n}\n\nexport async function computeTotalCountFromPaginationInfo(\n deps: {\n logger: LoggerService;\n },\n paginationInfo: OffsetPagination,\n pageSize?: number,\n): Promise<number | undefined> {\n /*\n paginationInfo: {\n total: , This is the total amount of repos, but will be NaN if the value is above 10k, see: https://github.com/jdalrymple/gitbeaker/issues/839#issuecomment-636482319\n next: ,\n current: ,\n previous: ,\n perPage: ,\n totalPages:\n }\n */\n\n if (isNaN(paginationInfo.total)) {\n deps.logger.debug(\n `Too many result, total count is NaN, returning current page size`,\n );\n return pageSize;\n }\n return paginationInfo.total;\n}\n\nexport async function executeFunctionOnFirstSuccessfulIntegration<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n config: Config;\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n repoUrl: string;\n fn: (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => Promise<{ successful: boolean; result?: T }>;\n },\n) {\n const validatedRepo = await validateAndBuildRepoData(\n deps.gitlabCredentialsProvider,\n integrations,\n deps.config,\n params,\n );\n for (const credential of validatedRepo.credentials) {\n const glKit = buildGitlab(\n deps,\n { credential, owner: validatedRepo.owner },\n validatedRepo.glConfig.baseUrl,\n );\n const res = await params.fn(validatedRepo, glKit);\n if (!res.successful) {\n continue;\n }\n return res.result;\n }\n return undefined;\n}\n\nexport async function fetchFromAllIntegrations<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n dataFetcher: (\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => Promise<{\n stopFetchingData?: boolean;\n result?: T;\n errors?: GitlabFetchError[];\n }>;\n },\n) {\n const glConfigs = verifyAndGetIntegrations(deps, integrations);\n\n const credentialsByConfig = await getCredentialsFromIntegrations(\n deps.gitlabCredentialsProvider,\n glConfigs,\n );\n const errors = new Map<number, GitlabFetchError>();\n const data: T[] = [];\n const dataErrs: GitlabFetchError[] = [];\n let stopFetchingData: boolean | undefined = false;\n for (const [glConfig, credentials] of credentialsByConfig) {\n if (stopFetchingData) {\n break;\n }\n deps.logger.debug(\n `Got ${credentials.length} credential(s) for ${glConfig.host}`,\n );\n for (const credential of credentials) {\n const glKit = buildGitlab(deps, { credential, errors }, glConfig.baseUrl);\n const res = await params.dataFetcher(glKit, credential, glConfig);\n res.errors?.forEach(err => dataErrs.push(err));\n\n if (res.result) {\n data.push(res.result);\n }\n\n stopFetchingData = res.stopFetchingData;\n }\n }\n\n const aggregatedErrors = new Map<number, GitlabFetchError>();\n errors.forEach((err, num) => aggregatedErrors.set(num, err));\n dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));\n\n return { data, errors: aggregatedErrors };\n}\n"],"names":["logErrorIfNeeded","validateAndBuildRepoData","buildGitlab"],"mappings":"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"}
|
|
@@ -1,11 +1,69 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var catalogModel = require('@backstage/catalog-model');
|
|
4
|
+
var errors = require('@backstage/errors');
|
|
5
|
+
var gitUrlParse = require('git-url-parse');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var gitUrlParse__default = /*#__PURE__*/_interopDefaultCompat(gitUrlParse);
|
|
10
|
+
|
|
3
11
|
function getNestedValue(obj, path) {
|
|
4
12
|
return path.split(".").reduce(
|
|
5
13
|
(acc, key) => acc && acc[key] ? acc[key] : undefined,
|
|
6
14
|
obj
|
|
7
15
|
);
|
|
8
16
|
}
|
|
17
|
+
function extractLocationOwnerMap(locationUrls) {
|
|
18
|
+
const locationGitOwnerMap = /* @__PURE__ */ new Map();
|
|
19
|
+
for (const locationUrl of locationUrls) {
|
|
20
|
+
const split = locationUrl.split("/blob/");
|
|
21
|
+
if (split.length < 2) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
locationGitOwnerMap.set(locationUrl, gitUrlParse__default.default(split[0]).owner);
|
|
25
|
+
}
|
|
26
|
+
return locationGitOwnerMap;
|
|
27
|
+
}
|
|
28
|
+
function computeTotalCount(data, countList, pageSize) {
|
|
29
|
+
let totalCount = countList.reduce(
|
|
30
|
+
(accumulator, currentValue) => accumulator + currentValue,
|
|
31
|
+
0
|
|
32
|
+
);
|
|
33
|
+
if (totalCount < pageSize) {
|
|
34
|
+
totalCount = data.length;
|
|
35
|
+
}
|
|
36
|
+
return totalCount;
|
|
37
|
+
}
|
|
38
|
+
function parseGitURLForApprovalTool(repoUrl) {
|
|
39
|
+
const parsedRepoUrl = new URL(repoUrl);
|
|
40
|
+
if (parsedRepoUrl.hostname.includes("gitlab")) {
|
|
41
|
+
return "GITLAB";
|
|
42
|
+
}
|
|
43
|
+
return "GIT";
|
|
44
|
+
}
|
|
45
|
+
function getImportTemplateRef(templateRef) {
|
|
46
|
+
try {
|
|
47
|
+
const { name, namespace, kind } = catalogModel.parseEntityRef(templateRef, {
|
|
48
|
+
defaultKind: "template",
|
|
49
|
+
defaultNamespace: "default"
|
|
50
|
+
});
|
|
51
|
+
if (kind !== "template") {
|
|
52
|
+
throw new errors.InputError(
|
|
53
|
+
`Invalid 'kind' in bulkImport.importTemplate: expected 'template' but got '${kind}'.`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return catalogModel.stringifyEntityRef({ kind, namespace, name });
|
|
57
|
+
} catch (err) {
|
|
58
|
+
throw new errors.InputError(
|
|
59
|
+
`Invalid scaffolder template entity reference in the configuration 'bulkImport.importTemplate': '${templateRef}'. Error: ${err.message}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
9
63
|
|
|
64
|
+
exports.computeTotalCount = computeTotalCount;
|
|
65
|
+
exports.extractLocationOwnerMap = extractLocationOwnerMap;
|
|
66
|
+
exports.getImportTemplateRef = getImportTemplateRef;
|
|
10
67
|
exports.getNestedValue = getNestedValue;
|
|
68
|
+
exports.parseGitURLForApprovalTool = parseGitURLForApprovalTool;
|
|
11
69
|
//# sourceMappingURL=utils.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs.js","sources":["../../src/helpers/utils.ts"],"sourcesContent":["/*\n * Copyright
|
|
1
|
+
{"version":3,"file":"utils.cjs.js","sources":["../../src/helpers/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nexport function getNestedValue<T>(obj: T, path: string): any {\n return path\n .split('.')\n .reduce(\n (acc, key) =>\n acc && (acc as Record<string, any>)[key]\n ? (acc as Record<string, any>)[key]\n : undefined,\n obj,\n );\n}\n\nexport function extractLocationOwnerMap(locationUrls: string[]) {\n const locationGitOwnerMap = new Map<string, string>();\n for (const locationUrl of locationUrls) {\n const split = locationUrl.split('/blob/');\n if (split.length < 2) {\n continue;\n }\n locationGitOwnerMap.set(locationUrl, gitUrlParse(split[0]).owner);\n }\n return locationGitOwnerMap;\n}\n\nexport function computeTotalCount<T>(\n data: T[],\n countList: number[],\n pageSize: number,\n) {\n let totalCount = countList.reduce(\n (accumulator, currentValue) => accumulator + currentValue,\n 0,\n );\n if (totalCount < pageSize) {\n totalCount = data.length;\n }\n return totalCount;\n}\n\nexport function parseGitURLForApprovalTool(repoUrl: string) {\n const parsedRepoUrl = new URL(repoUrl);\n if (parsedRepoUrl.hostname.includes('gitlab')) {\n return 'GITLAB';\n }\n\n return 'GIT';\n}\n\nexport function getImportTemplateRef(templateRef: string): string {\n try {\n const { name, namespace, kind } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n defaultNamespace: 'default',\n });\n\n if (kind !== 'template') {\n throw new InputError(\n `Invalid 'kind' in bulkImport.importTemplate: expected 'template' but got '${kind}'.`,\n );\n }\n\n return stringifyEntityRef({ kind, namespace, name });\n } catch (err) {\n throw new InputError(\n `Invalid scaffolder template entity reference in the configuration 'bulkImport.importTemplate': '${templateRef}'. ` +\n `Error: ${(err as Error).message}`,\n );\n }\n}\n"],"names":["gitUrlParse","parseEntityRef","InputError","stringifyEntityRef"],"mappings":";;;;;;;;;;AAqBgB,SAAA,cAAA,CAAkB,KAAQ,IAAmB,EAAA;AAC3D,EAAO,OAAA,IAAA,CACJ,KAAM,CAAA,GAAG,CACT,CAAA,MAAA;AAAA,IACC,CAAC,KAAK,GACJ,KAAA,GAAA,IAAQ,IAA4B,GAAG,CAAA,GAClC,GAA4B,CAAA,GAAG,CAChC,GAAA,SAAA;AAAA,IACN;AAAA,GACF;AACJ;AAEO,SAAS,wBAAwB,YAAwB,EAAA;AAC9D,EAAM,MAAA,mBAAA,uBAA0B,GAAoB,EAAA;AACpD,EAAA,KAAA,MAAW,eAAe,YAAc,EAAA;AACtC,IAAM,MAAA,KAAA,GAAQ,WAAY,CAAA,KAAA,CAAM,QAAQ,CAAA;AACxC,IAAI,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACpB,MAAA;AAAA;AAEF,IAAA,mBAAA,CAAoB,IAAI,WAAa,EAAAA,4BAAA,CAAY,MAAM,CAAC,CAAC,EAAE,KAAK,CAAA;AAAA;AAElE,EAAO,OAAA,mBAAA;AACT;AAEgB,SAAA,iBAAA,CACd,IACA,EAAA,SAAA,EACA,QACA,EAAA;AACA,EAAA,IAAI,aAAa,SAAU,CAAA,MAAA;AAAA,IACzB,CAAC,WAAa,EAAA,YAAA,KAAiB,WAAc,GAAA,YAAA;AAAA,IAC7C;AAAA,GACF;AACA,EAAA,IAAI,aAAa,QAAU,EAAA;AACzB,IAAA,UAAA,GAAa,IAAK,CAAA,MAAA;AAAA;AAEpB,EAAO,OAAA,UAAA;AACT;AAEO,SAAS,2BAA2B,OAAiB,EAAA;AAC1D,EAAM,MAAA,aAAA,GAAgB,IAAI,GAAA,CAAI,OAAO,CAAA;AACrC,EAAA,IAAI,aAAc,CAAA,QAAA,CAAS,QAAS,CAAA,QAAQ,CAAG,EAAA;AAC7C,IAAO,OAAA,QAAA;AAAA;AAGT,EAAO,OAAA,KAAA;AACT;AAEO,SAAS,qBAAqB,WAA6B,EAAA;AAChE,EAAI,IAAA;AACF,IAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAIC,4BAAe,WAAa,EAAA;AAAA,MAC5D,WAAa,EAAA,UAAA;AAAA,MACb,gBAAkB,EAAA;AAAA,KACnB,CAAA;AAED,IAAA,IAAI,SAAS,UAAY,EAAA;AACvB,MAAA,MAAM,IAAIC,iBAAA;AAAA,QACR,6EAA6E,IAAI,CAAA,EAAA;AAAA,OACnF;AAAA;AAGF,IAAA,OAAOC,+BAAmB,CAAA,EAAE,IAAM,EAAA,SAAA,EAAW,MAAM,CAAA;AAAA,WAC5C,GAAK,EAAA;AACZ,IAAA,MAAM,IAAID,iBAAA;AAAA,MACR,CAAmG,gGAAA,EAAA,WAAW,CACjG,UAAA,EAAA,GAAA,CAAc,OAAO,CAAA;AAAA,KACpC;AAAA;AAEJ;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
-
import { LoggerService, CacheService, DiscoveryService, HttpAuthService, AuthService, AuditorService } from '@backstage/backend-plugin-api';
|
|
2
|
+
import { LoggerService, CacheService, DiscoveryService, HttpAuthService, AuthService, AuditorService, DatabaseService } from '@backstage/backend-plugin-api';
|
|
3
3
|
import { CatalogApi } from '@backstage/catalog-client';
|
|
4
4
|
import { Config } from '@backstage/config';
|
|
5
5
|
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
|
@@ -25,6 +25,7 @@ interface RouterOptions {
|
|
|
25
25
|
auth: AuthService;
|
|
26
26
|
catalogApi: CatalogApi;
|
|
27
27
|
auditor: AuditorService;
|
|
28
|
+
database: DatabaseService;
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
31
|
* Router
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -18,7 +18,8 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
18
18
|
httpAuth: backendPluginApi.coreServices.httpAuth,
|
|
19
19
|
auth: backendPluginApi.coreServices.auth,
|
|
20
20
|
catalogApi: alpha.catalogServiceRef,
|
|
21
|
-
auditor: backendPluginApi.coreServices.auditor
|
|
21
|
+
auditor: backendPluginApi.coreServices.auditor,
|
|
22
|
+
database: backendPluginApi.coreServices.database
|
|
22
23
|
},
|
|
23
24
|
async init({
|
|
24
25
|
config,
|
|
@@ -30,7 +31,8 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
30
31
|
httpAuth,
|
|
31
32
|
auth,
|
|
32
33
|
catalogApi,
|
|
33
|
-
auditor
|
|
34
|
+
auditor,
|
|
35
|
+
database
|
|
34
36
|
}) {
|
|
35
37
|
const router$1 = await router.createRouter({
|
|
36
38
|
config,
|
|
@@ -41,7 +43,8 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
|
|
|
41
43
|
httpAuth,
|
|
42
44
|
auth,
|
|
43
45
|
catalogApi,
|
|
44
|
-
auditor
|
|
46
|
+
auditor,
|
|
47
|
+
database
|
|
45
48
|
});
|
|
46
49
|
http.use(router$1);
|
|
47
50
|
http.addAuthPolicy({
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nimport { createRouter } from './service/router';\n\n/**\n * The bulk-import backend plugin.\n * @public\n */\nexport const bulkImportPlugin = createBackendPlugin({\n pluginId: 'bulk-import',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n http: coreServices.httpRouter,\n cache: coreServices.cache,\n discovery: coreServices.discovery,\n permissions: coreServices.permissions,\n httpAuth: coreServices.httpAuth,\n auth: coreServices.auth,\n catalogApi: catalogServiceRef,\n auditor: coreServices.auditor,\n },\n async init({\n config,\n logger,\n http,\n cache,\n discovery,\n permissions,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n }) {\n const router = await createRouter({\n config,\n cache,\n discovery,\n permissions,\n logger,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n });\n http.use(router);\n http.addAuthPolicy({\n path: '/ping',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","catalogServiceRef","router","createRouter"],"mappings":";;;;;;AA4BO,MAAM,mBAAmBA,oCAAoB,CAAA;AAAA,EAClD,QAAU,EAAA,aAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,MAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,QACrB,MAAMA,6BAAa,CAAA,UAAA;AAAA,QACnB,OAAOA,6BAAa,CAAA,KAAA;AAAA,QACpB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,aAAaA,6BAAa,CAAA,WAAA;AAAA,QAC1B,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,MAAMA,6BAAa,CAAA,IAAA;AAAA,QACnB,UAAY,EAAAC,uBAAA;AAAA,QACZ,SAASD,6BAAa,CAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nimport { createRouter } from './service/router';\n\n/**\n * The bulk-import backend plugin.\n * @public\n */\nexport const bulkImportPlugin = createBackendPlugin({\n pluginId: 'bulk-import',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n http: coreServices.httpRouter,\n cache: coreServices.cache,\n discovery: coreServices.discovery,\n permissions: coreServices.permissions,\n httpAuth: coreServices.httpAuth,\n auth: coreServices.auth,\n catalogApi: catalogServiceRef,\n auditor: coreServices.auditor,\n database: coreServices.database,\n },\n async init({\n config,\n logger,\n http,\n cache,\n discovery,\n permissions,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n database,\n }) {\n const router = await createRouter({\n config,\n cache,\n discovery,\n permissions,\n logger,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n database,\n });\n http.use(router);\n http.addAuthPolicy({\n path: '/ping',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","catalogServiceRef","router","createRouter"],"mappings":";;;;;;AA4BO,MAAM,mBAAmBA,oCAAoB,CAAA;AAAA,EAClD,QAAU,EAAA,aAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,MAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,QACrB,MAAMA,6BAAa,CAAA,UAAA;AAAA,QACnB,OAAOA,6BAAa,CAAA,KAAA;AAAA,QACpB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,aAAaA,6BAAa,CAAA,WAAA;AAAA,QAC1B,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,MAAMA,6BAAa,CAAA,IAAA;AAAA,QACnB,UAAY,EAAAC,uBAAA;AAAA,QACZ,SAASD,6BAAa,CAAA,OAAA;AAAA,QACtB,UAAUA,6BAAa,CAAA;AAAA,OACzB;AAAA,MACA,MAAM,IAAK,CAAA;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACC,EAAA;AACD,QAAM,MAAAE,QAAA,GAAS,MAAMC,mBAAa,CAAA;AAAA,UAChC,MAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA,UAAA;AAAA,UACA,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAA,CAAK,IAAID,QAAM,CAAA;AACf,QAAA,IAAA,CAAK,aAAc,CAAA;AAAA,UACjB,IAAM,EAAA,OAAA;AAAA,UACN,KAAO,EAAA;AAAA,SACR,CAAA;AAAA;AACH,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
|