import { UpdateMode, type UpdateComicInput, type UpdateOptions, type UpdateTagInput } from '$gql/graphql'; type Key = string | number | symbol; interface AssociationUpdate { ids?: number[] | string[] | null; options?: UpdateOptions | null; } type Input = { [Property in K]?: T | null; }; abstract class Entry { key: K; constructor(key: K) { this.key = key; } abstract integrate(input: Input): void; abstract hasInput(): boolean; } class Association extends Entry { ids = []; options = { mode: UpdateMode.Add }; constructor(key: K) { super(key); } integrate(input: Input) { if (this.hasInput()) { input[this.key] = { ids: this.ids, options: this.options }; } } hasInput() { return this.ids.length > 0; } } class Enum extends Entry { value?: string = undefined; constructor(key: K) { super(key); } integrate(input: Input): void { if (this.hasInput()) { input[this.key] = this.value; } } hasInput() { return this.value !== undefined && this.value !== null; } } abstract class Controls { toInput() { const input = {} as I; Object.values(this).forEach((v: Entry) => v.integrate(input)); return input; } hasInput() { return Object.values(this).some((i: Entry) => i.hasInput()); } } export class UpdateTagsControls extends Controls { namespaces = new Association('namespaces'); } export class UpdateComicsControls extends Controls { artists = new Association('artists'); category = new Enum('category'); censorship = new Enum('censorship'); direction = new Enum('direction'); layout = new Enum('layout'); characters = new Association('characters'); circles = new Association('circles'); language = new Enum('language'); rating = new Enum('rating'); tags = new Association('tags'); worlds = new Association('worlds'); }