@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.2.1 → 7.3.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +41 -4
  3. package/dist/database/repositoryDao.cjs.js +6 -0
  4. package/dist/database/repositoryDao.cjs.js.map +1 -1
  5. package/dist/generated/openapidocument.cjs.js +89 -0
  6. package/dist/generated/openapidocument.cjs.js.map +1 -1
  7. package/dist/github/GithubAppManager.cjs.js +3 -0
  8. package/dist/github/GithubAppManager.cjs.js.map +1 -1
  9. package/dist/github/githubApiService.cjs.js +140 -144
  10. package/dist/github/githubApiService.cjs.js.map +1 -1
  11. package/dist/github/types.cjs.js.map +1 -1
  12. package/dist/github/utils/ghUtils.cjs.js +3 -3
  13. package/dist/github/utils/ghUtils.cjs.js.map +1 -1
  14. package/dist/github/utils/repoUtils.cjs.js +53 -99
  15. package/dist/github/utils/repoUtils.cjs.js.map +1 -1
  16. package/dist/gitlab/GitlabAppManager.cjs.js +2 -0
  17. package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -1
  18. package/dist/gitlab/gitlabApiService.cjs.js +65 -8
  19. package/dist/gitlab/gitlabApiService.cjs.js.map +1 -1
  20. package/dist/gitlab/utils/glUtils.cjs.js +1 -1
  21. package/dist/gitlab/utils/glUtils.cjs.js.map +1 -1
  22. package/dist/gitlab/utils/repoUtils.cjs.js +32 -57
  23. package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -1
  24. package/dist/service/handlers/import/bulkImports.cjs.js +14 -6
  25. package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
  26. package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
  27. package/dist/service/handlers/organization/organizations.cjs.js +2 -2
  28. package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
  29. package/dist/service/handlers/repository/repositories.cjs.js +41 -6
  30. package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
  31. package/dist/service/handlers/scm/scm.cjs.js +16 -0
  32. package/dist/service/handlers/scm/scm.cjs.js.map +1 -0
  33. package/dist/service/router.cjs.js +81 -9
  34. package/dist/service/router.cjs.js.map +1 -1
  35. package/package.json +16 -16
@@ -7,7 +7,7 @@ require('@backstage/plugin-permission-common');
7
7
  require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
8
8
  require('just-kebab-case');
9
9
  var loggingUtils = require('../helpers/loggingUtils.cjs.js');
10
- var utils$1 = require('../helpers/utils.cjs.js');
10
+ var utils = require('../helpers/utils.cjs.js');
11
11
  var handlers = require('../service/handlers/handlers.cjs.js');
12
12
  var GithubAppManager = require('./GithubAppManager.cjs.js');
13
13
  var types = require('./types.cjs.js');
@@ -15,7 +15,7 @@ var ghUtils = require('./utils/ghUtils.cjs.js');
15
15
  var orgUtils = require('./utils/orgUtils.cjs.js');
16
16
  var prUtils = require('./utils/prUtils.cjs.js');
17
17
  var repoUtils = require('./utils/repoUtils.cjs.js');
18
- var utils = require('./utils/utils.cjs.js');
18
+ var utils$1 = require('./utils/utils.cjs.js');
19
19
 
20
20
  class GithubApiService {
21
21
  logger;
@@ -31,6 +31,28 @@ class GithubApiService {
31
31
  this.githubCredentialsProvider = GithubAppManager.CustomGithubCredentialsProvider.fromIntegrations(this.integrations);
32
32
  this.cache = cacheService;
33
33
  }
34
+ get integrationDeps() {
35
+ return {
36
+ logger: this.logger,
37
+ cache: this.cache,
38
+ githubCredentialsProvider: this.githubCredentialsProvider
39
+ };
40
+ }
41
+ get executionDeps() {
42
+ return {
43
+ ...this.integrationDeps,
44
+ config: this.config
45
+ };
46
+ }
47
+ buildRepositoryResponse(repositories, result, pageSize) {
48
+ const repoList = Array.from(repositories.values());
49
+ const totalCount = utils.computeTotalCount(repoList, result.data, pageSize);
50
+ return {
51
+ repositories: repoList,
52
+ errors: Array.from(result.errors.values()),
53
+ totalCount
54
+ };
55
+ }
34
56
  async getCredentials(repoUrl) {
35
57
  const provider = integration.DefaultGithubCredentialsProvider.fromIntegrations(
36
58
  this.integrations
@@ -46,12 +68,8 @@ class GithubApiService {
46
68
  };
47
69
  }
48
70
  async getRepositoryFromIntegrations(repoUrl) {
49
- const { data, errors } = await utils.fetchFromMatchedIntegration(
50
- {
51
- logger: this.logger,
52
- cache: this.cache,
53
- githubCredentialsProvider: this.githubCredentialsProvider
54
- },
71
+ const { data, errors } = await utils$1.fetchFromMatchedIntegration(
72
+ this.integrationDeps,
55
73
  this.integrations,
56
74
  repoUrl,
57
75
  async (octokit, gitUrl) => {
@@ -78,14 +96,10 @@ class GithubApiService {
78
96
  errors
79
97
  };
80
98
  }
81
- async getOrganizationsFromIntegrations(search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
99
+ async getOrganizationsFromIntegrations(pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize, search) {
82
100
  const orgs = /* @__PURE__ */ new Map();
83
- const result = await utils.fetchFromAllIntegrations(
84
- {
85
- logger: this.logger,
86
- cache: this.cache,
87
- githubCredentialsProvider: this.githubCredentialsProvider
88
- },
101
+ const result = await utils$1.fetchFromAllIntegrations(
102
+ this.integrationDeps,
89
103
  this.integrations,
90
104
  {
91
105
  dataFetcher: async (octokit, credential, ghConfig) => {
@@ -128,21 +142,63 @@ class GithubApiService {
128
142
  }
129
143
  );
130
144
  const orgList = Array.from(orgs.values());
131
- const totalCount = utils$1.computeTotalCount(orgList, result.data, pageSize);
145
+ const totalCount = utils.computeTotalCount(orgList, result.data, pageSize);
132
146
  return {
133
147
  organizations: orgList,
134
148
  errors: Array.from(result.errors?.values() ?? []),
135
149
  totalCount
136
150
  };
137
151
  }
138
- async getOrgRepositoriesFromIntegrations(orgName, search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
152
+ async fetchUserTokenGithubIntegrationRepositories(userTokens, fetcher) {
153
+ const allErrors = [];
154
+ let totalCount;
155
+ const ghConfigs = this.integrations.github.list().map((i) => i.config);
156
+ for (const ghConfig of ghConfigs) {
157
+ const hostUrl = `https://${ghConfig.host}`;
158
+ const token = userTokens[hostUrl];
159
+ if (!token) {
160
+ continue;
161
+ }
162
+ const userCredential = { token, type: "token" };
163
+ const userOctokit = ghUtils.buildOcto(
164
+ { logger: this.logger, cache: void 0 },
165
+ { credential: userCredential },
166
+ ghConfig.apiBaseUrl
167
+ );
168
+ if (!userOctokit) {
169
+ continue;
170
+ }
171
+ const dataFetchErrors = /* @__PURE__ */ new Map();
172
+ const result = await fetcher(
173
+ userOctokit,
174
+ userCredential,
175
+ dataFetchErrors
176
+ );
177
+ totalCount = (totalCount ?? 0) + (result.totalCount ?? 0);
178
+ dataFetchErrors.forEach((err) => allErrors.push(err));
179
+ }
180
+ return { errors: allErrors, totalCount };
181
+ }
182
+ async getOrgRepositoriesFromIntegrations(orgName, search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize, userTokens) {
139
183
  const repositories = /* @__PURE__ */ new Map();
140
- const result = await utils.fetchFromAllIntegrations(
141
- {
142
- logger: this.logger,
143
- cache: this.cache,
144
- githubCredentialsProvider: this.githubCredentialsProvider
145
- },
184
+ if (userTokens && Object.keys(userTokens).length > 0) {
185
+ const { errors: allErrors, totalCount } = await this.fetchUserTokenGithubIntegrationRepositories(
186
+ userTokens,
187
+ (userOctokit, userCredential, dataFetchErrors) => repoUtils.addGithubTokenOrgRepositories(
188
+ { logger: this.logger },
189
+ userOctokit,
190
+ userCredential,
191
+ orgName,
192
+ repositories,
193
+ dataFetchErrors,
194
+ { search, pageNumber, pageSize }
195
+ )
196
+ );
197
+ const repoList = Array.from(repositories.values());
198
+ return { repositories: repoList, errors: allErrors, totalCount };
199
+ }
200
+ const result = await utils$1.fetchFromAllIntegrations(
201
+ this.integrationDeps,
146
202
  this.integrations,
147
203
  {
148
204
  dataFetcher: async (octokit, credential, ghConfig) => {
@@ -159,13 +215,10 @@ class GithubApiService {
159
215
  },
160
216
  octokit,
161
217
  credential,
162
- ghConfig,
163
218
  repositories,
164
219
  dataFetchErrors,
165
220
  {
166
- search,
167
- pageNumber,
168
- pageSize
221
+ search
169
222
  }
170
223
  );
171
224
  } else {
@@ -179,9 +232,7 @@ class GithubApiService {
179
232
  repositories,
180
233
  dataFetchErrors,
181
234
  {
182
- search,
183
- pageNumber,
184
- pageSize
235
+ search
185
236
  }
186
237
  );
187
238
  }
@@ -196,27 +247,32 @@ class GithubApiService {
196
247
  }
197
248
  }
198
249
  );
199
- const repoList = Array.from(repositories.values());
200
- const totalCount = utils$1.computeTotalCount(repoList, result.data, pageSize);
201
- return {
202
- repositories: repoList,
203
- errors: Array.from(result.errors?.values() ?? []),
204
- totalCount
205
- };
250
+ return this.buildRepositoryResponse(repositories, result, pageSize);
206
251
  }
207
252
  /**
208
253
  * Returns GithubRepositoryResponse containing:
209
254
  * - a list of unique repositories the github integrations have access to
210
255
  * - a list of errors encountered by each app and/or token (if any exist)
211
256
  */
212
- async getRepositoriesFromIntegrations(search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
257
+ async getRepositoriesFromIntegrations(search, userTokens) {
213
258
  const repositories = /* @__PURE__ */ new Map();
214
- const result = await utils.fetchFromAllIntegrations(
215
- {
216
- logger: this.logger,
217
- cache: this.cache,
218
- githubCredentialsProvider: this.githubCredentialsProvider
219
- },
259
+ if (userTokens && Object.keys(userTokens).length > 0) {
260
+ const { errors: allErrors, totalCount } = await this.fetchUserTokenGithubIntegrationRepositories(
261
+ userTokens,
262
+ (userOctokit, userCredential, dataFetchErrors) => repoUtils.addGithubTokenRepositories(
263
+ { logger: this.logger },
264
+ userOctokit,
265
+ userCredential,
266
+ repositories,
267
+ dataFetchErrors,
268
+ { search }
269
+ )
270
+ );
271
+ const repoList = Array.from(repositories.values());
272
+ return { repositories: repoList, errors: allErrors, totalCount };
273
+ }
274
+ const result = await utils$1.fetchFromAllIntegrations(
275
+ this.integrationDeps,
220
276
  this.integrations,
221
277
  {
222
278
  dataFetcher: async (octokit, credential, ghConfig) => {
@@ -228,13 +284,10 @@ class GithubApiService {
228
284
  },
229
285
  octokit,
230
286
  credential,
231
- ghConfig,
232
287
  repositories,
233
288
  dataFetchErrors,
234
289
  {
235
- search,
236
- pageNumber,
237
- pageSize
290
+ search
238
291
  }
239
292
  ) : await repoUtils.addGithubTokenRepositories(
240
293
  {
@@ -245,9 +298,7 @@ class GithubApiService {
245
298
  repositories,
246
299
  dataFetchErrors,
247
300
  {
248
- search,
249
- pageNumber,
250
- pageSize
301
+ search
251
302
  }
252
303
  );
253
304
  this.logger.debug(
@@ -260,48 +311,34 @@ class GithubApiService {
260
311
  }
261
312
  }
262
313
  );
263
- const repoList = Array.from(repositories.values());
264
- const totalCount = utils$1.computeTotalCount(repoList, result.data, pageSize);
265
- return {
266
- repositories: repoList,
267
- errors: Array.from(result.errors?.values() ?? []),
268
- totalCount
269
- };
314
+ return this.buildRepositoryResponse(repositories, result, handlers.DefaultPageSize);
270
315
  }
271
316
  async filterLocationsAccessibleFromIntegrations(locationUrls) {
272
- const locationGitOwnerMap = utils$1.extractLocationOwnerMap(locationUrls);
317
+ const locationGitOwnerMap = utils.extractLocationOwnerMap(locationUrls);
273
318
  const allAccessibleAppOrgs = /* @__PURE__ */ new Set();
274
319
  const allAccessibleTokenOrgs = /* @__PURE__ */ new Set();
275
320
  const allAccessibleUsernames = /* @__PURE__ */ new Set();
276
- await utils.fetchFromAllIntegrations(
277
- {
278
- logger: this.logger,
279
- cache: this.cache,
280
- githubCredentialsProvider: this.githubCredentialsProvider
281
- },
282
- this.integrations,
283
- {
284
- dataFetcher: async (octokit, credential, ghConfig) => {
285
- if (types.isGithubAppCredential(credential)) {
286
- const appOrgMap = await orgUtils.getAllAppOrgs(
287
- this.githubCredentialsProvider,
288
- ghConfig,
289
- credential.accountLogin
290
- );
291
- for (const [_, ghOrg] of appOrgMap) {
292
- allAccessibleAppOrgs.add(ghOrg.name);
293
- }
294
- } else {
295
- const username = (await octokit.rest.users.getAuthenticated())?.data?.login;
296
- if (username) {
297
- allAccessibleUsernames.add(username);
298
- }
299
- (await octokit.paginate(octokit.rest.orgs.listForAuthenticatedUser))?.map((org) => org.login)?.forEach((orgName) => allAccessibleTokenOrgs.add(orgName));
321
+ await utils$1.fetchFromAllIntegrations(this.integrationDeps, this.integrations, {
322
+ dataFetcher: async (octokit, credential, ghConfig) => {
323
+ if (types.isGithubAppCredential(credential)) {
324
+ const appOrgMap = await orgUtils.getAllAppOrgs(
325
+ this.githubCredentialsProvider,
326
+ ghConfig,
327
+ credential.accountLogin
328
+ );
329
+ for (const [_, ghOrg] of appOrgMap) {
330
+ allAccessibleAppOrgs.add(ghOrg.name);
300
331
  }
301
- return {};
332
+ } else {
333
+ const username = (await octokit.rest.users.getAuthenticated())?.data?.login;
334
+ if (username) {
335
+ allAccessibleUsernames.add(username);
336
+ }
337
+ (await octokit.paginate(octokit.rest.orgs.listForAuthenticatedUser))?.map((org) => org.login)?.forEach((orgName) => allAccessibleTokenOrgs.add(orgName));
302
338
  }
339
+ return {};
303
340
  }
304
- );
341
+ });
305
342
  return locationUrls.filter((loc) => {
306
343
  if (!locationGitOwnerMap.has(loc)) {
307
344
  return false;
@@ -311,12 +348,8 @@ class GithubApiService {
311
348
  });
312
349
  }
313
350
  async getPullRequest(repoUrl, pullRequestNumber) {
314
- const { data } = await utils.fetchFromMatchedIntegration(
315
- {
316
- logger: this.logger,
317
- cache: this.cache,
318
- githubCredentialsProvider: this.githubCredentialsProvider
319
- },
351
+ const { data } = await utils$1.fetchFromMatchedIntegration(
352
+ this.integrationDeps,
320
353
  this.integrations,
321
354
  repoUrl,
322
355
  async (octokit, gitUrl) => {
@@ -344,12 +377,8 @@ class GithubApiService {
344
377
  return data ?? {};
345
378
  }
346
379
  async updatePullRequest(repoUrl, pullRequestNumber, title, body) {
347
- await utils.fetchFromMatchedIntegration(
348
- {
349
- logger: this.logger,
350
- cache: this.cache,
351
- githubCredentialsProvider: this.githubCredentialsProvider
352
- },
380
+ await utils$1.fetchFromMatchedIntegration(
381
+ this.integrationDeps,
353
382
  this.integrations,
354
383
  repoUrl,
355
384
  async (octokit, gitUrl) => {
@@ -443,12 +472,8 @@ class GithubApiService {
443
472
  }
444
473
  async findImportOpenPr(logger, input) {
445
474
  const branchName = catalogUtils.getBranchName(this.config);
446
- const { data } = await utils.fetchFromMatchedIntegration(
447
- {
448
- logger: this.logger,
449
- cache: this.cache,
450
- githubCredentialsProvider: this.githubCredentialsProvider
451
- },
475
+ const { data } = await utils$1.fetchFromMatchedIntegration(
476
+ this.integrationDeps,
452
477
  this.integrations,
453
478
  input.repoUrl,
454
479
  async (octokit, gitUrl) => {
@@ -471,12 +496,8 @@ class GithubApiService {
471
496
  return data ?? {};
472
497
  }
473
498
  async getCatalogInfoFile(logger, input) {
474
- const { data } = await utils.fetchFromMatchedIntegration(
475
- {
476
- logger: this.logger,
477
- cache: this.cache,
478
- githubCredentialsProvider: this.githubCredentialsProvider
479
- },
499
+ const { data } = await utils$1.fetchFromMatchedIntegration(
500
+ this.integrationDeps,
480
501
  this.integrations,
481
502
  input.repoUrl,
482
503
  async (octokit, gitUrl) => {
@@ -505,13 +526,8 @@ class GithubApiService {
505
526
  async submitPrToRepo(logger, input) {
506
527
  const fileName = catalogUtils.getCatalogFilename(this.config);
507
528
  const errors = [];
508
- const result = await utils.executeFunctionOnFirstSuccessfulIntegration(
509
- {
510
- logger: this.logger,
511
- cache: this.cache,
512
- config: this.config,
513
- githubCredentialsProvider: this.githubCredentialsProvider
514
- },
529
+ const result = await utils$1.executeFunctionOnFirstSuccessfulIntegration(
530
+ this.executionDeps,
515
531
  this.integrations,
516
532
  {
517
533
  repoUrl: input.repoUrl,
@@ -660,13 +676,8 @@ class GithubApiService {
660
676
  };
661
677
  }
662
678
  async hasFileInRepo(input) {
663
- const fileExists = await utils.executeFunctionOnFirstSuccessfulIntegration(
664
- {
665
- logger: this.logger,
666
- cache: this.cache,
667
- config: this.config,
668
- githubCredentialsProvider: this.githubCredentialsProvider
669
- },
679
+ const fileExists = await utils$1.executeFunctionOnFirstSuccessfulIntegration(
680
+ this.executionDeps,
670
681
  this.integrations,
671
682
  {
672
683
  repoUrl: input.repoUrl,
@@ -695,13 +706,8 @@ class GithubApiService {
695
706
  return fileExists;
696
707
  }
697
708
  async closeImportPR(logger, input) {
698
- await utils.executeFunctionOnFirstSuccessfulIntegration(
699
- {
700
- logger: this.logger,
701
- cache: this.cache,
702
- config: this.config,
703
- githubCredentialsProvider: this.githubCredentialsProvider
704
- },
709
+ await utils$1.executeFunctionOnFirstSuccessfulIntegration(
710
+ this.executionDeps,
705
711
  this.integrations,
706
712
  {
707
713
  repoUrl: input.repoUrl,
@@ -739,13 +745,8 @@ class GithubApiService {
739
745
  );
740
746
  }
741
747
  async deleteImportBranch(input) {
742
- await utils.executeFunctionOnFirstSuccessfulIntegration(
743
- {
744
- logger: this.logger,
745
- cache: this.cache,
746
- config: this.config,
747
- githubCredentialsProvider: this.githubCredentialsProvider
748
- },
748
+ await utils$1.executeFunctionOnFirstSuccessfulIntegration(
749
+ this.executionDeps,
749
750
  this.integrations,
750
751
  {
751
752
  repoUrl: input.repoUrl,
@@ -771,13 +772,8 @@ class GithubApiService {
771
772
  );
772
773
  }
773
774
  async isRepoEmpty(input) {
774
- return await utils.executeFunctionOnFirstSuccessfulIntegration(
775
- {
776
- logger: this.logger,
777
- cache: this.cache,
778
- config: this.config,
779
- githubCredentialsProvider: this.githubCredentialsProvider
780
- },
775
+ return await utils$1.executeFunctionOnFirstSuccessfulIntegration(
776
+ this.executionDeps,
781
777
  this.integrations,
782
778
  {
783
779
  repoUrl: input.repoUrl,