chore: reworking where the types are stored and where the client is created

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2022-02-23 15:25:52 +01:00
parent 8f1cc99d3b
commit 6bf5faa3f2
4 changed files with 117 additions and 95 deletions
+30 -87
View File
@@ -14,11 +14,7 @@
* limitations under the License.
*/
import {
EntityName,
EntityRef,
parseEntityRef,
} from '@backstage/catalog-model';
import { parseEntityRef } from '@backstage/catalog-model';
import {
createApiRef,
DiscoveryApi,
@@ -26,11 +22,20 @@ import {
} from '@backstage/core-plugin-api';
import { ResponseError } from '@backstage/errors';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { JsonObject, JsonValue, Observable } from '@backstage/types';
import { Field, FieldValidation } from '@rjsf/core';
import { Observable } from '@backstage/types';
import qs from 'qs';
import ObservableImpl from 'zen-observable';
import { ListActionsResponse, ScaffolderTask, Status } from './types';
import {
ListActionsResponse,
LogEvent,
ScaffolderApi,
TemplateParameterSchema,
ScaffolderScaffoldOptions,
ScaffolderScaffoldResponse,
ScaffolderStreamLogsOptions,
ScaffolderGetIntegrationsListOptions,
ScaffolderGetIntegrationsListResponse,
} from './types';
/**
* Utility API reference for the {@link ScaffolderApi}.
@@ -41,70 +46,6 @@ export const scaffolderApiRef = createApiRef<ScaffolderApi>({
id: 'plugin.scaffolder.service',
});
type TemplateParameterSchema = {
title: string;
steps: Array<{
title: string;
schema: JsonObject;
}>;
};
export type LogEvent = {
type: 'log' | 'completion';
body: {
message: string;
stepId?: string;
status?: Status;
};
createdAt: string;
id: string;
taskId: string;
};
export type CustomField = {
name: string;
component: Field;
validation: (data: JsonValue, field: FieldValidation) => void;
};
/**
* An API to interact with the scaffolder backend.
*
* @public
*/
export interface ScaffolderApi {
getTemplateParameterSchema(
templateRef: EntityRef,
): Promise<TemplateParameterSchema>;
/**
* Executes the scaffolding of a component, given a template and its
* parameter values.
*
* @param templateName - Name of the Template entity for the scaffolder to use. New project is going to be created out of this template.
* @param values - Parameters for the template, e.g. name, description
* @param secrets - Optional secrets to pass to as the secrets parameter to the template.
*/
scaffold(
templateName: string,
values: Record<string, any>,
secrets?: Record<string, string>,
): Promise<string>;
getTask(taskId: string): Promise<ScaffolderTask>;
getIntegrationsList(options: {
allowedHosts: string[];
}): Promise<{ type: string; title: string; host: string }[]>;
/**
* Returns a list of all installed actions.
*/
listActions(): Promise<ListActionsResponse>;
streamLogs(options: { taskId: string; after?: number }): Observable<LogEvent>;
}
/**
* An API to interact with the scaffolder backend.
*
@@ -128,8 +69,10 @@ export class ScaffolderClient implements ScaffolderApi {
this.useLongPollingLogs = options.useLongPollingLogs ?? false;
}
async getIntegrationsList(options: { allowedHosts: string[] }) {
return [
async getIntegrationsList(
options: ScaffolderGetIntegrationsListOptions,
): Promise<ScaffolderGetIntegrationsListResponse> {
const integrations = [
...this.scmIntegrationsApi.azure.list(),
...this.scmIntegrationsApi.bitbucket.list(),
...this.scmIntegrationsApi.github.list(),
@@ -137,10 +80,14 @@ export class ScaffolderClient implements ScaffolderApi {
]
.map(c => ({ type: c.type, title: c.title, host: c.config.host }))
.filter(c => options.allowedHosts.includes(c.host));
return {
integrations,
};
}
async getTemplateParameterSchema(
templateRef: EntityRef,
templateRef: string,
): Promise<TemplateParameterSchema> {
const { namespace, kind, name } = parseEntityRef(templateRef);
@@ -164,15 +111,14 @@ export class ScaffolderClient implements ScaffolderApi {
* Executes the scaffolding of a component, given a template and its
* parameter values.
*
* @param templateName - Template name for the scaffolder to use. New project is going to be created out of this template.
* @param values - Parameters for the template, e.g. name, description
* @param secrets - Optional secrets to pass to as the secrets parameter to the template.
* @param options.templateName - Template name for the scaffolder to use. New project is going to be created out of this template.
* @param options.values - Parameters for the template, e.g. name, description
* @param options.secrets - Optional secrets to pass to as the secrets parameter to the template.
*/
async scaffold(
templateName: string,
values: Record<string, any>,
secrets: Record<string, string> = {},
): Promise<string> {
options: ScaffolderScaffoldOptions,
): Promise<ScaffolderScaffoldResponse> {
const { templateName, values, secrets = {} } = options;
const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v2/tasks`;
const response = await this.fetchApi.fetch(url, {
method: 'POST',
@@ -193,7 +139,7 @@ export class ScaffolderClient implements ScaffolderApi {
}
const { id } = (await response.json()) as { id: string };
return id;
return { jobId: id };
}
async getTask(taskId: string) {
@@ -208,10 +154,7 @@ export class ScaffolderClient implements ScaffolderApi {
return await response.json();
}
streamLogs(options: {
taskId: string;
after?: number;
}): Observable<LogEvent> {
streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent> {
if (this.useLongPollingLogs) {
return this.streamLogsPolling(options);
}
+1 -1
View File
@@ -21,7 +21,7 @@
*/
export { scaffolderApiRef, ScaffolderClient } from './api';
export type { ScaffolderApi } from './api';
export * from './types';
export {
createScaffolderFieldExtension,
ScaffolderFieldExtensions,
+5 -4
View File
@@ -64,11 +64,12 @@ export const scaffolderPlugin = createPlugin({
},
});
export const EntityPickerExtension = createScaffolderFieldExtension({
component: EntityPicker,
name: 'EntityPicker',
});
export const EntityPickerFieldExtension = scaffolderPlugin.provide(
createScaffolderFieldExtension({
component: EntityPicker,
name: 'EntityPicker',
}),
EntityPickerExtension,
);
export const EntityNamePickerFieldExtension = scaffolderPlugin.provide(
+81 -3
View File
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { JSONSchema } from '@backstage/catalog-model';
import { TaskSpec } from '@backstage/plugin-scaffolder-common';
import { JsonObject, Observable } from '@backstage/types';
import { JSONSchema7 } from 'json-schema';
export type Status = 'open' | 'processing' | 'failed' | 'completed' | 'skipped';
export type JobStatus = 'PENDING' | 'STARTED' | 'COMPLETED' | 'FAILED';
@@ -51,8 +52,8 @@ export type ListActionsResponse = Array<{
id: string;
description?: string;
schema?: {
input?: JSONSchema;
output?: JSONSchema;
input?: JSONSchema7;
output?: JSONSchema7;
};
}>;
@@ -72,3 +73,80 @@ export type TaskOutput = {
} & {
[key: string]: unknown;
};
export type TemplateParameterSchema = {
title: string;
steps: Array<{
title: string;
schema: JsonObject;
}>;
};
export type LogEvent = {
type: 'log' | 'completion';
body: {
message: string;
stepId?: string;
status?: Status;
};
createdAt: string;
id: string;
taskId: string;
};
export interface ScaffolderScaffoldOptions {
templateName: string;
values: Record<string, any>;
secrets?: Record<string, string>;
}
export interface ScaffolderScaffoldResponse {
jobId: string;
}
export interface ScaffolderGetIntegrationsListOptions {
allowedHosts: string[];
}
export interface ScaffolderGetIntegrationsListResponse {
integrations: { type: string; title: string; host: string }[];
}
export interface ScaffolderStreamLogsOptions {
taskId: string;
after?: number;
}
/**
* An API to interact with the scaffolder backend.
*
* @public
*/
export interface ScaffolderApi {
getTemplateParameterSchema(
templateRef: string,
): Promise<TemplateParameterSchema>;
/**
* Executes the scaffolding of a component, given a template and its
* parameter values.
*
* @param options.templateName - Name of the Template entity for the scaffolder to use. New project is going to be created out of this template.
* @param options.values - Parameters for the template, e.g. name, description
* @param options.secrets - Optional secrets to pass to as the secrets parameter to the template.
*/
scaffold(
options: ScaffolderScaffoldOptions,
): Promise<ScaffolderScaffoldResponse>;
getTask(taskId: string): Promise<ScaffolderTask>;
getIntegrationsList(
options: ScaffolderGetIntegrationsListOptions,
): Promise<ScaffolderGetIntegrationsListResponse>;
/**
* Returns a list of all installed actions.
*/
listActions(): Promise<ListActionsResponse>;
streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent>;
}