frontend-internal: add OpaqueType helper

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-09-11 11:51:40 +02:00
parent f094dfd54a
commit 873e42497a
10 changed files with 230 additions and 79 deletions
@@ -31,7 +31,7 @@ import {
import { ExtensionInput } from './createExtensionInput';
import { z } from 'zod';
import { createSchemaFromZod } from '../schema/createSchemaFromZod';
import { InternalExtensionDefinition } from '@internal/frontend';
import { OpaqueExtensionDefinition } from '@internal/frontend';
/**
* Convert a single extension input into a matching resolved input.
@@ -366,26 +366,6 @@ export function createExtension<
namespace: string | undefined extends TNamespace ? undefined : TNamespace;
name: string | undefined extends TName ? undefined : TName;
}> {
type T = {
config: string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
};
configInput: string extends keyof TConfigSchema
? {}
: z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>;
output: UOutput;
inputs: TInputs;
kind: string | undefined extends TKind ? undefined : TKind;
namespace: string | undefined extends TNamespace ? undefined : TNamespace;
name: string | undefined extends TName ? undefined : TName;
};
const schemaDeclaration = options.config?.schema;
const configSchema =
schemaDeclaration &&
@@ -397,10 +377,30 @@ export function createExtension<
),
);
return {
return OpaqueExtensionDefinition.create({
$$type: '@backstage/ExtensionDefinition',
version: 'v2',
T: undefined as unknown as T,
T: undefined as unknown as {
config: string extends keyof TConfigSchema
? {}
: {
[key in keyof TConfigSchema]: z.infer<
ReturnType<TConfigSchema[key]>
>;
};
configInput: string extends keyof TConfigSchema
? {}
: z.input<
z.ZodObject<{
[key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;
}>
>;
output: UOutput;
inputs: TInputs;
kind: string | undefined extends TKind ? undefined : TKind;
namespace: string | undefined extends TNamespace ? undefined : TNamespace;
name: string | undefined extends TName ? undefined : TName;
},
kind: options.kind,
namespace: options.namespace,
name: options.name,
@@ -512,5 +512,5 @@ export function createExtension<
},
}) as ExtensionDefinition<any>;
},
} as InternalExtensionDefinition<T>;
});
}
@@ -29,12 +29,12 @@ import { createExtensionInput } from './createExtensionInput';
import { RouteRef } from '../routing';
import { ExtensionDefinition } from './createExtension';
import { createExtensionDataContainer } from './createExtensionDataContainer';
import { toInternalExtensionDefinition } from '@internal/frontend';
import { OpaqueExtensionDefinition } from '@internal/frontend';
function unused(..._any: any[]) {}
function factoryOutput(ext: ExtensionDefinition, inputs: unknown = undefined) {
const int = toInternalExtensionDefinition(ext);
const int = OpaqueExtensionDefinition.toInternal(ext);
if (int.version !== 'v2') {
throw new Error('Expected v2 extension');
}
@@ -680,7 +680,7 @@ describe('createExtensionBlueprint', () => {
},
});
const ext = toInternalExtensionDefinition(
const ext = OpaqueExtensionDefinition.toInternal(
blueprint.makeWithOverrides({
output: [testDataRef2],
factory(origFactory) {
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
InternalExtensionDefinition,
toInternalExtensionDefinition,
} from '@internal/frontend';
import { OpaqueExtensionDefinition } from '@internal/frontend';
import { ExtensionDefinition } from './createExtension';
import {
Extension,
@@ -58,11 +55,11 @@ export function createFrontendModule<
const extensions = new Array<Extension<any>>();
const extensionDefinitionsById = new Map<
string,
InternalExtensionDefinition
typeof OpaqueExtensionDefinition.TInternal
>();
for (const def of options.extensions ?? []) {
const internal = toInternalExtensionDefinition(def);
const internal = OpaqueExtensionDefinition.toInternal(def);
const ext = resolveExtensionDefinition(def, { namespace: pluginId });
extensions.push(ext);
extensionDefinitionsById.set(ext.id, {
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
InternalExtensionDefinition,
toInternalExtensionDefinition,
} from '@internal/frontend';
import { OpaqueExtensionDefinition } from '@internal/frontend';
import { ExtensionDefinition } from './createExtension';
import {
Extension,
@@ -96,11 +93,11 @@ export function createFrontendPlugin<
const extensions = new Array<Extension<any>>();
const extensionDefinitionsById = new Map<
string,
InternalExtensionDefinition
typeof OpaqueExtensionDefinition.TInternal
>();
for (const def of options.extensions ?? []) {
const internal = toInternalExtensionDefinition(def);
const internal = OpaqueExtensionDefinition.toInternal(def);
const ext = resolveExtensionDefinition(def, { namespace: options.id });
extensions.push(ext);
extensionDefinitionsById.set(ext.id, {
@@ -26,7 +26,7 @@ import {
AnyExtensionDataRef,
ExtensionDataValue,
} from './createExtensionDataRef';
import { toInternalExtensionDefinition } from '@internal/frontend';
import { OpaqueExtensionDefinition } from '@internal/frontend';
/** @public */
export interface Extension<TConfig, TConfigInput = TConfig> {
@@ -141,7 +141,7 @@ export function resolveExtensionDefinition<
definition: ExtensionDefinition<T>,
context?: { namespace?: string },
): Extension<T['config'], T['configInput']> {
const internalDefinition = toInternalExtensionDefinition(definition);
const internalDefinition = OpaqueExtensionDefinition.toInternal(definition);
const {
name,
kind,