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.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { isString } from '@/TypeHelpers';
|
||||
import type { ExecutableData } from '@/application/collections/';
|
||||
import { type ExecutableErrorContext } from './ExecutableErrorContext';
|
||||
import { createExecutableContextErrorMessage, type ExecutableContextErrorMessageCreator } from './ExecutableErrorContextMessage';
|
||||
|
||||
export interface ExecutableValidatorFactory {
|
||||
(context: ExecutableErrorContext): ExecutableValidator;
|
||||
}
|
||||
|
||||
export interface ExecutableValidator {
|
||||
assertValidName(nameValue: string): void;
|
||||
assertDefined(
|
||||
data: ExecutableData | undefined,
|
||||
): asserts data is NonNullable<ExecutableData> & void;
|
||||
assert(
|
||||
validationPredicate: () => boolean,
|
||||
errorMessage: string,
|
||||
): asserts validationPredicate is (() => true);
|
||||
createContextualErrorMessage(errorMessage: string): string;
|
||||
}
|
||||
|
||||
export const createExecutableDataValidator
|
||||
: ExecutableValidatorFactory = (context) => new ContextualExecutableValidator(context);
|
||||
|
||||
export class ContextualExecutableValidator implements ExecutableValidator {
|
||||
constructor(
|
||||
private readonly context: ExecutableErrorContext,
|
||||
private readonly createErrorMessage
|
||||
: ExecutableContextErrorMessageCreator = createExecutableContextErrorMessage,
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
public assertValidName(nameValue: string): void {
|
||||
this.assert(() => Boolean(nameValue), 'missing name');
|
||||
this.assert(
|
||||
() => isString(nameValue),
|
||||
`Name (${JSON.stringify(nameValue)}) is not a string but ${typeof nameValue}.`,
|
||||
);
|
||||
}
|
||||
|
||||
public assertDefined(
|
||||
data: ExecutableData,
|
||||
): asserts data is NonNullable<ExecutableData> {
|
||||
this.assert(
|
||||
() => data !== undefined && data !== null && Object.keys(data).length > 0,
|
||||
'missing executable data',
|
||||
);
|
||||
}
|
||||
|
||||
public assert(
|
||||
validationPredicate: () => boolean,
|
||||
errorMessage: string,
|
||||
): asserts validationPredicate is (() => true) {
|
||||
if (!validationPredicate()) {
|
||||
this.throw(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public createContextualErrorMessage(errorMessage: string): string {
|
||||
return this.createErrorMessage(errorMessage, this.context);
|
||||
}
|
||||
|
||||
private throw(errorMessage: string): never {
|
||||
throw new Error(
|
||||
this.createContextualErrorMessage(errorMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user