OpenStackSwift tests added to project
Signed-off-by: Mert Can Bilgiç <mert.bilgic@trendyol.com>
This commit is contained in:
committed by
Mert Can Bilgiç
parent
75ec0e2358
commit
32fac33d8d
@@ -13,21 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { OpenstackProviderOptions } from 'pkgcloud';
|
||||
import fs from 'fs-extra';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { ObjectWritableMock, BufferReadableMock } from 'stream-mock';
|
||||
|
||||
const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir';
|
||||
|
||||
const checkFileExists = async (Key: string): Promise<boolean> => {
|
||||
// Key will always have / as file separator irrespective of OS since S3 expects /.
|
||||
// Normalize Key to OS specific path before checking if file exists.
|
||||
const relativeFilePath = Key.split(path.posix.sep).join(path.sep);
|
||||
const filePath = path.join(rootDir, Key);
|
||||
|
||||
try {
|
||||
await fs.access(filePath, fs.constants.F_OK);
|
||||
fs.accessSync(filePath, fs.constants.F_OK);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
@@ -38,11 +37,11 @@ class PkgCloudStorageClient {
|
||||
getFile(
|
||||
containerName: string,
|
||||
file: string,
|
||||
callback: (err: string, file: string) => any,
|
||||
callback: (err: any, file: string) => any,
|
||||
) {
|
||||
checkFileExists(file).then(res => {
|
||||
if (!res) {
|
||||
callback('File does not exist', undefined);
|
||||
callback('File does not exist', file);
|
||||
throw new Error('File does not exist');
|
||||
} else {
|
||||
callback(undefined, 'success');
|
||||
@@ -55,40 +54,28 @@ class PkgCloudStorageClient {
|
||||
callback: (err: string, container: string) => any,
|
||||
) {
|
||||
if (containerName !== 'mock') {
|
||||
callback("Container doesn't exist", undefined);
|
||||
callback("Container doesn't exist", containerName);
|
||||
throw new Error('Container does not exist');
|
||||
} else {
|
||||
callback(undefined, 'success');
|
||||
callback('Container does not exist', 'success');
|
||||
}
|
||||
}
|
||||
|
||||
upload({ containerName, remote }: { containerName: string; remote: string }) {
|
||||
checkFileExists(remote).then(res => {
|
||||
if (!res) {
|
||||
return new Error("File doesn't exists");
|
||||
}
|
||||
return fs.createWriteStream(`${containerName}/${remote}`);
|
||||
});
|
||||
upload() {
|
||||
return new ObjectWritableMock();
|
||||
}
|
||||
|
||||
download({
|
||||
containerName,
|
||||
remote,
|
||||
}: {
|
||||
containerName: string;
|
||||
remote: string;
|
||||
}) {
|
||||
checkFileExists(remote).then(res => {
|
||||
if (!res) {
|
||||
return new Error("File doesn't exists");
|
||||
}
|
||||
return fs.createReadStream(remote);
|
||||
download() {
|
||||
const stringify = JSON.stringify({
|
||||
"site_description": 'site_content',
|
||||
"site_name": "backstage"
|
||||
});
|
||||
return new BufferReadableMock([stringify]);
|
||||
}
|
||||
}
|
||||
|
||||
export class storage {
|
||||
static createClient(params: OpenstackProviderOptions) {
|
||||
static createClient() {
|
||||
return new PkgCloudStorageClient();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"p-limit": "^3.1.0",
|
||||
"pkgcloud": "^2.2.0",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"stream-mock": "^2.0.5",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2020 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 {
|
||||
Entity,
|
||||
EntityName,
|
||||
ENTITY_DEFAULT_NAMESPACE,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import mockFs from 'mock-fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import * as winston from 'winston';
|
||||
import { OpenStackSwiftPublish } from './openStackSwift';
|
||||
import { PublisherBase, TechDocsMetadata } from './types';
|
||||
|
||||
// NOTE: /packages/techdocs-common/__mocks__ is being used to mock pkgcloud client library
|
||||
|
||||
const createMockEntity = (annotations = {}): Entity => {
|
||||
return {
|
||||
apiVersion: 'version',
|
||||
kind: 'TestKind',
|
||||
metadata: {
|
||||
name: 'test-component-name',
|
||||
namespace: 'test-namespace',
|
||||
annotations: {
|
||||
...annotations,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const createMockEntityName = (): EntityName => ({
|
||||
kind: 'TestKind',
|
||||
name: 'test-component-name',
|
||||
namespace: 'test-namespace',
|
||||
});
|
||||
|
||||
const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir';
|
||||
|
||||
const getEntityRootDir = (entity: Entity) => {
|
||||
const {
|
||||
kind,
|
||||
metadata: { namespace, name },
|
||||
} = entity;
|
||||
|
||||
return path.join(rootDir, namespace || ENTITY_DEFAULT_NAMESPACE, kind, name);
|
||||
};
|
||||
|
||||
const logger = winston.createLogger();
|
||||
jest.spyOn(logger, 'info').mockReturnValue(logger);
|
||||
jest.spyOn(logger, 'error').mockReturnValue(logger);
|
||||
|
||||
let publisher: PublisherBase;
|
||||
|
||||
beforeEach(() => {
|
||||
mockFs.restore();
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
requestUrl: 'http://localhost:7000',
|
||||
publisher: {
|
||||
type: 'openStackSwift',
|
||||
openStackSwift: {
|
||||
username: 'mockuser',
|
||||
password: 'verystrongpass',
|
||||
authUrl: 'mockauthurl',
|
||||
region: 'mockregion',
|
||||
containerName: 'mock',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
publisher = OpenStackSwiftPublish.fromConfig(mockConfig, logger);
|
||||
});
|
||||
|
||||
describe('OpenStackSwiftPublish', () => {
|
||||
describe('publish', () => {
|
||||
beforeEach(() => {
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'index.html': '',
|
||||
'404.html': '',
|
||||
assets: {
|
||||
'main.css': '',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should publish a directory', async () => {
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
setTimeout(async () => {
|
||||
expect(
|
||||
await publisher.publish({
|
||||
entity,
|
||||
directory: entityRootDir,
|
||||
}),
|
||||
).toBeUndefined()
|
||||
}, 5000);
|
||||
});
|
||||
|
||||
it('should fail to publish a directory', async () => {
|
||||
expect.assertions(3);
|
||||
const wrongPathToGeneratedDirectory = path.join(
|
||||
rootDir,
|
||||
'wrong',
|
||||
'path',
|
||||
'to',
|
||||
'generatedDirectory',
|
||||
);
|
||||
|
||||
const entity = createMockEntity();
|
||||
await expect(
|
||||
publisher.publish({
|
||||
entity,
|
||||
directory: wrongPathToGeneratedDirectory,
|
||||
}),
|
||||
).rejects.toThrowError();
|
||||
|
||||
await publisher
|
||||
.publish({
|
||||
entity,
|
||||
directory: wrongPathToGeneratedDirectory,
|
||||
})
|
||||
.catch(error => {
|
||||
expect(error.message).toEqual(
|
||||
// Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error
|
||||
// Issue reported https://github.com/tschaub/mock-fs/issues/118
|
||||
expect.stringContaining(
|
||||
`Unable to upload file(s) to OpenStack Swift. Error: Failed to read template directory: ENOENT, no such file or directory`,
|
||||
),
|
||||
);
|
||||
expect(error.message).toEqual(
|
||||
expect.stringContaining(wrongPathToGeneratedDirectory),
|
||||
);
|
||||
});
|
||||
mockFs.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasDocsBeenGenerated', () => {
|
||||
it('should return true if docs has been generated', async () => {
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'index.html': 'file-content',
|
||||
},
|
||||
});
|
||||
|
||||
expect(await publisher.hasDocsBeenGenerated(entity)).toBe(true);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return false if docs has not been generated', async () => {
|
||||
const entity = createMockEntity();
|
||||
|
||||
expect(await publisher.hasDocsBeenGenerated(entity)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchTechDocsMetadata', () => {
|
||||
it('should return tech docs metadata', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json':
|
||||
'{"site_name": "backstage", "site_description": "site_content"}',
|
||||
},
|
||||
});
|
||||
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return tech docs metadata when json encoded with single quotes', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json': `{'site_name': 'backstage', 'site_description': 'site_content'}`,
|
||||
},
|
||||
});
|
||||
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return an error if the techdocs_metadata.json file is not present', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
await publisher
|
||||
.fetchTechDocsMetadata(entityNameMock)
|
||||
.catch(error =>
|
||||
expect(error).toEqual(
|
||||
new Error(
|
||||
`TechDocs metadata fetch failed, The file ${path.join(
|
||||
entityRootDir,
|
||||
'techdocs_metadata.json',
|
||||
)} does not exist !`,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -107,7 +107,6 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
* Directory structure used in the bucket is - entityNamespace/entityKind/entityName/index.html
|
||||
*/
|
||||
async publish({ entity, directory }: PublishRequest): Promise<void> {
|
||||
this.logger.info(`Publish Called hey`);
|
||||
try {
|
||||
// Note: OpenStack Swift manages creation of parent directories if they do not exist.
|
||||
// So collecting path of only the files is good enough.
|
||||
@@ -139,8 +138,7 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
};
|
||||
|
||||
// Rate limit the concurrent execution of file uploads to batches of 10 (per publish)
|
||||
const uploadFile = limiter(
|
||||
() =>
|
||||
const uploadFile = limiter(() =>
|
||||
new Promise((res, rej) => {
|
||||
const writeStream = this.storageClient.upload(params);
|
||||
|
||||
@@ -168,7 +166,6 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
async fetchTechDocsMetadata(
|
||||
entityName: EntityName,
|
||||
): Promise<TechDocsMetadata> {
|
||||
this.logger.info(`fetchTechDocsMetadata Called hey`);
|
||||
try {
|
||||
return await new Promise<TechDocsMetadata>(async (resolve, reject) => {
|
||||
const entityRootDir = `${entityName.namespace}/${entityName.kind}/${entityName.name}`;
|
||||
@@ -206,7 +203,6 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
*/
|
||||
docsRouter(): express.Handler {
|
||||
return async (req, res) => {
|
||||
this.logger.info(`docsRouter Called hey`);
|
||||
// Trim the leading forward slash
|
||||
// filePath example - /default/Component/documented-component/index.html
|
||||
|
||||
@@ -243,7 +239,6 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
*/
|
||||
async hasDocsBeenGenerated(entity: Entity): Promise<boolean> {
|
||||
try {
|
||||
this.logger.info(`hasDocsBeenGenerated Called hey`);
|
||||
const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;
|
||||
|
||||
return new Promise(res => {
|
||||
@@ -251,7 +246,6 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
this.containerName,
|
||||
`${entityRootDir}/index.html`,
|
||||
(err: any, file: any) => {
|
||||
console.log(file);
|
||||
if (!err && file) {
|
||||
res(true);
|
||||
} else res(false);
|
||||
|
||||
@@ -1816,35 +1816,78 @@
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@backstage/catalog-model@^0.2.0":
|
||||
version "0.7.2"
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/@backstage/catalog-model/-/catalog-model-0.2.0.tgz#e3fe2a4ddeb6a9b6ec480c80cb2b9c39cb245576"
|
||||
integrity sha512-Y1ocdRpBlxK/VrJQjHlQd0bgADECd1B2NRjwd8ss46ibT5hwLvMOfD80+Fa7oPLu0ktJrH4lq0pNIIJIml48zA==
|
||||
dependencies:
|
||||
"@backstage/config" "^0.1.3"
|
||||
"@backstage/config" "^0.1.1"
|
||||
"@types/json-schema" "^7.0.5"
|
||||
"@types/yup" "^0.29.8"
|
||||
ajv "^7.0.3"
|
||||
json-schema "^0.2.5"
|
||||
lodash "^4.17.15"
|
||||
uuid "^8.0.0"
|
||||
yup "^0.29.3"
|
||||
|
||||
"@backstage/catalog-model@^0.3.0":
|
||||
version "0.7.2"
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@backstage/catalog-model/-/catalog-model-0.3.1.tgz#45d08e2f333c9c566b2bf2629fd707fe989bb404"
|
||||
integrity sha512-9XhV7c4rmVW+Yzj2PiwTQ7DsegWGB3C4ELsDRExuEVZONdqNcC02cyJtrt3fT5F31ZS3tHkB9bMUymFOBLqUSA==
|
||||
dependencies:
|
||||
"@backstage/config" "^0.1.3"
|
||||
"@backstage/config" "^0.1.1"
|
||||
"@types/json-schema" "^7.0.5"
|
||||
"@types/yup" "^0.29.8"
|
||||
ajv "^7.0.3"
|
||||
json-schema "^0.2.5"
|
||||
lodash "^4.17.15"
|
||||
uuid "^8.0.0"
|
||||
yup "^0.29.3"
|
||||
|
||||
"@backstage/core@^0.3.0":
|
||||
version "0.6.3"
|
||||
version "0.3.2"
|
||||
resolved "https://registry.npmjs.org/@backstage/core/-/core-0.3.2.tgz#a8209126d5076cf4a8b9bd632fe4e5e2edb62916"
|
||||
integrity sha512-i5d+Wh8js4qEWoAsPY5L7HVSWpumr1OhfF2dUCGYdyW6AMqVJPca6+n6zp1Rg2CO+J9norp44XAVVCbyhtUpig==
|
||||
dependencies:
|
||||
"@backstage/config" "^0.1.3"
|
||||
"@backstage/core-api" "^0.2.11"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@backstage/config" "^0.1.1"
|
||||
"@backstage/core-api" "^0.2.1"
|
||||
"@backstage/theme" "^0.2.1"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
"@material-ui/lab" "4.0.0-alpha.45"
|
||||
"@types/dagre" "^0.7.44"
|
||||
"@types/react" "^16.9"
|
||||
"@types/react-sparklines" "^1.7.0"
|
||||
classnames "^2.2.6"
|
||||
clsx "^1.1.0"
|
||||
d3-selection "^2.0.0"
|
||||
d3-shape "^2.0.0"
|
||||
d3-zoom "^2.0.0"
|
||||
dagre "^0.8.5"
|
||||
immer "^7.0.9"
|
||||
lodash "^4.17.15"
|
||||
material-table "^1.69.1"
|
||||
prop-types "^15.7.2"
|
||||
qs "^6.9.4"
|
||||
rc-progress "^3.0.0"
|
||||
react "^16.12.0"
|
||||
react-dom "^16.12.0"
|
||||
react-helmet "6.1.0"
|
||||
react-hook-form "^6.6.0"
|
||||
react-markdown "^5.0.2"
|
||||
react-router "6.0.0-beta.0"
|
||||
react-router-dom "6.0.0-beta.0"
|
||||
react-sparklines "^1.7.0"
|
||||
react-syntax-highlighter "^13.5.1"
|
||||
react-use "^15.3.3"
|
||||
remark-gfm "^1.0.0"
|
||||
zen-observable "^0.8.15"
|
||||
|
||||
"@backstage/core@^0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.npmjs.org/@backstage/core/-/core-0.5.0.tgz#6ff384adc595c18c7db60b9b2d23ebbb9086ed36"
|
||||
integrity sha512-lCxgKBavUlLYZjZmRF8A7koP4NUhK/tbdf9SaEod0miZg6JTaDoAm3dmHPyqrMBHgoRRCDTxRIxNhj/8vY87oA==
|
||||
dependencies:
|
||||
"@backstage/config" "^0.1.2"
|
||||
"@backstage/core-api" "^0.2.8"
|
||||
"@backstage/theme" "^0.2.2"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
"@material-ui/lab" "4.0.0-alpha.45"
|
||||
@@ -1877,20 +1920,53 @@
|
||||
remark-gfm "^1.0.0"
|
||||
zen-observable "^0.8.15"
|
||||
|
||||
"@backstage/plugin-catalog@^0.2.1":
|
||||
version "0.4.0"
|
||||
"@backstage/plugin-catalog-react@^0.0.2":
|
||||
version "0.0.2"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.0.2.tgz#e50da2dac9fab3a0d5973f8d1083ee2c368e5e52"
|
||||
integrity sha512-O6aujFPRaEFTk4XlwOoswbnoHIOqMtj6ycUj6R1mNKOM4plUgGDKKhO3be69FHMJEMbiSvVe6AW+1kXaK+1LqA==
|
||||
dependencies:
|
||||
"@backstage/catalog-client" "^0.3.5"
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.0"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@types/react" "^16.9"
|
||||
react "^16.13.1"
|
||||
react-router "6.0.0-beta.0"
|
||||
react-router-dom "6.0.0-beta.0"
|
||||
react-use "^15.3.3"
|
||||
|
||||
"@backstage/plugin-catalog-react@^0.0.4":
|
||||
version "0.0.4"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.0.4.tgz#a4c8ba90cf48106ac6af2e03afa6338010a1299b"
|
||||
integrity sha512-1fAqULJvLyE+3SeZ2yxDJnJ3SbUFv2Im55d3KbMgRaSog1chSJJoO3jbIwIRQIBXjRmCXrZbf56qwwWwxj6OjA==
|
||||
dependencies:
|
||||
"@backstage/catalog-client" "^0.3.6"
|
||||
"@backstage/catalog-model" "^0.7.2"
|
||||
"@backstage/core" "^0.6.3"
|
||||
"@backstage/plugin-catalog-react" "^0.1.0"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.2"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@types/react" "^16.9"
|
||||
react "^16.13.1"
|
||||
react-router "6.0.0-beta.0"
|
||||
react-router-dom "6.0.0-beta.0"
|
||||
react-use "^15.3.3"
|
||||
|
||||
"@backstage/plugin-catalog@^0.2.1":
|
||||
version "0.2.14"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-catalog/-/plugin-catalog-0.2.14.tgz#50a4176a55ffa543a426ec78cbc9deaecdbcf2b7"
|
||||
integrity sha512-lDmNcC+m1zbbzYATUp5yIZ5PUp+YyBc1KKu3CCgqjLWSbJ1aJrU1N4g59euel1l2+qSW+lH76Kkp6ZYpZbSO9A==
|
||||
dependencies:
|
||||
"@backstage/catalog-client" "^0.3.5"
|
||||
"@backstage/catalog-model" "^0.7.0"
|
||||
"@backstage/core" "^0.5.0"
|
||||
"@backstage/plugin-scaffolder" "^0.4.1"
|
||||
"@backstage/theme" "^0.2.2"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
"@material-ui/lab" "4.0.0-alpha.45"
|
||||
"@types/react" "^16.9"
|
||||
classnames "^2.2.6"
|
||||
git-url-parse "^11.4.4"
|
||||
moment "^2.26.0"
|
||||
react "^16.13.1"
|
||||
react-dom "^16.13.1"
|
||||
react-helmet "6.1.0"
|
||||
@@ -1900,12 +1976,15 @@
|
||||
swr "^0.3.0"
|
||||
|
||||
"@backstage/plugin-catalog@^0.3.1":
|
||||
version "0.4.0"
|
||||
version "0.3.2"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-catalog/-/plugin-catalog-0.3.2.tgz#06945f10fd678efdade3f2795590c12433568fa0"
|
||||
integrity sha512-iHLxPHRN9nYIXwOEAQ06m+PagsFb6Nb/XjJSebCAnSrAxPPITvBCfxc2H1GbyyMdC7KAr1ozORB/FFkNsCaQJg==
|
||||
dependencies:
|
||||
"@backstage/catalog-client" "^0.3.6"
|
||||
"@backstage/catalog-model" "^0.7.2"
|
||||
"@backstage/core" "^0.6.3"
|
||||
"@backstage/plugin-catalog-react" "^0.1.0"
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.2"
|
||||
"@backstage/plugin-catalog-react" "^0.0.4"
|
||||
"@backstage/plugin-scaffolder" "^0.5.1"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
@@ -1946,6 +2025,56 @@
|
||||
react-use "^15.3.3"
|
||||
swr "^0.3.0"
|
||||
|
||||
"@backstage/plugin-scaffolder@^0.4.1":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-scaffolder/-/plugin-scaffolder-0.4.2.tgz#58159227997f7e248ce52535bc32f19fcd0990dc"
|
||||
integrity sha512-YuyHM587Rqg6KufxfFqQdI7dsZniBM/11Aj8Q0m5ZszOpCuNmDDkR1VX8MKHTBJ709mnLAqRgArdla7FOrOAXQ==
|
||||
dependencies:
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.0"
|
||||
"@backstage/plugin-catalog-react" "^0.0.2"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
"@material-ui/lab" "4.0.0-alpha.45"
|
||||
"@rjsf/core" "^2.4.0"
|
||||
"@rjsf/material-ui" "^2.4.0"
|
||||
classnames "^2.2.6"
|
||||
git-url-parse "^11.4.4"
|
||||
moment "^2.26.0"
|
||||
react "^16.13.1"
|
||||
react-dom "^16.13.1"
|
||||
react-lazylog "^4.5.2"
|
||||
react-router "6.0.0-beta.0"
|
||||
react-router-dom "6.0.0-beta.0"
|
||||
react-use "^15.3.3"
|
||||
swr "^0.3.0"
|
||||
|
||||
"@backstage/plugin-scaffolder@^0.5.1":
|
||||
version "0.5.1"
|
||||
resolved "https://registry.npmjs.org/@backstage/plugin-scaffolder/-/plugin-scaffolder-0.5.1.tgz#9d36f6b01991ddd9f9f2996068f3f31c766db8db"
|
||||
integrity sha512-EG+iUc107bneVBPQpFKGp2jD9Y9+x50g/gY6TBN1je8TkgyluoxMj7wKv9e+d4TeGzXwK/LW/suajG9Zo0TJGQ==
|
||||
dependencies:
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.2"
|
||||
"@backstage/plugin-catalog-react" "^0.0.4"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
"@material-ui/lab" "4.0.0-alpha.45"
|
||||
"@rjsf/core" "^2.4.0"
|
||||
"@rjsf/material-ui" "^2.4.0"
|
||||
classnames "^2.2.6"
|
||||
git-url-parse "^11.4.4"
|
||||
moment "^2.26.0"
|
||||
react "^16.13.1"
|
||||
react-dom "^16.13.1"
|
||||
react-lazylog "^4.5.2"
|
||||
react-router "6.0.0-beta.0"
|
||||
react-router-dom "6.0.0-beta.0"
|
||||
react-use "^15.3.3"
|
||||
swr "^0.3.0"
|
||||
|
||||
"@bcoe/v8-coverage@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
@@ -15076,6 +15205,11 @@ immer@1.10.0:
|
||||
resolved "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
|
||||
integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==
|
||||
|
||||
immer@^7.0.9:
|
||||
version "7.0.15"
|
||||
resolved "https://registry.npmjs.org/immer/-/immer-7.0.15.tgz#dc3bc6db87401659d2e737c67a21b227c484a4ad"
|
||||
integrity sha512-yM7jo9+hvYgvdCQdqvhCNRRio0SCXc8xDPzA25SvKWa7b1WVPjLwQs1VYU5JPXjcJPTqAa5NP5dqpORGYBQ2AA==
|
||||
|
||||
immer@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
|
||||
@@ -18630,7 +18764,7 @@ modify-values@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
||||
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
|
||||
|
||||
moment@^2.19.3, moment@^2.25.3, moment@^2.27.0:
|
||||
moment@^2.19.3, moment@^2.25.3, moment@^2.26.0, moment@^2.27.0:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
@@ -24025,6 +24159,11 @@ stream-http@^2.7.2:
|
||||
to-arraybuffer "^1.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
stream-mock@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/stream-mock/-/stream-mock-2.0.5.tgz#c99d24bd6dbb0eaa57cf6ffefdb064150747826e"
|
||||
integrity sha512-dx9skT8QYjwLsal+MhGHr4UtgS49brw851C/oTixmhCi4Ip+/qnZmhV1qOcznYYAED6gYKmKea+jjza4/wjpSg==
|
||||
|
||||
stream-shift@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||
|
||||
Reference in New Issue
Block a user