adds @backstage/plugin-todo-backend to dependencies for plugin/todo-backend

Signed-off-by: Oleg S <97077423+RobotSail@users.noreply.github.com>
This commit is contained in:
Oleg S
2023-02-17 10:07:21 -05:00
parent fd28151c95
commit 4120513412
12 changed files with 78 additions and 193 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-todo-backend': patch
---
todo-backend is now exposed as a plugin which uses the new plugin system
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-todo-backend': minor
'example-backend-next': patch
---
Expose the todos-backend plugin using the new system, add the new entrypoint for todos-backend into the experimental backend
+2 -2
View File
@@ -18,12 +18,12 @@ import { catalogPlugin } from '@backstage/plugin-catalog-backend';
import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend';
import { createBackend } from '@backstage/backend-defaults';
import { appPlugin } from '@backstage/plugin-app-backend';
import { todosPlugin } from '@backstage/plugin-todo-backend';
import { todoPlugin } from '@backstage/plugin-todo-backend';
const backend = createBackend();
backend.add(catalogPlugin());
backend.add(catalogModuleTemplateKind());
backend.add(appPlugin({ appPackageName: 'example-app' }));
backend.add(todosPlugin());
backend.add(todoPlugin());
backend.start();
+7 -10
View File
@@ -8,9 +8,9 @@ import { CatalogApi } from '@backstage/catalog-client';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import express from 'express';
import type { HttpRouterService } from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
import { ScmIntegrations } from '@backstage/integration';
import { ServiceRef } from '@backstage/backend-plugin-api';
import { UrlReader } from '@backstage/backend-common';
// @public (undocumented)
@@ -90,6 +90,9 @@ export type TodoParserResult = {
lineNumber: number;
};
// @alpha
export const todoPlugin: () => BackendFeature;
// @public (undocumented)
export interface TodoReader {
readTodos(options: ReadTodosOptions): Promise<ReadTodosResult>;
@@ -136,6 +139,9 @@ export type TodoScmReaderOptions = {
filePathFilter?: (filePath: string) => boolean;
};
// @alpha (undocumented)
export const todoScmReaderRef: ServiceRef<TodoScmReader, 'plugin'>;
// @public (undocumented)
export interface TodoService {
// (undocumented)
@@ -146,13 +152,4 @@ export interface TodoService {
},
): Promise<ListTodosResponse>;
}
// @alpha (undocumented)
export const todosPlugin: () => BackendFeature;
// @alpha (undocumented)
export type TodosPluginDependencies = {
todoReader: TodoService;
http: HttpRouterService;
};
```
+1
View File
@@ -30,6 +30,7 @@
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/catalog-client": "workspace:^",
"@backstage/catalog-model": "workspace:^",
"@backstage/config": "workspace:^",
+1
View File
@@ -22,3 +22,4 @@
export * from './lib';
export * from './service';
export * from './plugin';
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { UrlReader } from '@backstage/backend-common';
import { loggerToWinstonLogger, UrlReader } from '@backstage/backend-common';
import { ScmIntegrations } from '@backstage/integration';
import { Logger } from 'winston';
@@ -28,6 +28,11 @@ import {
import { Config } from '@backstage/config';
import { createTodoParser } from './createTodoParser';
import path from 'path';
import {
coreServices,
createServiceFactory,
createServiceRef,
} from '@backstage/backend-plugin-api';
const excludedExtensions = [
'.png',
@@ -167,3 +172,26 @@ export class TodoScmReader implements TodoReader {
return { result: { items: todos }, etag: tree.etag };
}
}
/**
* @alpha
*/
export const todoScmReaderRef = createServiceRef<TodoScmReader>({
id: 'todoScmReaderFactory',
defaultFactory: async service =>
createServiceFactory({
service,
deps: {
reader: coreServices.urlReader,
config: coreServices.config,
logger: coreServices.logger,
},
factory: async ({ reader, config, logger }) => {
const winstonLogger = loggerToWinstonLogger(logger);
return TodoScmReader.fromConfig(config, {
logger: winstonLogger,
reader,
});
},
}),
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
export { TodoScmReader } from './TodoScmReader';
export { TodoScmReader, todoScmReaderRef } from './TodoScmReader';
export type { TodoScmReaderOptions } from './TodoScmReader';
export { createTodoParser } from './createTodoParser';
export type { TodoParserOptions } from './createTodoParser';
+8 -48
View File
@@ -18,23 +18,15 @@ import {
createBackendPlugin,
coreServices,
} from '@backstage/backend-plugin-api';
import { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';
import { InputError } from '@backstage/errors';
import express, { Router } from 'express';
import {
getBearerToken,
parseFilterParam,
parseIntegerParam,
parseOrderByParam,
} from './lib/utils';
import { todoReaderServiceRef } from './service/TodoReaderService';
import { TODO_FIELDS } from './service/types';
import { createRouter } from './service/router';
/**
* The Todos plugin is responsible for aggregating todo comments within source.
* @alpha
*/
export const todosPlugin = createBackendPlugin({
export const todoPlugin = createBackendPlugin({
pluginId: 'todo-backend',
register(env) {
env.registerInit({
@@ -43,43 +35,11 @@ export const todosPlugin = createBackendPlugin({
http: coreServices.httpRouter,
},
async init({ http, todoReader }) {
const router = Router();
router.use(express.json());
router.get('/v1/todos', async (req, res) => {
const offset = parseIntegerParam(req.query.offset, 'offset query');
const limit = parseIntegerParam(req.query.limit, 'limit query');
const orderBy = parseOrderByParam(req.query.orderBy, TODO_FIELDS);
const filters = parseFilterParam(req.query.filter, TODO_FIELDS);
const entityRef = req.query.entity;
if (entityRef && typeof entityRef !== 'string') {
throw new InputError(`entity query must be a string`);
}
let entity: CompoundEntityRef | undefined = undefined;
if (entityRef) {
try {
entity = parseEntityRef(entityRef);
} catch (error) {
throw new InputError(`Invalid entity ref, ${error}`);
}
}
const todos = await todoReader.listTodos(
{
entity,
offset,
limit,
orderBy,
filters,
},
{
token: getBearerToken(req.headers.authorization),
},
);
res.json(todos);
});
http.use(router);
http.use(
await createRouter({
todoService: todoReader,
}),
);
},
});
},
@@ -20,15 +20,15 @@ import {
getEntitySourceLocation,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { TodoReader, TodoScmReader } from '../lib';
import { ListTodosRequest, ListTodosResponse, TodoService } from './types';
import {
coreServices,
createServiceFactory,
createServiceRef,
ServiceRef,
} from '@backstage/backend-plugin-api';
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { TodoReader, todoScmReaderRef } from '../lib';
import { ListTodosRequest, ListTodosResponse, TodoService } from './types';
const DEFAULT_DEFAULT_PAGE_SIZE = 10;
const DEFAULT_MAX_PAGE_SIZE = 50;
@@ -138,28 +138,22 @@ export class TodoReaderService implements TodoService {
}
}
export const todoReaderServiceRef = createServiceRef<TodoService>({
id: 'todo-client',
defaultFactory: async service =>
createServiceFactory({
service,
deps: {
catalogApi: catalogServiceRef,
logger: coreServices.logger,
reader: coreServices.urlReader,
config: coreServices.config,
},
async factory({ catalogApi, logger, reader, config }) {
const winstonLogger = loggerToWinstonLogger(logger);
const todoReader = TodoScmReader.fromConfig(config, {
reader: reader,
logger: winstonLogger,
});
return new TodoReaderService({
catalogClient: catalogApi,
todoReader,
// TODO: override defaults here
});
},
}),
});
export const todoReaderServiceRef: ServiceRef<TodoService> =
createServiceRef<TodoService>({
id: 'todo.client',
defaultFactory: async service =>
createServiceFactory({
service,
deps: {
catalogApi: catalogServiceRef,
todoReader: todoScmReaderRef,
},
async factory({ catalogApi, todoReader }) {
const todoReaderService = new TodoReaderService({
catalogClient: catalogApi,
todoReader,
});
return todoReaderService;
},
}),
});
+1 -7
View File
@@ -16,12 +16,6 @@
export { createRouter } from './router';
export type { RouterOptions } from './router';
export type {
TodoService,
ListTodosRequest,
ListTodosResponse,
TodosPluginDependencies,
} from './types';
export type { TodoService, ListTodosRequest, ListTodosResponse } from './types';
export { TodoReaderService } from './TodoReaderService';
export type { TodoReaderServiceOptions } from './TodoReaderService';
export { todosPlugin } from './plugin';
@@ -1,89 +0,0 @@
/*
* Copyright 2023 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 {
createBackendPlugin,
coreServices,
} from '@backstage/backend-plugin-api';
import { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';
import { InputError } from '@backstage/errors';
import express, { Router } from 'express';
import {
getBearerToken,
parseFilterParam,
parseIntegerParam,
parseOrderByParam,
} from '../lib/utils';
import { todoReaderServiceRef } from './TodoReaderService';
import { TODO_FIELDS } from './types';
import type { TodosPluginDependencies } from './types';
const todosPluginInit = async (params: TodosPluginDependencies) => {
const { http, todoReader } = params;
const router = Router();
router.use(express.json());
router.get('/v1/todos', async (req, res) => {
const offset = parseIntegerParam(req.query.offset, 'offset query');
const limit = parseIntegerParam(req.query.limit, 'limit query');
const orderBy = parseOrderByParam(req.query.orderBy, TODO_FIELDS);
const filters = parseFilterParam(req.query.filter, TODO_FIELDS);
const entityRef = req.query.entity;
if (entityRef && typeof entityRef !== 'string') {
throw new InputError(`entity query must be a string`);
}
let entity: CompoundEntityRef | undefined = undefined;
if (entityRef) {
try {
entity = parseEntityRef(entityRef);
} catch (error) {
throw new InputError(`Invalid entity ref, ${error}`);
}
}
const todos = await todoReader.listTodos(
{
entity,
offset,
limit,
orderBy,
filters,
},
{
token: getBearerToken(req.headers.authorization),
},
);
res.json(todos);
});
http.use(router);
};
/**
* @alpha
*/
export const todosPlugin = createBackendPlugin({
pluginId: 'todo-backend',
register(env) {
env.registerInit({
deps: {
todoReader: todoReaderServiceRef,
http: coreServices.httpRouter,
},
init: todosPluginInit,
});
},
});