diff --git a/packages/techdocs-cli-embedded-app/app-config.yaml b/packages/techdocs-cli-embedded-app/app-config.yaml
index 56e63ff97c..6ede05b587 100644
--- a/packages/techdocs-cli-embedded-app/app-config.yaml
+++ b/packages/techdocs-cli-embedded-app/app-config.yaml
@@ -7,4 +7,3 @@ backend:
techdocs:
builder: 'external'
- requestUrl: http://localhost:3000/api
diff --git a/packages/techdocs-cli-embedded-app/src/apis.ts b/packages/techdocs-cli-embedded-app/src/apis.ts
index 1fe6ba8086..d230a9f83c 100644
--- a/packages/techdocs-cli-embedded-app/src/apis.ts
+++ b/packages/techdocs-cli-embedded-app/src/apis.ts
@@ -64,17 +64,11 @@ class TechDocsDevStorageApi implements TechDocsStorageApi {
}
async getApiOrigin() {
- return (
- this.configApi.getOptionalString('techdocs.requestUrl') ??
- (await this.discoveryApi.getBaseUrl('techdocs'))
- );
+ return await this.discoveryApi.getBaseUrl('techdocs');
}
async getStorageUrl() {
- return (
- this.configApi.getOptionalString('techdocs.storageUrl') ??
- `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs`
- );
+ return `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs`;
}
async getBuilder() {
@@ -134,10 +128,7 @@ class TechDocsDevApi implements TechDocsApi {
}
async getApiOrigin() {
- return (
- this.configApi.getOptionalString('techdocs.requestUrl') ??
- (await this.discoveryApi.getBaseUrl('techdocs'))
- );
+ return await this.discoveryApi.getBaseUrl('techdocs');
}
async getEntityMetadata(_entityId: any) {
diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
index f2dcefc00e..56686dd081 100644
--- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
+++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
@@ -35,8 +35,8 @@ import { Content } from '@backstage/core-components';
import {
Reader,
- TechDocsPage,
- TechDocsPageHeader,
+ TechDocsReaderPage,
+ TechDocsReaderPageHeader,
} from '@backstage/plugin-techdocs';
const useStyles = makeStyles((theme: Theme) => ({
@@ -146,19 +146,19 @@ const DefaultTechDocsPage = () => {
};
return (
-
+
{({ entityRef, onReady }) => (
<>
-
-
+
>
)}
-
+
);
};
diff --git a/packages/techdocs-cli-embedded-app/src/config.ts b/packages/techdocs-cli-embedded-app/src/config.ts
index 482ceb41ec..ae801dac2a 100644
--- a/packages/techdocs-cli-embedded-app/src/config.ts
+++ b/packages/techdocs-cli-embedded-app/src/config.ts
@@ -22,7 +22,6 @@ const PRODUCTION_CONFIG = {
},
techdocs: {
builder: 'external',
- requestUrl: 'http://localhost:3000/api',
},
};
@@ -32,7 +31,6 @@ const DEVELOPMENT_CONFIG = {
},
techdocs: {
builder: 'external',
- requestUrl: 'http://localhost:7007/api',
},
};
diff --git a/plugins/techdocs-backend/src/service/router.test.ts b/plugins/techdocs-backend/src/service/router.test.ts
index 2e707c9513..f3f9892f44 100644
--- a/plugins/techdocs-backend/src/service/router.test.ts
+++ b/plugins/techdocs-backend/src/service/router.test.ts
@@ -21,7 +21,6 @@ import {
PluginEndpointDiscovery,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
-import { NotModifiedError } from '@backstage/errors';
import {
GeneratorBuilder,
PreparerBuilder,
@@ -31,12 +30,7 @@ import express, { Response } from 'express';
import request from 'supertest';
import { DocsSynchronizer, DocsSynchronizerSyncOpts } from './DocsSynchronizer';
import { CachedEntityLoader } from './CachedEntityLoader';
-import {
- createEventStream,
- createHttpResponse,
- createRouter,
- RouterOptions,
-} from './router';
+import { createEventStream, createRouter, RouterOptions } from './router';
import { TechDocsCache } from '../cache';
import { DocsBuildStrategy } from './DocsBuildStrategy';
@@ -160,120 +154,6 @@ describe('createRouter', () => {
});
describe('GET /sync/:namespace/:kind/:name', () => {
- describe('accept application/json', () => {
- it('should return not found if entity is not found', async () => {
- const app = await createApp(outOfTheBoxOptions);
-
- MockCachedEntityLoader.prototype.load.mockResolvedValue(undefined);
-
- const response = await request(app)
- .get('/sync/default/Component/test')
- .send();
-
- expect(response.status).toBe(404);
- });
-
- it('should return not found if entity has no uid', async () => {
- const app = await createApp(outOfTheBoxOptions);
-
- MockCachedEntityLoader.prototype.load.mockResolvedValue(
- entityWithoutMetadata,
- );
-
- const response = await request(app)
- .get('/sync/default/Component/test')
- .send();
-
- expect(response.status).toBe(404);
- });
-
- it('should not check for an update when shouldBuild returns false', async () => {
- const app = await createApp(outOfTheBoxOptions);
-
- docsBuildStrategy.shouldBuild.mockResolvedValue(false);
- MockCachedEntityLoader.prototype.load.mockResolvedValue(entity);
- MockDocsSynchronizer.prototype.doCacheSync.mockImplementation(
- async ({ responseHandler }) =>
- responseHandler.finish({ updated: false }),
- );
-
- const response = await request(app)
- .get('/sync/default/Component/test')
- .send();
-
- expect(response.status).toBe(304);
- });
-
- it('should error if build is required and is missing preparer', async () => {
- const app = await createApp(recommendedOptions);
-
- docsBuildStrategy.shouldBuild.mockResolvedValue(true);
- MockCachedEntityLoader.prototype.load.mockResolvedValue(entity);
-
- const response = await request(app)
- .get('/sync/default/Component/test')
- .send();
-
- expect(response.status).toBe(500);
- expect(response.text).toMatch(
- /Invalid configuration\. docsBuildStrategy\.shouldBuild returned 'true', but no 'preparer' was provided to the router initialization./,
- );
-
- expect(MockDocsSynchronizer.prototype.doSync).toBeCalledTimes(0);
- });
-
- it('should execute synchronization', async () => {
- const app = await createApp(outOfTheBoxOptions);
-
- docsBuildStrategy.shouldBuild.mockResolvedValue(true);
- MockCachedEntityLoader.prototype.load.mockResolvedValue(entity);
- MockDocsSynchronizer.prototype.doSync.mockImplementation(
- async ({ responseHandler }) =>
- responseHandler.finish({ updated: true }),
- );
-
- await request(app).get('/sync/default/Component/test').send();
-
- expect(MockDocsSynchronizer.prototype.doSync).toBeCalledTimes(1);
- expect(MockDocsSynchronizer.prototype.doSync).toBeCalledWith({
- responseHandler: {
- log: expect.any(Function),
- error: expect.any(Function),
- finish: expect.any(Function),
- },
- entity,
- generators,
- preparers,
- });
- });
-
- it('should return on updated', async () => {
- const app = await createApp(outOfTheBoxOptions);
-
- docsBuildStrategy.shouldBuild.mockResolvedValue(true);
- MockCachedEntityLoader.prototype.load.mockResolvedValue(entity);
- MockDocsSynchronizer.prototype.doSync.mockImplementation(
- async ({ responseHandler }) => {
- const { log, finish } = responseHandler;
-
- log('Some log');
-
- finish({ updated: true });
- },
- );
-
- const response = await request(app)
- .get('/sync/default/Component/test')
- .send();
-
- expect(response.status).toBe(201);
- expect(response.get('content-type')).toMatch(/application\/json/);
- expect(response.text).toEqual(
- '{"message":"Docs updated or did not need updating"}',
- );
- });
- });
-
describe('accept text/event-stream', () => {
it('should return not found if entity is not found', async () => {
const app = await createApp(outOfTheBoxOptions);
@@ -559,48 +439,3 @@ data: {"updated":true}
expect(res.end).toBeCalledTimes(1);
});
});
-
-describe('createHttpResponse', () => {
- const res: jest.Mocked = {
- status: jest.fn(),
- json: jest.fn(),
- } as any;
-
- let handlers: DocsSynchronizerSyncOpts;
-
- beforeEach(() => {
- res.status.mockImplementation(() => res);
- handlers = createHttpResponse(res);
- });
- afterEach(() => {
- jest.resetAllMocks();
- });
-
- it('should return CREATED if updated', async () => {
- handlers.finish({ updated: true });
-
- expect(res.status).toBeCalledTimes(1);
- expect(res.status).toBeCalledWith(201);
-
- expect(res.json).toBeCalledTimes(1);
- expect(res.json).toBeCalledWith({
- message: 'Docs updated or did not need updating',
- });
- });
-
- it('should return NOT_MODIFIED if not updated', async () => {
- expect(() => handlers.finish({ updated: false })).toThrowError(
- NotModifiedError,
- );
- });
-
- it('should throw custom error', async () => {
- expect(() => handlers.error(new Error('Some Error'))).toThrowError(
- /Some Error/,
- );
- });
-
- it('should ignore logs', async () => {
- expect(() => handlers.log('Some Message')).not.toThrow();
- });
-});
diff --git a/plugins/techdocs-backend/src/service/standaloneServer.ts b/plugins/techdocs-backend/src/service/standaloneServer.ts
index 4ab4c084e0..f0ee42ba4a 100644
--- a/plugins/techdocs-backend/src/service/standaloneServer.ts
+++ b/plugins/techdocs-backend/src/service/standaloneServer.ts
@@ -60,11 +60,10 @@ export async function startStandaloneServer(
logger.debug('Creating application...');
const preparers = new Preparers();
- const directoryPreparer = new DirectoryPreparer(
- config,
+ const directoryPreparer = DirectoryPreparer.fromConfig(config, {
logger,
- mockUrlReader,
- );
+ reader: mockUrlReader,
+ });
preparers.register('dir', directoryPreparer);
const dockerClient = new Docker();
diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts
index 326e587a83..537fc52b27 100644
--- a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts
+++ b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts
@@ -54,7 +54,6 @@ const createPublisherFromConfig = ({
} = {}) => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'awsS3',
awsS3: {
diff --git a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts
index 3e5e420e4b..7af5338d88 100644
--- a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts
+++ b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts
@@ -51,7 +51,6 @@ const createPublisherFromConfig = ({
} = {}) => {
const config = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'azureBlobStorage',
azureBlobStorage: {
diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts
index 6dac092cec..6471d89a06 100644
--- a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts
+++ b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts
@@ -52,7 +52,6 @@ const createPublisherFromConfig = ({
} = {}) => {
const config = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'googleGcs',
googleGcs: {
diff --git a/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts b/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts
index aeb4e120f5..619431fdd7 100644
--- a/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts
+++ b/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts
@@ -84,7 +84,6 @@ beforeEach(() => {
mockFs.restore();
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'openStackSwift',
openStackSwift: {
@@ -114,7 +113,6 @@ describe('OpenStackSwiftPublish', () => {
it('should reject incorrect config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'openStackSwift',
openStackSwift: {
diff --git a/plugins/techdocs-node/src/stages/publish/publish.test.ts b/plugins/techdocs-node/src/stages/publish/publish.test.ts
index a47da828a7..4537313edf 100644
--- a/plugins/techdocs-node/src/stages/publish/publish.test.ts
+++ b/plugins/techdocs-node/src/stages/publish/publish.test.ts
@@ -37,11 +37,7 @@ describe('Publisher', () => {
});
it('should create local publisher by default', async () => {
- const mockConfig = new ConfigReader({
- techdocs: {
- requestUrl: 'http://localhost:7007',
- },
- });
+ const mockConfig = new ConfigReader({});
const publisher = await Publisher.fromConfig(mockConfig, {
logger,
@@ -53,7 +49,6 @@ describe('Publisher', () => {
it('should create local publisher from config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'local',
},
@@ -70,7 +65,6 @@ describe('Publisher', () => {
it('should create google gcs publisher from config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'googleGcs',
googleGcs: {
@@ -91,7 +85,6 @@ describe('Publisher', () => {
it('should create AWS S3 publisher from config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'awsS3',
awsS3: {
@@ -115,7 +108,6 @@ describe('Publisher', () => {
it('should create Azure Blob Storage publisher from config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'azureBlobStorage',
azureBlobStorage: {
@@ -143,7 +135,6 @@ describe('Publisher', () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'azureBlobStorage',
azureBlobStorage: {
@@ -166,7 +157,6 @@ describe('Publisher', () => {
it('should create Open Stack Swift publisher from config', async () => {
const mockConfig = new ConfigReader({
techdocs: {
- requestUrl: 'http://localhost:7007',
publisher: {
type: 'openStackSwift',
openStackSwift: {
diff --git a/plugins/techdocs/src/client.test.ts b/plugins/techdocs/src/client.test.ts
index a88c724cc8..71ad57d12a 100644
--- a/plugins/techdocs/src/client.test.ts
+++ b/plugins/techdocs/src/client.test.ts
@@ -35,9 +35,7 @@ const mockEntity = {
describe('TechDocsStorageClient', () => {
const mockBaseUrl = 'http://backstage:9191/api/techdocs';
- const configApi = new MockConfigApi({
- techdocs: { requestUrl: 'http://backstage:9191/api/techdocs' },
- });
+ const configApi = new MockConfigApi({});
const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl);
const identityApi: jest.Mocked = {
getCredentials: jest.fn(),
diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage.tsx
index ff44d429df..1bfd0e6f51 100644
--- a/plugins/techdocs/src/reader/components/TechDocsReaderPage.tsx
+++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage.tsx
@@ -18,11 +18,13 @@ import React, { useCallback, useState } from 'react';
import { useOutlet } from 'react-router';
import { useParams } from 'react-router-dom';
import useAsync from 'react-use/lib/useAsync';
+import { Reader } from './Reader';
+import { TechDocsReaderPageHeader } from './TechDocsReaderPageHeader';
import { techdocsApiRef } from '../../api';
import { TechDocsEntityMetadata, TechDocsMetadata } from '../../types';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { useApi, useApp } from '@backstage/core-plugin-api';
-import { Page } from '@backstage/core-components';
+import { Page, Content } from '@backstage/core-components';
/**
* Helper function that gives the children of {@link TechDocsReaderPage} access to techdocs and entity metadata
@@ -78,7 +80,32 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {
if (entityMetadataError) return ;
- if (!children) return outlet;
+ if (!children)
+ return (
+ outlet || (
+
+
+
+
+
+
+ )
+ );
return (