create extension class

This commit is contained in:
Niels Lyngsø
2023-02-03 14:17:24 +01:00
parent ab2d551af3
commit 5f204d5f17
6 changed files with 51 additions and 6 deletions

View File

@@ -0,0 +1,27 @@
import type { ClassConstructor, ManifestClass } from '../models';
import { hasDefaultExport } from './has-default-export.function';
import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function';
import { loadExtension } from './load-extension.function';
//TODO: Write tests for this method:
export async function createExtensionClass<T = unknown>(manifest: ManifestClass): Promise<T | undefined> {
const js = await loadExtension(manifest);
if (isManifestClassConstructorType(manifest)) {
return new manifest.class() as T;
}
if (js) {
if (hasDefaultExport<ClassConstructor<T>>(js)) {
return new js.default();
}
console.error('-- Extension did not succeed creating an class instance, missing a default export of the served JavaScript file', manifest);
return undefined;
}
console.error('-- Extension did not succeed creating an class instance, missing a default export or `class` in the manifest.', manifest);
return undefined;
}

View File

@@ -1,10 +1,10 @@
import type { ManifestElement } from '../models';
import type { HTMLElementConstructor, ManifestElement } from '../models';
import { hasDefaultExport } from './has-default-export.function';
import { isManifestElementNameType } from './is-manifest-element-name-type.function';
import { loadExtension } from './load-extension.function';
export async function createExtensionElement(manifest: ManifestElement): Promise<HTMLElement | undefined> {
//TODO: Write tests for these extension options:
const js = await loadExtension(manifest);
@@ -15,7 +15,7 @@ export async function createExtensionElement(manifest: ManifestElement): Promise
// TODO: Do we need this except for the default() loader?
if (js) {
if (hasDefaultExport(js)) {
if (hasDefaultExport<HTMLElementConstructor>(js)) {
// created by default class
return new js.default();
}

View File

@@ -1,5 +1,3 @@
import type { HTMLElementConstructor } from '../models';
export function hasDefaultExport(object: unknown): object is { default: HTMLElementConstructor } {
export function hasDefaultExport<ConstructorType>(object: unknown): object is { default: ConstructorType } {
return typeof object === 'object' && object !== null && 'default' in object;
}

View File

@@ -0,0 +1,7 @@
import type { ManifestClass, ManifestClassWithClassConstructor } from '../models';
export function isManifestClassConstructorType(manifest: unknown): manifest is ManifestClassWithClassConstructor {
return (
typeof manifest === 'object' && manifest !== null && (manifest as ManifestClass).class !== undefined
);
}

View File

@@ -0,0 +1,8 @@
import { isManifestJSType } from './is-manifest-js-type.function';
import { isManifestLoaderType } from './is-manifest-loader-type.function';
import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function';
import type { ManifestBase, ManifestClass } from '@umbraco-cms/extensions-registry';
export function isManifestClassableType(manifest: ManifestBase): manifest is ManifestClass {
return isManifestClassConstructorType(manifest) || isManifestLoaderType(manifest) || isManifestJSType(manifest);
}

View File

@@ -98,6 +98,11 @@ export interface ManifestClass extends ManifestWithLoader<object> {
class?: ClassConstructor<unknown>;
//loader?: () => Promise<object | HTMLElement>;
}
export interface ManifestClassWithClassConstructor extends ManifestClass {
class: ClassConstructor<unknown>;
}
export interface ManifestElement extends ManifestWithLoader<object | HTMLElement> {
type: ManifestStandardTypes;
js?: string;