Rename inventory to catalog

This commit is contained in:
Fredrik Adelöw
2020-05-12 11:16:09 +02:00
parent 7a8c30ef1e
commit e121fc6cad
37 changed files with 83 additions and 99 deletions
@@ -1,13 +1,13 @@
# Inventory Backend
# Catalog Backend
WORK IN PROGRESS
This is the backend part of the default inventory plugin.
This is the backend part of the default catalog plugin.
It responds to requests from the frontend part, and fulfills them by delegating
to your existing inventory related services.
to your existing catalog related services.
## Links
- (Frontend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/inventory]
- (Frontend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/catalog]
- (The Backstage homepage)[https://backstage.io]
@@ -1,5 +1,5 @@
{
"name": "@backstage/plugin-inventory-backend",
"name": "@backstage/plugin-catalog-backend",
"version": "0.1.1-alpha.4",
"main": "dist",
"license": "Apache-2.0",
@@ -18,16 +18,16 @@ import { NotFoundError } from '@backstage/backend-common';
import path from 'path';
import Knex from 'knex';
import { v4 as uuidv4 } from 'uuid';
import { AddLocationRequest, Component, Inventory, Location } from './types';
import { AddLocationRequest, Component, Catalog, Location } from './types';
export class DatabaseInventory implements Inventory {
static async create(database: Knex): Promise<DatabaseInventory> {
export class DatabaseCatalog implements Catalog {
static async create(database: Knex): Promise<DatabaseCatalog> {
await database.migrate.latest({
directory: path.resolve(__dirname, '..', 'migrations'),
loadExtensions: ['.js'],
});
return new DatabaseInventory(database);
return new DatabaseCatalog(database);
}
constructor(private readonly database: Knex) {}
@@ -49,9 +49,7 @@ export class DatabaseInventory implements Inventory {
}
async removeLocation(id: string): Promise<void> {
const result = await this.database('locations')
.where({ id })
.del();
const result = await this.database('locations').where({ id }).del();
if (!result) {
throw new NotFoundError(`Found no location with ID ${id}`);
@@ -59,9 +57,7 @@ export class DatabaseInventory implements Inventory {
}
async location(id: string): Promise<Location> {
const items = await this.database('locations')
.where({ id })
.select();
const items = await this.database('locations').where({ id }).select();
if (!items.length) {
throw new NotFoundError(`Found no location with ID ${id}`);
}
@@ -16,9 +16,9 @@
import { NotFoundError } from '@backstage/backend-common';
import { v4 as uuidv4 } from 'uuid';
import { AddLocationRequest, Component, Inventory, Location } from './types';
import { AddLocationRequest, Component, Catalog, Location } from './types';
export class StaticInventory implements Inventory {
export class StaticCatalog implements Catalog {
private _components: Component[];
private _locations: Location[];
@@ -32,7 +32,7 @@ export class StaticInventory implements Inventory {
}
async component(id: string): Promise<Component> {
const item = this._components.find(i => i.id === id);
const item = this._components.find((i) => i.id === id);
if (!item) {
throw new NotFoundError(`Found no component with ID ${id}`);
}
@@ -46,11 +46,11 @@ export class StaticInventory implements Inventory {
}
async removeLocation(id: string): Promise<void> {
this._locations = this._locations.filter(l => l.id !== id);
this._locations = this._locations.filter((l) => l.id !== id);
}
async location(id: string): Promise<Location> {
const location = this._locations.find(l => l.id === id);
const location = this._locations.find((l) => l.id === id);
if (!location) {
throw new NotFoundError(`Found no location with ID ${id}`);
}
@@ -14,6 +14,6 @@
* limitations under the License.
*/
export * from './DatabaseInventory';
export * from './StaticInventory';
export * from './DatabaseCatalog';
export * from './StaticCatalog';
export * from './types';
@@ -38,7 +38,7 @@ export const addLocationRequestShape: yup.Schema<AddLocationRequest> = yup
})
.noUnknown();
export type Inventory = {
export type Catalog = {
components(): Promise<Component[]>;
component(id: string): Promise<Component>;
addLocation(location: AddLocationRequest): Promise<Location>;
@@ -14,5 +14,5 @@
* limitations under the License.
*/
export * from './inventory';
export * from './catalog';
export * from './service/router';
@@ -18,25 +18,16 @@ import * as Knex from 'knex';
export async function up(knex: Knex): Promise<any> {
return knex.schema
.createTable('locations', table => {
table
.uuid('id')
.primary()
.comment('Auto-generated ID of the location');
table
.string('type')
.notNullable()
.comment('The type of location');
.createTable('locations', (table) => {
table.uuid('id').primary().comment('Auto-generated ID of the location');
table.string('type').notNullable().comment('The type of location');
table
.string('target')
.notNullable()
.comment('The actual target of the location');
})
.createTable('components', table => {
table
.string('name')
.primary()
.comment('The name of the component');
.createTable('components', (table) => {
table.string('name').primary().comment('The name of the component');
});
}
@@ -19,10 +19,10 @@ import express, { Request } from 'express';
import Router from 'express-promise-router';
import { Logger } from 'winston';
import yup from 'yup';
import { addLocationRequestShape, Inventory } from '../inventory';
import { addLocationRequestShape, Catalog } from '../catalog';
export interface RouterOptions {
inventory: Inventory;
catalog: Catalog;
logger: Logger;
}
@@ -54,19 +54,19 @@ async function validateRequestBody<T>(
export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const inventory = options.inventory;
const logger = options.logger.child({ plugin: 'inventory' });
const catalog = options.catalog;
const logger = options.logger.child({ plugin: 'catalog' });
const router = Router();
// Components
router
.get('/components', async (req, res) => {
const components = await inventory.components();
const components = await catalog.components();
res.status(200).send(components);
})
.get('/components/:id', async (req, res) => {
const { id } = req.params;
const component = await inventory.component(id);
const component = await catalog.component(id);
res.status(200).send(component);
});
@@ -74,21 +74,21 @@ export async function createRouter(
router
.post('/locations', async (req, res) => {
const input = await validateRequestBody(req, addLocationRequestShape);
const output = await inventory.addLocation(input);
const output = await catalog.addLocation(input);
res.status(201).send(output);
})
.get('/locations', async (req, res) => {
const output = await inventory.locations();
const output = await catalog.locations();
res.status(200).send(output);
})
.get('/locations/:id', async (req, res) => {
const { id } = req.params;
const output = await inventory.location(id);
const output = await catalog.location(id);
res.status(200).send(output);
})
.delete('/locations/:id', async (req, res) => {
const { id } = req.params;
await inventory.removeLocation(id);
await catalog.removeLocation(id);
res.status(200).send();
});
@@ -24,19 +24,19 @@ import cors from 'cors';
import express from 'express';
import helmet from 'helmet';
import { Logger } from 'winston';
import { Inventory } from '../inventory';
import { Catalog } from '../catalog';
import { createRouter } from './router';
export interface ApplicationOptions {
enableCors: boolean;
inventory: Inventory;
catalog: Catalog;
logger: Logger;
}
export async function createStandaloneApplication(
options: ApplicationOptions,
): Promise<express.Application> {
const { enableCors, inventory, logger } = options;
const { enableCors, catalog, logger } = options;
const app = express();
app.use(helmet());
@@ -46,7 +46,7 @@ export async function createStandaloneApplication(
app.use(compression());
app.use(express.json());
app.use(requestLoggingHandler());
app.use('/', await createRouter({ inventory, logger }));
app.use('/', await createRouter({ catalog, logger }));
app.use(notFoundHandler());
app.use(errorHandler());
@@ -16,7 +16,7 @@
import { Server } from 'http';
import { Logger } from 'winston';
import { StaticInventory } from '../inventory';
import { StaticCatalog } from '../catalog';
import { createStandaloneApplication } from './standaloneApplication';
export interface ServerOptions {
@@ -28,9 +28,9 @@ export interface ServerOptions {
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'inventory-backend' });
const logger = options.logger.child({ service: 'catalog-backend' });
const inventory = new StaticInventory(
const catalog = new StaticCatalog(
[
{ id: 'component1' },
{ id: 'component2' },
@@ -43,7 +43,7 @@ export async function startStandaloneServer(
logger.debug('Creating application...');
const app = await createStandaloneApplication({
enableCors: options.enableCors,
inventory,
catalog,
logger,
});
+13
View File
@@ -0,0 +1,13 @@
# Catalog Frontend
WORK IN PROGRESS
This is the frontend part of the default catalog plugin.
It will implement the core API for handling your catalog of software, and
supply the base views to show and manage them.
## Links
- (Backend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/catalog-backend]
- (The Backstage homepage)[https://backstage.io]
@@ -1,5 +1,5 @@
{
"name": "@backstage/plugin-inventory",
"name": "@backstage/plugin-catalog",
"version": "0.1.1-alpha.4",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts",
@@ -17,16 +17,16 @@
import React from 'react';
import { render } from '@testing-library/react';
import mockFetch from 'jest-fetch-mock';
import InventoryPage from './InventoryPage';
import CatalogPage from './CatalogPage';
import { ThemeProvider } from '@material-ui/core';
import { lightTheme } from '@backstage/theme';
describe('InventoryPage', () => {
describe('CatalogPage', () => {
it('should render', async () => {
mockFetch.mockResponse(() => new Promise(() => {}));
const rendered = render(
<ThemeProvider theme={lightTheme}>
<InventoryPage />
<CatalogPage />
</ThemeProvider>,
);
expect(await rendered.findByText('backstage-backend')).toBeInTheDocument();
@@ -31,10 +31,10 @@ const STATIC_DATA = [
{ id: 'backstage-microsite', kind: 'website' },
];
const InventoryPage: FC<{}> = () => {
const CatalogPage: FC<{}> = () => {
return (
<Page theme={pageTheme.home}>
<Header title="Inventory" subtitle="All your stuff" />
<Header title="Catalog" subtitle="All your stuff" />
<Content>
<Typography variant="h3">All of it</Typography>
<InfoCard>
@@ -62,4 +62,4 @@ const InventoryPage: FC<{}> = () => {
);
};
export default InventoryPage;
export default CatalogPage;
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { default } from './InventoryPage';
export { default } from './CatalogPage';
@@ -16,7 +16,7 @@
import { plugin } from './plugin';
describe('inventory', () => {
describe('catalog', () => {
it('should export plugin', () => {
expect(plugin).toBeDefined();
});
@@ -15,11 +15,11 @@
*/
import { createPlugin } from '@backstage/core';
import InventoryPage from './components/InventoryPage';
import CatalogPage from './components/CatalogPage';
export const plugin = createPlugin({
id: 'inventory',
id: 'catalog',
register({ router }) {
router.registerRoute('/inventory', InventoryPage);
router.registerRoute('/catalog', CatalogPage);
},
});
-13
View File
@@ -1,13 +0,0 @@
# Inventory Frontend
WORK IN PROGRESS
This is the frontend part of the default inventory plugin.
It will implement the core API for handling your inventory of software, and
supply the base views to show and manage them.
## Links
- (Backend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/inventory-backend]
- (The Backstage homepage)[https://backstage.io]
+3 -6
View File
@@ -1,13 +1,10 @@
# Inventory Frontend
# Scaffolder Frontend
WORK IN PROGRESS
This is the frontend part of the default inventory plugin.
It will implement the core API for handling your inventory of software, and
supply the base views to show and manage them.
This is the frontend part of the default scaffolder plugin.
## Links
- (Backend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/inventory-backend]
- (Backend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/scaffolder-backend]
- (The Backstage homepage)[https://backstage.io]
+1 -1
View File
@@ -16,7 +16,7 @@
import { plugin } from './plugin';
describe('inventory', () => {
describe('scaffolder', () => {
it('should export plugin', () => {
expect(plugin).toBeDefined();
});