frontend-plugin-api: add support for extension configuration schema

Co-authored-by: Camila Belo <camilaibs@gmail.com>
Co-authored-by: Philipp Hugenroth <philipph@spotify.com>
Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Vincenzo Scamporlino <vincenzos@spotify.com>
Co-authored-by: Johan Haals <johan.haals@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-08-23 14:32:06 +02:00
parent d11e8e0e3d
commit a52d7f271b
9 changed files with 190 additions and 42 deletions
@@ -27,26 +27,45 @@ export interface ExtensionInstance {
/** @internal */
export function createExtensionInstance(options: {
id: string;
extension: Extension;
extension: Extension<unknown>;
config: unknown;
attachments: Record<string, ExtensionInstance[]>;
}): ExtensionInstance {
const { extension, config, attachments } = options;
const { id, extension, config, attachments } = options;
const extensionData = new Map<string, unknown>();
extension.factory({
config,
bind: mapValues(extension.output, ref => {
return (value: unknown) => extensionData.set(ref.id, value);
}),
inputs: mapValues(
extension.inputs,
({ extensionData: pointData }, inputName) => {
// TODO: validation
return (attachments[inputName] ?? []).map(attachment =>
mapValues(pointData, ref => attachment.data.get(ref.id)),
);
},
),
});
return { id: options.id, data: extensionData, $$type: 'extension-instance' };
let parsedConfig: unknown;
try {
parsedConfig = extension.configSchema?.parse(config ?? {});
} catch (e) {
throw new Error(
`Invalid configuration for extension instance '${id}', ${e}`,
);
}
try {
extension.factory({
config: parsedConfig,
bind: mapValues(extension.output, ref => {
return (value: unknown) => extensionData.set(ref.id, value);
}),
inputs: mapValues(
extension.inputs,
({ extensionData: pointData }, inputName) => {
// TODO: validation
return (attachments[inputName] ?? []).map(attachment =>
mapValues(pointData, ref => attachment.data.get(ref.id)),
);
},
),
});
} catch (e) {
throw new Error(`Failed to instantiate extension instance '${id}', ${e}`);
}
return {
id: options.id,
data: extensionData,
$$type: 'extension-instance',
};
}