added support for sqlite

Signed-off-by: Lykke Axlin <lykkeaxlin@hotmail.com>

Co-authored-by: klaraab <klarabroman@live.se>
This commit is contained in:
Lykke Axlin
2021-10-15 10:41:48 +02:00
parent e5679eb27c
commit 49511f5081
14 changed files with 375 additions and 205 deletions
@@ -1,35 +0,0 @@
/*
* Copyright 2021 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.
*/
exports.up = function up(knex) {
return knex.raw(`
CREATE OR REPLACE FUNCTION update_timestamp() RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$;
`);
};
exports.down = function down(knex) {
return knex.raw(`
DROP FUNCTION IF EXISTS update_timestamp() CASCADE;
`);
};
@@ -17,8 +17,12 @@
exports.up = async function up(knex) {
await knex.schema.createTable('metadata', table => {
table.comment('The table of Bazaar metadata');
table
.text('entity_ref')
.notNullable()
.unique()
.comment('The ref of the entity');
table.text('name').notNullable().comment('The name of the entity');
table.text('entity_ref').notNullable().comment('The ref of the entity');
table
.text('community')
.comment('Link to where the community can discuss ideas');
@@ -31,20 +35,20 @@ exports.up = async function up(knex) {
.defaultTo('proposed')
.notNullable()
.comment('The status of the Bazaar project');
table.timestamps(true, true);
table
.text('updated_at')
.notNullable()
.comment('Timestamp on ISO 8601 format when entity was last updated');
});
await knex.raw(`
CREATE TRIGGER update_timestamp
BEFORE UPDATE
ON metadata
FOR EACH ROW
EXECUTE PROCEDURE update_timestamp();
`);
await knex.schema.createTable('members', table => {
table.comment('The table of Bazaar members');
table.text('entity_ref').notNullable().comment('The ref of the entity');
table
.text('entity_ref')
.notNullable()
.references('metadata.entity_ref')
.onDelete('CASCADE')
.comment('The ref of the entity');
table.text('user_id').notNullable().comment('The user id of the member');
table
.dateTime('join_date')
@@ -17,12 +17,14 @@
import { DatabaseHandler } from './DatabaseHandler';
import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
const members: Array<any> = [
{
entity_ref: 'project1',
user_id: 'member1',
},
];
const bazaarProject: any = {
name: 'name',
entityRef: 'ref',
community: '',
status: 'proposed',
announcement: 'a',
membersCount: 0,
};
describe('DatabaseHandler', () => {
const databases = TestDatabases.create({
@@ -38,10 +40,11 @@ describe('DatabaseHandler', () => {
'should do a full sync with the locations on connect, %p',
async databaseId => {
const db = await createDatabaseHandler(databaseId);
await db.addMember(members[0].user_id, members[0].entity_ref);
const cov: any[] = await db.getMembers('project1');
expect(cov[0].entity_ref).toEqual(members[0].entity_ref);
expect(cov[0].user_id).toEqual(members[0].user_id);
await db.insertMetadata(bazaarProject);
const entities = await db.getEntities();
expect(entities.length).toEqual(1);
expect(entities[0].entity_ref).toEqual(bazaarProject.entityRef);
},
60_000,
);
@@ -43,20 +43,103 @@ export class DatabaseHandler {
this.database = options.database;
}
async getMembers(entityRef: any) {
async getMembers(entityRef: string) {
return await this.database
.select('*')
.from('public.members')
.from('members')
.where({ entity_ref: entityRef });
}
async addMember(userId: any, entityRef: any, picture?: string) {
async addMember(userId: string, entityRef: string, picture?: string) {
await this.database
.insert({
entity_ref: entityRef,
user_id: userId,
picture: picture,
})
.into('public.members');
.into('members');
}
async deleteMember(userId: string, entityRef: string) {
return await this.database('members')
.where({ entity_ref: decodeURIComponent(entityRef) })
.andWhere('user_id', userId)
.del();
}
async getMetadata(entityRef: string) {
const coalesce = this.database.raw(
'coalesce(count(members.entity_ref), 0) as members_count',
);
const columns = [
'members.entity_ref',
'metadata.entity_ref',
'metadata.name',
'metadata.announcement',
'metadata.status',
'metadata.updated_at',
'metadata.community',
];
return await this.database('metadata')
.select([...columns, coalesce])
.where({ 'metadata.entity_ref': entityRef })
.groupBy(columns)
.leftJoin('members', 'metadata.entity_ref', '=', 'members.entity_ref');
}
async insertMetadata(bazaarProject: any) {
const { name, entityRef, community, announcement, status } = bazaarProject;
await this.database
.insert({
name: name,
entity_ref: entityRef,
community: community,
announcement: announcement,
status: status,
updated_at: new Date().toISOString(),
})
.into('metadata');
}
async updateMetadata(bazaarProject: any) {
const { entityRef, community, announcement, status } = bazaarProject;
return await this.database('metadata')
.where({ entity_ref: entityRef })
.update({
announcement: announcement,
community: community,
status: status,
updated_at: new Date().toISOString(),
});
}
async deleteMetadata(entityRef: string) {
return await this.database('metadata')
.where({ entity_ref: entityRef })
.del();
}
async getEntities() {
const coalesce = this.database.raw(
'coalesce(count(members.entity_ref), 0) as members_count',
);
const columns = [
'members.entity_ref',
'metadata.entity_ref',
'metadata.name',
'metadata.announcement',
'metadata.status',
'metadata.updated_at',
'metadata.community',
];
return await this.database('metadata')
.select([...columns, coalesce])
.groupBy(columns)
.leftJoin('members', 'metadata.entity_ref', '=', 'members.entity_ref');
}
}
+9 -85
View File
@@ -61,21 +61,7 @@ export async function createRouter(
router.delete('/member/:ref/:id', async (request, response) => {
const { ref, id } = request.params;
const count = await db('public.members')
.where({ entity_ref: decodeURIComponent(ref) })
.andWhere('user_id', id)
.del();
if (count) {
response.json({ status: 'ok' });
} else {
response.status(404).json({ message: 'Record not found' });
}
});
router.delete('/members/:ref', async (request, response) => {
const ref = decodeURIComponent(request.params.ref);
const count = await db('public.members').where({ entity_ref: ref }).del();
const count = await dbHandler.deleteMember(id, ref);
if (count) {
response.json({ status: 'ok' });
@@ -85,97 +71,35 @@ export async function createRouter(
});
router.get('/metadata/:ref', async (request, response) => {
const entity_ref = decodeURIComponent(request.params.ref);
const coalesce = db.raw(
'coalesce(count(members.entity_ref), 0) as members_count',
);
const columns = [
'members.entity_ref',
'metadata.entity_ref',
'metadata.name',
'metadata.announcement',
'metadata.status',
'metadata.updated_at',
'metadata.community',
];
const data = await db('public.members as members')
.select([...columns, coalesce])
.where({ 'metadata.entity_ref': entity_ref })
.groupBy(columns)
.rightJoin(
'public.metadata as metadata',
'metadata.entity_ref',
'=',
'members.entity_ref',
);
const ref = decodeURIComponent(request.params.ref);
const data = await dbHandler.getMetadata(ref);
response.json({ status: 'ok', data: data });
});
router.get('/entities', async (_, response) => {
const coalesce = db.raw(
'coalesce(count(members.entity_ref), 0) as members_count',
);
const columns = [
'members.entity_ref',
'metadata.entity_ref',
'metadata.name',
'metadata.announcement',
'metadata.status',
'metadata.updated_at',
'metadata.community',
];
const data = await db('public.members as members')
.select([...columns, coalesce])
.groupBy(columns)
.rightJoin(
'public.metadata as metadata',
'metadata.entity_ref',
'=',
'members.entity_ref',
);
const data = await dbHandler.getEntities();
response.json({ status: 'ok', data: data });
});
router.put('/metadata', async (request, response) => {
const { name, announcement, status, community, entity_ref } = request.body;
const bazaarProject = request.body;
const count = await db('public.metadata')
.where({ entity_ref: entity_ref })
.update({
announcement: announcement,
community: community,
status: status,
});
const count = await dbHandler.updateMetadata(bazaarProject);
if (count) {
response.json({ status: 'ok' });
} else {
await db
.insert({
name: name,
entity_ref: entity_ref,
community: community,
announcement: announcement,
status: status,
})
.into('public.metadata');
await dbHandler.insertMetadata(bazaarProject);
response.json({ status: 'ok' });
}
});
router.delete('/metadata/:ref', async (request, response) => {
const entity_ref = decodeURIComponent(request.params.ref);
const ref = decodeURIComponent(request.params.ref);
const count = await db('public.metadata')
.where({ entity_ref: entity_ref })
.del();
const count = await dbHandler.deleteMetadata(ref);
if (count) {
response.json({ status: 'ok' });
+5 -1
View File
@@ -101,6 +101,10 @@ The metadata related to the Bazaar is stored in a database. Right now there are
## Future work and ideas
- Workflow
- Make it possible to add a Bazaar project without linking it to a Backstage entity, this would make it easier to just add an idea to the Bazaar.
- Bazaar landing page
- Add a tab 'My page', where your personal data is displayed. For example: your projects and its latest activities, projects or tags you are following etc.
@@ -117,7 +121,7 @@ The metadata related to the Bazaar is stored in a database. Right now there are
- Dialogues
- Extend the dialogue for adding a project with more fields, e.g. chat link and the possibility to add images
- Extend the dialogue for adding a project with more fields, e.g. the possibility to add images
- Testing
- Add tests to all the components
+2 -2
View File
@@ -22,7 +22,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.9.0",
"@backstage/cli": "^0.7.2",
"@backstage/cli": "^0.7.15",
"@backstage/core-components": "^0.6.1",
"@backstage/core-plugin-api": "^0.1.10",
"@backstage/plugin-catalog": "^0.7.0",
@@ -30,7 +30,7 @@
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/jest-dom": "^5.10.1",
"luxon": "^2.0.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
+4 -28
View File
@@ -20,7 +20,7 @@ import {
DiscoveryApi,
IdentityApi,
} from '@backstage/core-plugin-api';
import { BazaarProject, Status } from './types';
import { BazaarProject } from './types';
export const bazaarApiRef = createApiRef<BazaarApi>({
id: 'bazaar',
@@ -28,13 +28,7 @@ export const bazaarApiRef = createApiRef<BazaarApi>({
});
export interface BazaarApi {
updateMetadata(
entity: Entity,
name: string,
community: string,
announcement: string,
status: Status,
): Promise<any>;
updateMetadata(bazaarProject: BazaarProject): Promise<any>;
getMetadata(entity: Entity): Promise<any>;
@@ -61,13 +55,7 @@ export class BazaarClient implements BazaarApi {
this.discoveryApi = options.discoveryApi;
}
async updateMetadata(
entity: Entity,
name: string,
community: string,
announcement: string,
status: Status,
): Promise<any> {
async updateMetadata(bazaarProject: BazaarProject): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
return await fetch(`${baseUrl}/metadata`, {
@@ -76,13 +64,7 @@ export class BazaarClient implements BazaarApi {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
entity_ref: stringifyEntityRef(entity),
name: name,
announcement: announcement,
community: community,
status: status,
}),
body: JSON.stringify(bazaarProject),
}).then(resp => resp.json());
}
@@ -155,11 +137,5 @@ export class BazaarClient implements BazaarApi {
await fetch(`${baseUrl}/metadata/${encodeURIComponent(entityRef)}`, {
method: 'DELETE',
});
if (bazaarProject.membersCount > 0) {
await fetch(`${baseUrl}/members/${encodeURIComponent(entityRef)}`, {
method: 'DELETE',
});
}
}
}
@@ -15,7 +15,7 @@
*/
import React, { useState, useEffect } from 'react';
import { Entity } from '@backstage/catalog-model';
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { SubmitHandler } from 'react-hook-form';
import { useApi } from '@backstage/core-plugin-api';
import { ProjectDialog } from '../ProjectDialog';
@@ -70,13 +70,14 @@ export const AddProjectDialog = ({
const formValues = getValues();
if (selectedEntity) {
await bazaarApi.updateMetadata(
selectedEntity,
selectedEntity.metadata.name,
formValues.community,
formValues.announcement,
formValues.status,
);
await bazaarApi.updateMetadata({
name: selectedEntity.metadata.name,
entityRef: stringifyEntityRef(selectedEntity),
announcement: formValues.announcement,
status: formValues.status,
community: formValues.community,
membersCount: 0,
} as BazaarProject);
fetchBazaarProjects();
fetchCatalogEntities();
@@ -15,7 +15,7 @@
*/
import React, { useState, useEffect } from 'react';
import { Entity } from '@backstage/catalog-model';
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { useApi } from '@backstage/core-plugin-api';
import { ProjectDialog } from '../ProjectDialog';
import { BazaarProject, FormValues } from '../../types';
@@ -56,13 +56,14 @@ export const EditProjectDialog = ({
const handleSave: any = async (getValues: any, _: any) => {
const formValues = getValues();
const updateResponse = await bazaarApi.updateMetadata(
entity!,
entity.metadata.name,
formValues.community,
formValues.announcement,
formValues.status,
);
const updateResponse = await bazaarApi.updateMetadata({
name: entity.metadata.name,
entityRef: stringifyEntityRef(entity),
announcement: formValues.announcement,
status: formValues.status,
community: formValues.community,
membersCount: bazaarProject.membersCount,
});
if (updateResponse.status === 'ok') fetchBazaarProject();
handleClose();
@@ -73,7 +73,9 @@ export const ProjectCard = ({ bazaarProject }: Props) => {
>
<ItemCardHeader
title={name}
subtitle={`updated ${DateTime.fromISO(updatedAt!).toRelative({
subtitle={`updated ${DateTime.fromISO(
new Date(updatedAt!).toISOString(),
).toRelative({
base: DateTime.now(),
})}`}
/>
@@ -39,12 +39,15 @@ const useStyles = makeStyles({
},
});
const filterCatalogEntities = (bazaarProjects: any, catalogEntities: any) => {
const bazaarProjectRefs = bazaarProjects?.value?.map(
const filterCatalogEntities = (
bazaarProjects: BazaarProject[],
catalogEntities: Entity[],
) => {
const bazaarProjectRefs = bazaarProjects.map(
(project: BazaarProject) => project.entityRef,
);
const filtered = catalogEntities?.value?.filter((entity: Entity) => {
const filtered = catalogEntities.filter((entity: Entity) => {
return !bazaarProjectRefs?.includes(stringifyEntityRef(entity));
});
@@ -110,8 +113,8 @@ export const SortView = () => {
useEffect(() => {
const filteredCatalogEntities = filterCatalogEntities(
bazaarProjects,
catalogEntities,
bazaarProjects.value || [],
catalogEntities.value || [],
);
if (filteredCatalogEntities) {
+1
View File
@@ -16,3 +16,4 @@
export { bazaarPlugin, BazaarPage } from './plugin';
export { EntityBazaarInfoCard } from './components/EntityBazaarInfoCard';
export type { BazaarProject } from './types';
+210 -7
View File
@@ -343,6 +343,13 @@
dependencies:
"@babel/highlight" "^7.14.5"
"@babel/code-frame@^7.15.8":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503"
integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==
dependencies:
"@babel/highlight" "^7.14.5"
"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4":
version "7.14.4"
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58"
@@ -353,6 +360,11 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.9.tgz#ac7996ceaafcf8f410119c8af0d1db4cf914a210"
integrity sha512-p3QjZmMGHDGdpcwEYYWu7i7oJShJvtgMjJeb0W95PPhSm++3lm8YXYOh45Y6iCN9PkZLTZ7CIX5nFrp7pw7TXw==
"@babel/compat-data@^7.15.0":
version "7.15.0"
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
"@babel/core@7.12.9":
version "7.12.9"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8"
@@ -375,7 +387,7 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.4.4", "@babel/core@^7.7.5":
"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.7.5":
version "7.14.8"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.14.8.tgz#20cdf7c84b5d86d83fac8710a8bc605a7ba3f010"
integrity sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q==
@@ -396,6 +408,27 @@
semver "^6.3.0"
source-map "^0.5.0"
"@babel/core@^7.4.4":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10"
integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==
dependencies:
"@babel/code-frame" "^7.15.8"
"@babel/generator" "^7.15.8"
"@babel/helper-compilation-targets" "^7.15.4"
"@babel/helper-module-transforms" "^7.15.8"
"@babel/helpers" "^7.15.4"
"@babel/parser" "^7.15.8"
"@babel/template" "^7.15.4"
"@babel/traverse" "^7.15.4"
"@babel/types" "^7.15.6"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.1.2"
semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.14.8", "@babel/generator@^7.14.9":
version "7.14.9"
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.14.9.tgz#23b19c597d38b4f7dc2e3fe42a69c88d9ecfaa16"
@@ -414,6 +447,15 @@
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/generator@^7.15.4", "@babel/generator@^7.15.8":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1"
integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==
dependencies:
"@babel/types" "^7.15.6"
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
@@ -464,6 +506,16 @@
browserslist "^4.16.6"
semver "^6.3.0"
"@babel/helper-compilation-targets@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9"
integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==
dependencies:
"@babel/compat-data" "^7.15.0"
"@babel/helper-validator-option" "^7.14.5"
browserslist "^4.16.6"
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3":
version "7.14.4"
resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz#abf888d836a441abee783c75229279748705dc42"
@@ -564,6 +616,15 @@
"@babel/template" "^7.14.5"
"@babel/types" "^7.14.5"
"@babel/helper-function-name@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc"
integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==
dependencies:
"@babel/helper-get-function-arity" "^7.15.4"
"@babel/template" "^7.15.4"
"@babel/types" "^7.15.4"
"@babel/helper-get-function-arity@^7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
@@ -578,6 +639,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-get-function-arity@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b"
integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-hoist-variables@^7.13.0":
version "7.13.16"
resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30"
@@ -593,6 +661,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-hoist-variables@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df"
integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-member-expression-to-functions@^7.13.12":
version "7.13.12"
resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72"
@@ -607,6 +682,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-member-expression-to-functions@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef"
integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
version "7.13.12"
resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977"
@@ -621,6 +703,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-module-imports@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f"
integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.14.8":
version "7.14.8"
resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.8.tgz#d4279f7e3fd5f4d5d342d833af36d4dd87d7dc49"
@@ -649,6 +738,20 @@
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
"@babel/helper-module-transforms@^7.15.4", "@babel/helper-module-transforms@^7.15.8":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2"
integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==
dependencies:
"@babel/helper-module-imports" "^7.15.4"
"@babel/helper-replace-supers" "^7.15.4"
"@babel/helper-simple-access" "^7.15.4"
"@babel/helper-split-export-declaration" "^7.15.4"
"@babel/helper-validator-identifier" "^7.15.7"
"@babel/template" "^7.15.4"
"@babel/traverse" "^7.15.4"
"@babel/types" "^7.15.6"
"@babel/helper-optimise-call-expression@^7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
@@ -663,6 +766,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-optimise-call-expression@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171"
integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-plugin-utils@7.10.4":
version "7.10.4"
resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
@@ -716,6 +826,16 @@
"@babel/traverse" "^7.14.5"
"@babel/types" "^7.14.5"
"@babel/helper-replace-supers@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a"
integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.15.4"
"@babel/helper-optimise-call-expression" "^7.15.4"
"@babel/traverse" "^7.15.4"
"@babel/types" "^7.15.4"
"@babel/helper-simple-access@^7.13.12":
version "7.13.12"
resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
@@ -730,6 +850,13 @@
dependencies:
"@babel/types" "^7.14.8"
"@babel/helper-simple-access@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b"
integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-skip-transparent-expression-wrappers@^7.12.1":
version "7.12.1"
resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf"
@@ -758,6 +885,13 @@
dependencies:
"@babel/types" "^7.14.5"
"@babel/helper-split-export-declaration@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257"
integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==
dependencies:
"@babel/types" "^7.15.4"
"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0":
version "7.14.0"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
@@ -768,6 +902,11 @@
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
"@babel/helper-validator-identifier@^7.15.7":
version "7.15.7"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
"@babel/helper-validator-option@^7.12.17":
version "7.12.17"
resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831"
@@ -807,6 +946,15 @@
"@babel/traverse" "^7.14.8"
"@babel/types" "^7.14.8"
"@babel/helpers@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43"
integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==
dependencies:
"@babel/template" "^7.15.4"
"@babel/traverse" "^7.15.4"
"@babel/types" "^7.15.4"
"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13":
version "7.14.0"
resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf"
@@ -835,6 +983,11 @@
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.14.9.tgz#596c1ad67608070058ebf8df50c1eaf65db895a4"
integrity sha512-RdUTOseXJ8POjjOeEBEvNMIZU/nm4yu2rufRkcibzkkg7DmQvXU8v3M4Xk9G7uuI86CDGkKcuDWgioqZm+mScQ==
"@babel/parser@^7.15.4", "@babel/parser@^7.15.8":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016"
integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
version "7.13.12"
resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a"
@@ -1536,7 +1689,7 @@
"@babel/helper-plugin-utils" "^7.14.5"
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.14.0", "@babel/plugin-transform-modules-commonjs@^7.14.5", "@babel/plugin-transform-modules-commonjs@^7.4.4":
"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.14.0", "@babel/plugin-transform-modules-commonjs@^7.14.5":
version "7.14.5"
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz#7aaee0ea98283de94da98b28f8c35701429dad97"
integrity sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==
@@ -1546,6 +1699,16 @@
"@babel/helper-simple-access" "^7.14.5"
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-commonjs@^7.4.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz#8201101240eabb5a76c08ef61b2954f767b6b4c1"
integrity sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==
dependencies:
"@babel/helper-module-transforms" "^7.15.4"
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/helper-simple-access" "^7.15.4"
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-systemjs@^7.13.8":
version "7.13.8"
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3"
@@ -2130,6 +2293,15 @@
"@babel/parser" "^7.14.5"
"@babel/types" "^7.14.5"
"@babel/template@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194"
integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==
dependencies:
"@babel/code-frame" "^7.14.5"
"@babel/parser" "^7.15.4"
"@babel/types" "^7.15.4"
"@babel/traverse@7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0"
@@ -2174,6 +2346,21 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d"
integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==
dependencies:
"@babel/code-frame" "^7.14.5"
"@babel/generator" "^7.15.4"
"@babel/helper-function-name" "^7.15.4"
"@babel/helper-hoist-variables" "^7.15.4"
"@babel/helper-split-export-declaration" "^7.15.4"
"@babel/parser" "^7.15.4"
"@babel/types" "^7.15.4"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611"
@@ -2199,6 +2386,14 @@
"@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
"@babel/types@^7.15.4", "@babel/types@^7.15.6":
version "7.15.6"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f"
integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==
dependencies:
"@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
"@backstage/catalog-client@^0.3.18":
version "0.3.19"
resolved "https://registry.npmjs.org/@backstage/catalog-client/-/catalog-client-0.3.19.tgz#109b0fde1cc2d9a306635f3775fc8f6174172b14"
@@ -6270,7 +6465,7 @@
lz-string "^1.4.4"
pretty-format "^26.6.2"
"@testing-library/jest-dom@^5.10.1", "@testing-library/jest-dom@^5.14.1":
"@testing-library/jest-dom@^5.10.1":
version "5.14.1"
resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.14.1.tgz#8501e16f1e55a55d675fe73eecee32cdaddb9766"
integrity sha512-dfB7HVIgTNCxH22M1+KU6viG5of2ldoA5ly8Ar8xkezKHKXjRvznCdbMbqjYGgO2xjRbwnR+rR8MLUIqF3kKbQ==
@@ -6421,7 +6616,15 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/body-parser@*", "@types/body-parser@1.19.0", "@types/body-parser@^1.19.0":
"@types/body-parser@*", "@types/body-parser@^1.19.0":
version "1.19.1"
resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c"
integrity sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==
dependencies:
"@types/connect" "*"
"@types/node" "*"
"@types/body-parser@1.19.0":
version "1.19.0"
resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==
@@ -22944,9 +23147,9 @@ react-hook-form@^7.12.2:
integrity sha512-kcLDmSmlyLUFx2UU5bG/o4+3NeK753fhKodJa8gkplXohGkpAq0/p+TR24OWjZmkEc3ES7ppC5v5d6KUk+fJTA==
react-hook-form@^7.13.0:
version "7.17.3"
resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.17.3.tgz#3ed85bed3a6aa4d013e0027a93799d668064c201"
integrity sha512-hUKOVtz6Wb319VJRl6OKV8vAhLo5P5raOQEG8lJZt/VXBMv6n2adgpIl1e+36rjX126Wq351ipM0goCgj4UUzQ==
version "7.17.4"
resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.17.4.tgz#232b6aaccddb91eb4a228ac20b154abd90866fdb"
integrity sha512-7XhbCr7d9fDC1TgcK/BUbt7D3q0VJMu7jPErfsa0JrxVjv/nni41xWdJcy0Zb7R+Np8OsCkQ2lMyloAtE3DLiQ==
react-hot-loader@^4.12.21:
version "4.13.0"