feature(home-plugin): Use static methods on Api classes

Confirming with the style guide:
7.Keep constructors private, prefer static factory methods for creating instances.

Signed-off-by: Renan Mendes Carvalho <aitherios@gmail.com>
This commit is contained in:
Renan Mendes Carvalho
2023-08-30 17:23:31 +02:00
committed by Camila Belo
parent 6cfcf8a4a7
commit b53d3537dd
6 changed files with 77 additions and 58 deletions
+30 -29
View File
@@ -78,19 +78,18 @@ export const ComponentTabs: (props: {
// @public
export class CoreStorageVisitsApi extends VisitsApiFactory {
constructor({
storageApi,
identityApi,
randomUUID,
limit,
}: {
storageApi: StorageApi;
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
});
// (undocumented)
static create(options: CoreStorageVisitsApiOptions): CoreStorageVisitsApi;
}
// @public (undocumented)
export type CoreStorageVisitsApiOptions = {
storageApi: StorageApi;
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
};
// @public @deprecated (undocumented)
export const createCardExtension: typeof createCardExtension_2;
@@ -180,19 +179,18 @@ export type LayoutConfiguration = {
// @public
export class LocalStorageVisitsApi extends VisitsApiFactory {
constructor({
localStorage,
randomUUID,
limit,
identityApi,
}: {
localStorage?: Window['localStorage'];
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
});
// (undocumented)
static create(options: LocalStorageVisitsApiOptions): LocalStorageVisitsApi;
}
// @public (undocumented)
export type LocalStorageVisitsApiOptions = {
localStorage?: Window['localStorage'];
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
};
// @public @deprecated (undocumented)
export type RendererProps = RendererProps_2;
@@ -270,17 +268,12 @@ export interface VisitsApi {
// @public
export class VisitsApiFactory implements VisitsApi {
constructor({
protected constructor({
randomUUID,
limit,
retrieveAll,
persistAll,
}: {
randomUUID: Window['crypto']['randomUUID'];
limit: number;
retrieveAll?: () => Promise<Array<Visit>>;
persistAll?: (visits: Array<Visit>) => Promise<void>;
});
}: VisitsApiFactoryOptions);
// (undocumented)
protected readonly limit: number;
// (undocumented)
@@ -295,6 +288,14 @@ export class VisitsApiFactory implements VisitsApi {
saveVisit(saveParams: VisitsApiSaveParams): Promise<Visit>;
}
// @public (undocumented)
export type VisitsApiFactoryOptions = {
randomUUID: Window['crypto']['randomUUID'];
limit: number;
retrieveAll?: () => Promise<Array<Visit>>;
persistAll?: (visits: Array<Visit>) => Promise<void>;
};
// @public
export type VisitsApiQueryParams = {
limit?: number;
@@ -18,7 +18,7 @@ import { BackstageUserIdentity, IdentityApi } from '@backstage/core-plugin-api';
import { CoreStorageVisitsApi } from './CoreStorageVisitsApi';
import { MockStorageApi } from '@backstage/test-utils';
describe('new CoreStorageVisitsApi({ storageApi: MockStorageApi.create() })', () => {
describe('CoreStorageVisitsApi.create({ storageApi: MockStorageApi.create() })', () => {
const mockRandomUUID = () =>
'068f3129-7440-4e0e-8fd4-xxxxxxxxxxxx'.replace(
/x/g,
@@ -42,7 +42,7 @@ describe('new CoreStorageVisitsApi({ storageApi: MockStorageApi.create() })', ()
});
it('instantiates', () => {
const api = new CoreStorageVisitsApi({
const api = CoreStorageVisitsApi.create({
storageApi: MockStorageApi.create(),
identityApi: mockIdentityApi,
});
@@ -50,7 +50,7 @@ describe('new CoreStorageVisitsApi({ storageApi: MockStorageApi.create() })', ()
});
it('saves a visit', async () => {
const api = new CoreStorageVisitsApi({
const api = CoreStorageVisitsApi.create({
storageApi: MockStorageApi.create(),
identityApi: mockIdentityApi,
});
@@ -67,7 +67,7 @@ describe('new CoreStorageVisitsApi({ storageApi: MockStorageApi.create() })', ()
});
it('retrieves visits', async () => {
const api = new CoreStorageVisitsApi({
const api = CoreStorageVisitsApi.create({
storageApi: MockStorageApi.create(),
identityApi: mockIdentityApi,
});
+14 -7
View File
@@ -17,6 +17,14 @@ import { IdentityApi, StorageApi } from '@backstage/core-plugin-api';
import { Visit } from './VisitsApi';
import { VisitsApiFactory } from './VisitsApiFactory';
/** @public */
export type CoreStorageVisitsApiOptions = {
storageApi: StorageApi;
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
};
/**
* @public
* This is an implementation of VisitsApi that relies on a StorageApi
@@ -26,17 +34,16 @@ export class CoreStorageVisitsApi extends VisitsApiFactory {
private readonly storageKeyPrefix = '@backstage/plugin-home:visits';
private readonly identityApi: IdentityApi;
constructor({
static create(options: CoreStorageVisitsApiOptions) {
return new CoreStorageVisitsApi(options);
}
private constructor({
storageApi,
identityApi,
randomUUID = window?.crypto?.randomUUID,
limit = 100,
}: {
storageApi: StorageApi;
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
}) {
}: CoreStorageVisitsApiOptions) {
super({ randomUUID, limit });
this.storageApi = storageApi;
this.identityApi = identityApi;
@@ -17,7 +17,7 @@
import { BackstageUserIdentity, IdentityApi } from '@backstage/core-plugin-api';
import { LocalStorageVisitsApi } from './LocalStorageVisitsApi';
describe('new LocalStorageVisitsApi()', () => {
describe('LocalStorageVisitsApi.create()', () => {
const mockRandomUUID = () =>
'068f3129-7440-4e0e-8fd4-xxxxxxxxxxxx'.replace(
/x/g,
@@ -42,12 +42,12 @@ describe('new LocalStorageVisitsApi()', () => {
});
it('instantiates with only identitiyApi', () => {
const api = new LocalStorageVisitsApi({ identityApi: mockIdentityApi });
const api = LocalStorageVisitsApi.create({ identityApi: mockIdentityApi });
expect(api).toBeTruthy();
});
it('saves a visit', async () => {
const api = new LocalStorageVisitsApi({ identityApi: mockIdentityApi });
const api = LocalStorageVisitsApi.create({ identityApi: mockIdentityApi });
const visit = {
pathname: '/catalog/default/component/playback-order',
entityRef: 'component:default/playback-order',
@@ -61,7 +61,7 @@ describe('new LocalStorageVisitsApi()', () => {
});
it('retrieves visits', async () => {
const api = new LocalStorageVisitsApi({ identityApi: mockIdentityApi });
const api = LocalStorageVisitsApi.create({ identityApi: mockIdentityApi });
const visit = {
pathname: '/catalog/default/component/playback-order',
entityRef: 'component:default/playback-order',
+14 -7
View File
@@ -17,6 +17,14 @@ import { IdentityApi } from '@backstage/core-plugin-api';
import { Visit } from './VisitsApi';
import { VisitsApiFactory } from './VisitsApiFactory';
/** @public */
export type LocalStorageVisitsApiOptions = {
localStorage?: Window['localStorage'];
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
};
/**
* @public
* This is a reference implementation of VisitsApi using window.localStorage.
@@ -26,17 +34,16 @@ export class LocalStorageVisitsApi extends VisitsApiFactory {
private readonly storageKeyPrefix = '@backstage/plugin-home:visits';
private readonly identityApi: IdentityApi;
constructor({
static create(options: LocalStorageVisitsApiOptions) {
return new LocalStorageVisitsApi(options);
}
private constructor({
localStorage = window?.localStorage,
randomUUID = window?.crypto?.randomUUID,
limit = 100,
identityApi,
}: {
localStorage?: Window['localStorage'];
randomUUID?: Window['crypto']['randomUUID'];
limit?: number;
identityApi: IdentityApi;
}) {
}: LocalStorageVisitsApiOptions) {
super({ randomUUID, limit });
this.localStorage = localStorage;
this.identityApi = identityApi;
+11 -7
View File
@@ -17,6 +17,14 @@ import { Visit, VisitsApi, VisitsApiQueryParams, VisitsApiSaveParams } from './V
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
/** @public */
export type VisitsApiFactoryOptions = {
randomUUID: Window['crypto']['randomUUID'];
limit: number;
retrieveAll?: () => Promise<Array<Visit>>;
persistAll?: (visits: Array<Visit>) => Promise<void>;
};
/**
* @public
* This helps the creation of VisitApi implementations. Important to note
@@ -30,17 +38,12 @@ export class VisitsApiFactory implements VisitsApi {
protected retrieveAll: () => Promise<Array<Visit>>;
protected persistAll: (visits: Array<Visit>) => Promise<void>;
constructor({
protected constructor({
randomUUID = window?.crypto?.randomUUID,
limit = 100,
retrieveAll,
persistAll,
}: {
randomUUID: Window['crypto']['randomUUID'];
limit: number;
retrieveAll?: () => Promise<Array<Visit>>;
persistAll?: (visits: Array<Visit>) => Promise<void>;
}) {
}: VisitsApiFactoryOptions) {
this.randomUUID = randomUUID;
this.limit = Math.abs(limit);
this.retrieveAll = retrieveAll ?? (async () => []);
@@ -59,6 +62,7 @@ export class VisitsApiFactory implements VisitsApi {
}
});
// reversing order to guarantee filterBy priority
(queryParams?.filterBy ?? []).reverse().forEach(filter => {
visits = visits.filter(visit => {
const field = visit[filter.field] as number | string;