feat: add endpoint for bitbucket autocomplete in scaffolder

Signed-off-by: Benjamin Janssens <benji.janssens@gmail.com>
This commit is contained in:
Benjamin Janssens
2024-06-13 11:51:57 +02:00
parent d79cd670cc
commit 21ddf60522
4 changed files with 105 additions and 0 deletions
+1
View File
@@ -70,6 +70,7 @@
"@backstage/errors": "workspace:^",
"@backstage/integration": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-bitbucket-cloud-common": "workspace:^",
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/plugin-permission-common": "workspace:^",
@@ -0,0 +1,79 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InputError } from '@backstage/errors';
import { BitbucketCloudClient } from '@backstage/plugin-bitbucket-cloud-common';
export async function handleBitbucketCloudRequest(
token: string,
resource: string,
parameters: Record<string, string>,
): Promise<string[]> {
const client = BitbucketCloudClient.fromConfig({
host: 'bitbucket.org',
apiBaseUrl: 'https://api.bitbucket.org/2.0',
accessToken: token,
});
switch (resource) {
case 'workspaces': {
const result: string[] = [];
for await (const page of client.listWorkspaces().iteratePages()) {
const slugs = [...page.values!].map(p => p.slug!);
result.push(...slugs);
}
return result;
}
case 'projects': {
if (!parameters.workspace)
throw new InputError('Missing workspace query parameter');
const result: string[] = [];
for await (const page of client
.listProjectsByWorkspace(parameters.workspace)
.iteratePages()) {
const keys = [...page.values!].map(p => p.key!);
result.push(...keys);
}
return result;
}
case 'repositories': {
if (!parameters.workspace || !parameters.project)
throw new InputError(
'Missing workspace and/or project query parameter',
);
const result: string[] = [];
for await (const page of client
.listRepositoriesByWorkspace(parameters.workspace, {
q: `project.key="${parameters.project}"`,
})
.iteratePages()) {
const slugs = [...page.values!].map(p => p.slug!);
result.push(...slugs);
}
return result;
}
default:
throw new InputError(`Invalid resource: ${resource}`);
}
}
@@ -94,6 +94,7 @@ import {
} from '@backstage/plugin-auth-node';
import { InternalTaskSecrets } from '../scaffolder/tasks/types';
import { checkPermission } from '../util/checkPermissions';
import { handleBitbucketCloudRequest } from './autocomplete';
/**
*
@@ -771,6 +772,29 @@ export async function createRouter(
base64Content: file.content.toString('base64'),
})),
});
})
.get('/v2/autocomplete/:provider/:resource', async (req, res) => {
const { token, ...query } = req.query;
const { provider, resource } = req.params;
if (!token) throw new InputError('Missing token query parameter');
let result: string[];
switch (provider) {
case 'bitbucketCloud': {
result = await handleBitbucketCloudRequest(
token as string,
resource,
query as Record<string, string>,
);
break;
}
default:
throw new InputError(`Unsupported provider: ${provider}`);
}
res.status(200).json(result);
});
const app = express();
+1
View File
@@ -7093,6 +7093,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/plugin-bitbucket-cloud-common": "workspace:^"
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/plugin-permission-common": "workspace:^"