todo-backend: create layered shell with types and mock
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/catalog-client": "^0.3.6",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@types/express": "^4.17.6",
|
||||
"express": "^4.17.1",
|
||||
|
||||
@@ -14,4 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './service/router';
|
||||
export * from './lib';
|
||||
export * from './service';
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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 { UrlReader } from '@backstage/backend-common';
|
||||
import { Logger } from 'winston';
|
||||
import { ReadTodosOptions, ReadTodosResult, TodoReader } from './types';
|
||||
|
||||
type Options = {
|
||||
logger: Logger;
|
||||
reader: UrlReader;
|
||||
};
|
||||
|
||||
export class TodoScmReader implements TodoReader {
|
||||
private readonly logger: Logger;
|
||||
private readonly reader: UrlReader;
|
||||
|
||||
constructor(options: Options) {
|
||||
this.logger = options.logger;
|
||||
this.reader = options.reader;
|
||||
}
|
||||
|
||||
async readTodos(_options: ReadTodosOptions): Promise<ReadTodosResult> {
|
||||
return {
|
||||
items: [{ text: 'My mock todo' }],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { TodoScmReader } from './TodoScmReader';
|
||||
export type {
|
||||
TodoItem,
|
||||
TodoReader,
|
||||
ReadTodosOptions,
|
||||
ReadTodosResult,
|
||||
} from './types';
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export type TodoItem = {
|
||||
text: string;
|
||||
author?: string;
|
||||
viewUrl?: string;
|
||||
editUrl?: string;
|
||||
};
|
||||
|
||||
export type ReadTodosOptions = {
|
||||
/**
|
||||
* Base URLs defining the root at which to search for TODOs
|
||||
*/
|
||||
url: string;
|
||||
};
|
||||
|
||||
export type ReadTodosResult = {
|
||||
/**
|
||||
* TODO items found at the given locations
|
||||
*/
|
||||
items: TodoItem[];
|
||||
};
|
||||
|
||||
export interface TodoReader {
|
||||
/**
|
||||
* Searches for TODO items in code at a given location
|
||||
*/
|
||||
readTodos(options: ReadTodosOptions): Promise<ReadTodosResult>;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './TodoReader';
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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 { CatalogClient } from '@backstage/catalog-client';
|
||||
import { Logger } from 'winston';
|
||||
import { TodoReader } from '../lib';
|
||||
import { ListTodosRequest, ListTodosResponse, TodoService } from './types';
|
||||
|
||||
type Options = {
|
||||
logger: Logger;
|
||||
todoReader: TodoReader;
|
||||
catalogClient: CatalogClient;
|
||||
};
|
||||
|
||||
export class TodoReaderService implements TodoService {
|
||||
private readonly logger: Logger;
|
||||
private readonly todoReader: TodoReader;
|
||||
private readonly catalogClient: CatalogClient;
|
||||
|
||||
constructor(options: Options) {
|
||||
this.logger = options.logger;
|
||||
this.todoReader = options.todoReader;
|
||||
this.catalogClient = options.catalogClient;
|
||||
}
|
||||
|
||||
async listTodos(_req: ListTodosRequest): Promise<ListTodosResponse> {
|
||||
const todos = await this.todoReader.readTodos({
|
||||
url: 'https://github.com/backstage/backstage',
|
||||
});
|
||||
return {
|
||||
items: todos.items.slice(0, 10),
|
||||
totalCount: todos.items.length,
|
||||
cursors: {
|
||||
prev: 'prev',
|
||||
self: 'self',
|
||||
next: 'next',
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { createRouter } from './router';
|
||||
export type { TodoService, ListTodosRequest, ListTodosResponse } from './types';
|
||||
export { TodoReaderService } from './TodoReaderService';
|
||||
@@ -14,31 +14,45 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { InputError } from '@backstage/backend-common';
|
||||
import { EntityName, parseEntityName } from '@backstage/catalog-model';
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import { Logger } from 'winston';
|
||||
import { TodoService } from './types';
|
||||
|
||||
export interface RouterOptions {
|
||||
logger: Logger;
|
||||
config: Config;
|
||||
reader: UrlReader;
|
||||
catalogClient: CatalogClient;
|
||||
todoService: TodoService;
|
||||
}
|
||||
|
||||
export async function createRouter(
|
||||
options: RouterOptions,
|
||||
): Promise<express.Router> {
|
||||
const { logger } = options;
|
||||
const { todoService } = options;
|
||||
|
||||
const router = Router();
|
||||
router.use(express.json());
|
||||
|
||||
router.get('/v1/todos', (req, res) => {
|
||||
logger.debug('got todo request', req.query);
|
||||
res.json({ items: [{ text: 'Test TODO' }], totalCount: 1 });
|
||||
router.get('/v1/todos', async (req, res) => {
|
||||
const { entity: entityRef, cursor } = req.query;
|
||||
|
||||
if (entityRef && typeof entityRef !== 'string') {
|
||||
throw new InputError(`entity query must be a string`);
|
||||
}
|
||||
if (cursor && typeof cursor !== 'string') {
|
||||
throw new InputError(`cursor query must be a string`);
|
||||
}
|
||||
|
||||
let entity: EntityName | undefined = undefined;
|
||||
if (entityRef) {
|
||||
try {
|
||||
entity = parseEntityName(entityRef);
|
||||
} catch (error) {
|
||||
throw new InputError(`Invalid entity ref, ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
const todos = await todoService.listTodos({ entity, cursor });
|
||||
res.json(todos);
|
||||
});
|
||||
|
||||
return router;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* 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 { EntityName } from '@backstage/catalog-model';
|
||||
import { TodoItem } from '../lib';
|
||||
|
||||
export type ListTodosRequest = {
|
||||
entity?: EntityName;
|
||||
cursor?: string;
|
||||
};
|
||||
|
||||
export type ListTodosResponse = {
|
||||
items: TodoItem[];
|
||||
totalCount: number;
|
||||
cursors: {
|
||||
prev: string;
|
||||
self: string;
|
||||
next: string;
|
||||
};
|
||||
};
|
||||
|
||||
export interface TodoService {
|
||||
listTodos(req: ListTodosRequest): Promise<ListTodosResponse>;
|
||||
}
|
||||
Reference in New Issue
Block a user