chore(catalog): rename all pages and components to use Entity nomenclature
This commit is contained in:
@@ -20,7 +20,6 @@ import {
|
||||
LOCATION_ANNOTATION,
|
||||
} from '@backstage/catalog-model';
|
||||
import Cache from 'node-cache';
|
||||
import { DescriptorEnvelope } from '../types';
|
||||
import { CatalogApi, EntityCompoundName } from './types';
|
||||
|
||||
export class CatalogClient implements CatalogApi {
|
||||
@@ -77,10 +76,8 @@ export class CatalogClient implements CatalogApi {
|
||||
return await this.getOptional(`/locations/${id}`);
|
||||
}
|
||||
|
||||
async getEntities(
|
||||
filter?: Record<string, string>,
|
||||
): Promise<DescriptorEnvelope[]> {
|
||||
const cachedValue = this.cache.get<DescriptorEnvelope[]>(
|
||||
async getEntities(filter?: Record<string, string>): Promise<Entity[]> {
|
||||
const cachedValue = this.cache.get<Entity[]>(
|
||||
`get:${JSON.stringify(filter)}`,
|
||||
);
|
||||
if (cachedValue) return cachedValue;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createApiRef } from '@backstage/core';
|
||||
import { Entity, Location } from '@backstage/catalog-model';
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useApi } from '@backstage/core';
|
||||
import { catalogApiRef } from '../../api/types';
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
Card,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useStarredEntities } from '../../hooks/useStarredEntites';
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ export const CatalogPage: FC<{}> = () => {
|
||||
>
|
||||
Create Service
|
||||
</Button>
|
||||
<SupportButton>All your components</SupportButton>
|
||||
<SupportButton>All your software catalog entities</SupportButton>
|
||||
</ContentHeader>
|
||||
<div className={styles.contentWrapper}>
|
||||
<div>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
@@ -50,12 +51,12 @@ describe('CatalogTable component', () => {
|
||||
),
|
||||
);
|
||||
const errorMessage = await rendered.findByText(
|
||||
/Error encountered while fetching components./,
|
||||
/Error encountered while fetching catalog entities./,
|
||||
);
|
||||
expect(errorMessage).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display component names when loading has finished and no error occurred', async () => {
|
||||
it('should display entity names when loading has finished and no error occurred', async () => {
|
||||
const rendered = render(
|
||||
wrapInTestApp(
|
||||
<CatalogTable
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Table, TableColumn } from '@backstage/core';
|
||||
import { Link } from '@material-ui/core';
|
||||
@@ -72,7 +73,7 @@ export const CatalogTable: FC<CatalogTableProps> = ({
|
||||
return (
|
||||
<div>
|
||||
<Alert severity="error">
|
||||
Error encountered while fetching components. {error.toString()}
|
||||
Error encountered while fetching catalog entities. {error.toString()}
|
||||
</Alert>
|
||||
</div>
|
||||
);
|
||||
|
||||
+7
-6
@@ -13,21 +13,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ComponentContextMenu } from './ComponentContextMenu';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { EntityContextMenu } from './EntityContextMenu';
|
||||
|
||||
describe('ComponentContextMenu', () => {
|
||||
it('should call onUnregisterComponent on button click', async () => {
|
||||
it('should call onUnregisterEntity on button click', async () => {
|
||||
await act(async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const menu = render(
|
||||
<ComponentContextMenu onUnregisterComponent={mockCallback} />,
|
||||
<EntityContextMenu onUnregisterEntity={mockCallback} />,
|
||||
);
|
||||
const button = await menu.findByTestId('menu-button');
|
||||
button.click();
|
||||
const unregister = await menu.findByText('Unregister component');
|
||||
fireEvent.click(button);
|
||||
const unregister = await menu.findByText('Unregister entity');
|
||||
expect(unregister).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
+8
-9
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
ListItemIcon,
|
||||
@@ -34,13 +35,11 @@ const useStyles = makeStyles({
|
||||
},
|
||||
});
|
||||
|
||||
type ComponentContextMenuProps = {
|
||||
onUnregisterComponent: () => void;
|
||||
type Props = {
|
||||
onUnregisterEntity: () => void;
|
||||
};
|
||||
|
||||
export const ComponentContextMenu: FC<ComponentContextMenuProps> = ({
|
||||
onUnregisterComponent,
|
||||
}) => {
|
||||
export const EntityContextMenu: FC<Props> = ({ onUnregisterEntity }) => {
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();
|
||||
const classes = useStyles();
|
||||
|
||||
@@ -53,7 +52,7 @@ export const ComponentContextMenu: FC<ComponentContextMenuProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
@@ -75,13 +74,13 @@ export const ComponentContextMenu: FC<ComponentContextMenuProps> = ({
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onUnregisterComponent();
|
||||
onUnregisterEntity();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<Cancel fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<Typography variant="inherit">Unregister component</Typography>
|
||||
<Typography variant="inherit">Unregister entity</Typography>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<ListItemIcon>
|
||||
@@ -91,6 +90,6 @@ export const ComponentContextMenu: FC<ComponentContextMenuProps> = ({
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Popover>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+5
-6
@@ -13,21 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { ComponentMetadataCard } from './ComponentMetadataCard';
|
||||
import { EntityMetadataCard } from './EntityMetadataCard';
|
||||
|
||||
describe('ComponentMetadataCard component', () => {
|
||||
it('should display component name if provided', async () => {
|
||||
describe('EntityMetadataCard component', () => {
|
||||
it('should display entity name if provided', async () => {
|
||||
const testEntity: Entity = {
|
||||
apiVersion: 'backstage.io/v1beta1',
|
||||
kind: 'Component',
|
||||
metadata: { name: 'test' },
|
||||
};
|
||||
const rendered = await render(
|
||||
<ComponentMetadataCard entity={testEntity} />,
|
||||
);
|
||||
const rendered = await render(<EntityMetadataCard entity={testEntity} />);
|
||||
expect(await rendered.findByText('test')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
+2
-1
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { InfoCard, StructuredMetadataTable } from '@backstage/core';
|
||||
import React, { FC } from 'react';
|
||||
@@ -21,7 +22,7 @@ type Props = {
|
||||
entity: Entity;
|
||||
};
|
||||
|
||||
export const ComponentMetadataCard: FC<Props> = ({ entity }) => (
|
||||
export const EntityMetadataCard: FC<Props> = ({ entity }) => (
|
||||
<InfoCard title="Metadata">
|
||||
<StructuredMetadataTable metadata={entity.metadata} />
|
||||
</InfoCard>
|
||||
+8
-7
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ComponentPage } from './ComponentPage';
|
||||
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { render, wait } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
import { catalogApiRef, CatalogApi } from '../../api/types';
|
||||
import { CatalogApi, catalogApiRef } from '../../api/types';
|
||||
import { EntityPage } from './EntityPage';
|
||||
|
||||
const getTestProps = (name: string) => {
|
||||
return {
|
||||
@@ -36,8 +37,8 @@ const getTestProps = (name: string) => {
|
||||
|
||||
const errorApi = { post: () => {} };
|
||||
|
||||
describe('ComponentPage', () => {
|
||||
it('should redirect to component table page when name is not provided', async () => {
|
||||
describe('EntityPage', () => {
|
||||
it('should redirect to catalog page when name is not provided', async () => {
|
||||
const props = getTestProps('');
|
||||
render(
|
||||
wrapInTestApp(
|
||||
@@ -52,7 +53,7 @@ describe('ComponentPage', () => {
|
||||
],
|
||||
])}
|
||||
>
|
||||
<ComponentPage {...props} />
|
||||
<EntityPage {...props} />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
+9
-11
@@ -31,13 +31,13 @@ import { Alert } from '@material-ui/lab';
|
||||
import React, { FC, useEffect, useState } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
import { catalogApiRef } from '../..';
|
||||
import { ComponentContextMenu } from '../ComponentContextMenu/ComponentContextMenu';
|
||||
import { ComponentMetadataCard } from '../ComponentMetadataCard/ComponentMetadataCard';
|
||||
import { ComponentRemovalDialog } from '../ComponentRemovalDialog/ComponentRemovalDialog';
|
||||
import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';
|
||||
import { EntityMetadataCard } from '../EntityMetadataCard/EntityMetadataCard';
|
||||
import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog';
|
||||
|
||||
const REDIRECT_DELAY = 1000;
|
||||
|
||||
type ComponentPageProps = {
|
||||
type Props = {
|
||||
match: {
|
||||
params: {
|
||||
optionalNamespaceAndName: string;
|
||||
@@ -68,7 +68,7 @@ function headerProps(
|
||||
};
|
||||
}
|
||||
|
||||
export const ComponentPage: FC<ComponentPageProps> = ({ match, history }) => {
|
||||
export const EntityPage: FC<Props> = ({ match, history }) => {
|
||||
const { optionalNamespaceAndName, kind } = match.params;
|
||||
const [name, namespace] = optionalNamespaceAndName.split(':').reverse();
|
||||
|
||||
@@ -83,7 +83,7 @@ export const ComponentPage: FC<ComponentPageProps> = ({ match, history }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!error && !loading && !entity) {
|
||||
errorApi.post(new Error('Component not found!'));
|
||||
errorApi.post(new Error('Entity not found!'));
|
||||
setTimeout(() => {
|
||||
history.push('/');
|
||||
}, REDIRECT_DELAY);
|
||||
@@ -141,9 +141,7 @@ export const ComponentPage: FC<ComponentPageProps> = ({ match, history }) => {
|
||||
// TODO: Switch theme and type props based on component type (website, library, ...)
|
||||
<Page theme={pageTheme.service}>
|
||||
<Header title={headerTitle} type={headerType}>
|
||||
{entity && (
|
||||
<ComponentContextMenu onUnregisterComponent={showRemovalDialog} />
|
||||
)}
|
||||
{entity && <EntityContextMenu onUnregisterEntity={showRemovalDialog} />}
|
||||
</Header>
|
||||
|
||||
{loading && <Progress />}
|
||||
@@ -161,7 +159,7 @@ export const ComponentPage: FC<ComponentPageProps> = ({ match, history }) => {
|
||||
<Content>
|
||||
<Grid container spacing={3} direction="column">
|
||||
<Grid item>
|
||||
<ComponentMetadataCard entity={entity} />
|
||||
<EntityMetadataCard entity={entity} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<SentryIssuesWidget
|
||||
@@ -172,7 +170,7 @@ export const ComponentPage: FC<ComponentPageProps> = ({ match, history }) => {
|
||||
</Grid>
|
||||
</Content>
|
||||
|
||||
<ComponentRemovalDialog
|
||||
<UnregisterEntityDialog
|
||||
open={confirmationDialogOpen}
|
||||
entity={entity}
|
||||
onConfirm={cleanUpAfterRemoval}
|
||||
+4
-4
@@ -33,7 +33,7 @@ import { useAsync } from 'react-use';
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
import { catalogApiRef } from '../../api/types';
|
||||
|
||||
type ComponentRemovalDialogProps = {
|
||||
type Props = {
|
||||
open: boolean;
|
||||
onConfirm: () => any;
|
||||
onClose: () => any;
|
||||
@@ -50,7 +50,7 @@ function useColocatedEntities(entity: Entity): AsyncState<Entity[]> {
|
||||
}, [catalogApi, entity]);
|
||||
}
|
||||
|
||||
export const ComponentRemovalDialog: FC<ComponentRemovalDialogProps> = ({
|
||||
export const UnregisterEntityDialog: FC<Props> = ({
|
||||
open,
|
||||
onConfirm,
|
||||
onClose,
|
||||
@@ -76,7 +76,7 @@ export const ComponentRemovalDialog: FC<ComponentRemovalDialogProps> = ({
|
||||
return (
|
||||
<Dialog fullScreen={fullScreen} open={open} onClose={onClose}>
|
||||
<DialogTitle id="responsive-dialog-title">
|
||||
Are you sure you want to unregister this component?
|
||||
Are you sure you want to unregister this entity?
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
{loading ? <Progress /> : null}
|
||||
@@ -108,7 +108,7 @@ export const ComponentRemovalDialog: FC<ComponentRemovalDialogProps> = ({
|
||||
</ul>
|
||||
</Typography>
|
||||
<DialogContentText>
|
||||
To undo, just re-register the component in Backstage.
|
||||
To undo, just re-register the entity in Backstage.
|
||||
</DialogContentText>
|
||||
</>
|
||||
) : null}
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
CatalogFilterGroup,
|
||||
CatalogFilterItem,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EntityMeta,
|
||||
LocationSpec,
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useApi, storageApiRef } from '@backstage/core';
|
||||
import { useObservable } from 'react-use';
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { storageApiRef, useApi } from '@backstage/core';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useObservable } from 'react-use';
|
||||
|
||||
const buildEntityKey = (component: Entity) =>
|
||||
`entity:${component.kind}:${component.metadata.namespace ?? 'default'}:${
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { useStarredEntities } from './useStarredEntites';
|
||||
|
||||
@@ -17,5 +17,4 @@
|
||||
export { plugin } from './plugin';
|
||||
export * from './api/CatalogClient';
|
||||
export * from './api/types';
|
||||
export * from './types';
|
||||
export * from './routes';
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import { CatalogPage } from './components/CatalogPage/CatalogPage';
|
||||
import { ComponentPage } from './components/ComponentPage/ComponentPage';
|
||||
import { EntityPage } from './components/EntityPage/EntityPage';
|
||||
import { entityRoute, rootRoute } from './routes';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'catalog',
|
||||
register({ router }) {
|
||||
router.addRoute(rootRoute, CatalogPage);
|
||||
router.addRoute(entityRoute, ComponentPage);
|
||||
router.addRoute(entityRoute, EntityPage);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface ComponentDescriptorV1beta1 extends DescriptorEnvelope {
|
||||
spec: {
|
||||
type: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type ComponentDescriptor = ComponentDescriptorV1beta1;
|
||||
|
||||
/**
|
||||
* Metadata fields common to all versions/kinds of entity.
|
||||
*
|
||||
* @see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta
|
||||
*/
|
||||
export type EntityMeta = {
|
||||
/**
|
||||
* A globally unique ID for the entity.
|
||||
*
|
||||
* This field can not be set by the user at creation time, and the server
|
||||
* will reject an attempt to do so. The field will be populated in read
|
||||
* operations. The field can (optionally) be specified when performing
|
||||
* update or delete operations, but the server is free to reject requests
|
||||
* that do so in such a way that it breaks semantics.
|
||||
*/
|
||||
uid?: string;
|
||||
|
||||
/**
|
||||
* An opaque string that changes for each update operation to any part of
|
||||
* the entity, including metadata.
|
||||
*
|
||||
* This field can not be set by the user at creation time, and the server
|
||||
* will reject an attempt to do so. The field will be populated in read
|
||||
* operations. The field can (optionally) be specified when performing
|
||||
* update or delete operations, and the server will then reject the
|
||||
* operation if it does not match the current stored value.
|
||||
*/
|
||||
etag?: string;
|
||||
|
||||
/**
|
||||
* A positive nonzero number that indicates the current generation of data
|
||||
* for this entity; the value is incremented each time the spec changes.
|
||||
*
|
||||
* This field can not be set by the user at creation time, and the server
|
||||
* will reject an attempt to do so. The field will be populated in read
|
||||
* operations.
|
||||
*/
|
||||
generation?: number;
|
||||
|
||||
/**
|
||||
* The name of the entity.
|
||||
*
|
||||
* Must be uniqe within the catalog at any given point in time, for any
|
||||
* given namespace, for any given kind.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* The short description of the entity.
|
||||
*
|
||||
* A a human readable string.
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* The namespace that the entity belongs to.
|
||||
*/
|
||||
namespace?: string;
|
||||
|
||||
/**
|
||||
* Key/value pairs of identifying information attached to the entity.
|
||||
*/
|
||||
labels?: Record<string, string>;
|
||||
|
||||
/**
|
||||
* Key/value pairs of non-identifying auxiliary information attached to the
|
||||
* entity.
|
||||
*/
|
||||
annotations?: Record<string, string>;
|
||||
};
|
||||
|
||||
/**
|
||||
* The format envelope that's common to all versions/kinds.
|
||||
*
|
||||
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
|
||||
*/
|
||||
export type DescriptorEnvelope = {
|
||||
/**
|
||||
* The version of specification format for this particular entity that
|
||||
* this is written against.
|
||||
*/
|
||||
apiVersion: string;
|
||||
|
||||
/**
|
||||
* The high level entity type being described.
|
||||
*/
|
||||
kind: string;
|
||||
|
||||
/**
|
||||
* Optional metadata related to the entity.
|
||||
*/
|
||||
metadata: EntityMeta;
|
||||
|
||||
/**
|
||||
* The specification data describing the entity itself.
|
||||
*/
|
||||
spec?: object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses and validates descriptors.
|
||||
*
|
||||
* The output must be validated and well formed.
|
||||
*/
|
||||
export type DescriptorParser = {
|
||||
/**
|
||||
* Parses and validates a single raw descriptor.
|
||||
*
|
||||
* @param descriptor A raw descriptor object
|
||||
* @returns A structure describing the parsed and validated descriptor
|
||||
* @throws An Error if the descriptor was malformed
|
||||
*/
|
||||
parse(descriptor: object): Promise<DescriptorEnvelope>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses and validates a single envelope into its materialized kind.
|
||||
*
|
||||
* These parsers may assume that the envelope is already validated and well
|
||||
* formed.
|
||||
*/
|
||||
export type KindParser = {
|
||||
/**
|
||||
* Try to parse an envelope into a materialized kind.
|
||||
*
|
||||
* @param envelope A valid descriptor envelope
|
||||
* @returns A materialized type, or undefined if the given version/kind is
|
||||
* not meant to be handled by this parser
|
||||
* @throws An Error if the type was handled and found to not be properly
|
||||
* formatted
|
||||
*/
|
||||
tryParse(
|
||||
envelope: DescriptorEnvelope,
|
||||
): Promise<DescriptorEnvelope | undefined>;
|
||||
};
|
||||
Reference in New Issue
Block a user