import { type TSchema } from '@sinclair/typebox'; import { GROUP } from '../utils/consts.ts'; import type { Services } from '../utils/service.ts'; import { statusSchema } from './custom-resource.status.ts'; import type { CustomResourceRequest } from './custom-resource.request.ts'; type CustomResourceHandlerOptions = { request: CustomResourceRequest; services: Services; }; type CustomResourceConstructor = { kind: string; spec: TSpec; names: { plural: string; singular: string; }; }; abstract class CustomResource { #options: CustomResourceConstructor; constructor(options: CustomResourceConstructor) { this.#options = options; } public readonly version = 'v1'; public get name() { return `${this.#options.names.plural}.${this.group}`; } public get group() { return GROUP; } public get path() { return `/apis/${this.group}/v1/${this.#options.names.plural}`; } public get kind() { return this.#options.kind; } public get spec() { return this.#options.spec; } public get names() { return this.#options.names; } public abstract update(options: CustomResourceHandlerOptions): Promise; public create?(options: CustomResourceHandlerOptions): Promise; public delete?(options: CustomResourceHandlerOptions): Promise; public toManifest = () => { return { apiVersion: 'apiextensions.k8s.io/v1', kind: 'CustomResourceDefinition', metadata: { name: this.name, }, spec: { group: this.group, names: { kind: this.kind, plural: this.#options.names.plural, singular: this.#options.names.singular, }, scope: 'Namespaced', versions: [ { name: this.version, served: true, storage: true, schema: { openAPIV3Schema: { type: 'object', properties: { spec: this.spec, status: statusSchema, }, }, }, subresources: { status: {}, }, }, ], }, }; }; } export { CustomResource, type CustomResourceConstructor, type CustomResourceHandlerOptions };