Files
privacy.sexy/src/domain/Executables/Category/CollectionCategory.ts
undergroundwires c138f74460 Refactor to unify scripts/categories as Executable
This commit consolidates scripts and categories under a unified
'Executable' concept. This simplifies the architecture and improves code
readability.

- Introduce subfolders within `src/domain` to segregate domain elements.
- Update class and interface names by removing the 'I' prefix in
  alignment with new coding standards.
- Replace 'Node' with 'Executable' to clarify usage; reserve 'Node'
  exclusively for the UI's tree component.
2024-06-12 12:36:40 +02:00

60 lines
1.8 KiB
TypeScript

import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
import type { Category } from './Category';
import type { Script } from '../Script/Script';
export class CollectionCategory extends BaseEntity<number> implements Category {
private allSubScripts?: ReadonlyArray<Script> = undefined;
public readonly name: string;
public readonly docs: ReadonlyArray<string>;
public readonly subCategories: ReadonlyArray<Category>;
public readonly scripts: ReadonlyArray<Script>;
constructor(parameters: CategoryInitParameters) {
super(parameters.id);
validateParameters(parameters);
this.name = parameters.name;
this.docs = parameters.docs;
this.subCategories = parameters.subcategories;
this.scripts = parameters.scripts;
}
public includes(script: Script): boolean {
return this.getAllScriptsRecursively().some((childScript) => childScript.id === script.id);
}
public getAllScriptsRecursively(): readonly Script[] {
if (!this.allSubScripts) {
this.allSubScripts = parseScriptsRecursively(this);
}
return this.allSubScripts;
}
}
export interface CategoryInitParameters {
readonly id: number;
readonly name: string;
readonly docs: ReadonlyArray<string>;
readonly subcategories: ReadonlyArray<Category>;
readonly scripts: ReadonlyArray<Script>;
}
function parseScriptsRecursively(category: Category): ReadonlyArray<Script> {
return [
...category.scripts,
...category.subCategories.flatMap((c) => c.getAllScriptsRecursively()),
];
}
function validateParameters(parameters: CategoryInitParameters) {
if (!parameters.name) {
throw new Error('missing name');
}
if (parameters.subcategories.length === 0 && parameters.scripts.length === 0) {
throw new Error('A category must have at least one sub-category or script');
}
}