frontend-plugin-api: initial optional extension output implementation
Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Co-authored-by: Philipp Hugenroth <philipph@spotify.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -49,4 +49,42 @@ describe('createExtension', () => {
|
||||
});
|
||||
expect(extension.id).toBe('test');
|
||||
});
|
||||
|
||||
it('should create an extension with a some optional output', () => {
|
||||
const extension = createExtension({
|
||||
id: 'test',
|
||||
at: 'root',
|
||||
output: {
|
||||
foo: stringData,
|
||||
bar: stringData.optional(),
|
||||
},
|
||||
factory({ bind }) {
|
||||
bind({
|
||||
foo: 'bar',
|
||||
});
|
||||
bind({
|
||||
foo: 'bar',
|
||||
bar: 'baz',
|
||||
});
|
||||
bind({
|
||||
// @ts-expect-error
|
||||
foo: 3,
|
||||
});
|
||||
bind({
|
||||
foo: 'bar',
|
||||
// @ts-expect-error
|
||||
bar: 3,
|
||||
});
|
||||
// @ts-expect-error
|
||||
bind({ bar: 'bar' });
|
||||
// @ts-expect-error
|
||||
bind({});
|
||||
// @ts-expect-error
|
||||
bind();
|
||||
// @ts-expect-error
|
||||
bind('bar');
|
||||
},
|
||||
});
|
||||
expect(extension.id).toBe('test');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,10 +18,26 @@ import { PortableSchema } from '../schema';
|
||||
import { BackstagePlugin } from './createPlugin';
|
||||
import { AnyExtensionDataMap, Extension } from './types';
|
||||
|
||||
type OnlyRequiredKeys<TOutput extends AnyExtensionDataMap> = {
|
||||
[K in keyof TOutput]: TOutput[K]['config']['optional'] extends true
|
||||
? never
|
||||
: K;
|
||||
}[keyof TOutput];
|
||||
|
||||
type OnlyOptionalKeys<TOutput extends AnyExtensionDataMap> = {
|
||||
[K in keyof TOutput]: TOutput[K]['config']['optional'] extends false
|
||||
? never
|
||||
: K;
|
||||
}[keyof TOutput];
|
||||
|
||||
/** @public */
|
||||
export type ExtensionDataBind<TOutput extends AnyExtensionDataMap> = (outputs: {
|
||||
[K in keyof TOutput]: TOutput[K]['T'];
|
||||
}) => void;
|
||||
export type ExtensionDataBind<TOutput extends AnyExtensionDataMap> = (
|
||||
outputs: {
|
||||
[K in OnlyRequiredKeys<TOutput>]: TOutput[K]['T'];
|
||||
} & {
|
||||
[K in OnlyOptionalKeys<TOutput>]?: TOutput[K]['T'];
|
||||
},
|
||||
) => void;
|
||||
|
||||
/** @public */
|
||||
export type ExtensionDataValue<TData extends AnyExtensionDataMap> = {
|
||||
|
||||
@@ -15,14 +15,35 @@
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
export type ExtensionDataRef<T> = {
|
||||
export type ExtensionDataRef<
|
||||
TData,
|
||||
TConfig extends { optional: boolean } = { optional: false },
|
||||
> = {
|
||||
id: string;
|
||||
T: T;
|
||||
T: TData;
|
||||
config: TConfig;
|
||||
$$type: 'extension-data';
|
||||
};
|
||||
|
||||
/** @public */
|
||||
// TODO: change to options object with ID.
|
||||
export function createExtensionDataRef<T>(id: string): ExtensionDataRef<T> {
|
||||
return { id, $$type: 'extension-data' } as ExtensionDataRef<T>;
|
||||
export interface ConfigurableExtensionDataRef<
|
||||
TData,
|
||||
TConfig extends { optional: boolean },
|
||||
> extends ExtensionDataRef<TData, TConfig> {
|
||||
optional(): ConfigurableExtensionDataRef<TData, TData & { optional: true }>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
// TODO: change to options object with ID.
|
||||
export function createExtensionDataRef<TData>(
|
||||
id: string,
|
||||
): ConfigurableExtensionDataRef<TData, { optional: false }> {
|
||||
return {
|
||||
id,
|
||||
$$type: 'extension-data',
|
||||
config: { optional: false },
|
||||
optional() {
|
||||
return { ...this, config: { ...this.config, optional: true } };
|
||||
},
|
||||
} as ConfigurableExtensionDataRef<TData, { optional: false }>;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { ExtensionDataRef } from './createExtensionDataRef';
|
||||
import { BackstagePlugin } from './createPlugin';
|
||||
|
||||
/** @public */
|
||||
export type AnyExtensionDataMap = Record<string, ExtensionDataRef<any>>;
|
||||
export type AnyExtensionDataMap = Record<string, ExtensionDataRef<any, any>>;
|
||||
|
||||
/** @public */
|
||||
export interface Extension<TConfig> {
|
||||
|
||||
Reference in New Issue
Block a user