added ability to revert (#21)

This commit is contained in:
undergroundwires
2020-07-15 19:04:56 +01:00
parent 57028987f1
commit 9c063d59de
58 changed files with 1448 additions and 265 deletions

View File

@@ -13,11 +13,11 @@ export class Application implements IApplication {
public readonly name: string,
public readonly repositoryUrl: string,
public readonly version: string,
public readonly categories: ReadonlyArray<ICategory>) {
public readonly actions: ReadonlyArray<ICategory>) {
if (!name) { throw Error('Application has no name'); }
if (!repositoryUrl) { throw Error('Application has no repository url'); }
if (!version) { throw Error('Version cannot be empty'); }
this.flattened = flatten(categories);
this.flattened = flatten(actions);
if (this.flattened.allCategories.length === 0) {
throw new Error('Application must consist of at least one category');
}

View File

@@ -5,9 +5,9 @@ export interface IApplication {
readonly name: string;
readonly repositoryUrl: string;
readonly version: string;
readonly categories: ReadonlyArray<ICategory>;
readonly totalScripts: number;
readonly totalCategories: number;
readonly actions: ReadonlyArray<ICategory>;
getRecommendedScripts(): ReadonlyArray<IScript>;
findCategory(categoryId: number): ICategory | undefined;

View File

@@ -1,9 +1,11 @@
import { IEntity } from './../infrastructure/Entity/IEntity';
import { IEntity } from '../infrastructure/Entity/IEntity';
import { IDocumentable } from './IDocumentable';
export interface IScript extends IEntity<string>, IDocumentable {
readonly name: string;
readonly code: string;
readonly isRecommended: boolean;
readonly documentationUrls: ReadonlyArray<string>;
readonly code: string;
readonly revertCode: string;
canRevert(): boolean;
}

View File

@@ -2,44 +2,56 @@ import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
import { IScript } from './IScript';
export class Script extends BaseEntity<string> implements IScript {
private static ensureNoEmptyLines(name: string, code: string): void {
if (code.split('\n').some((line) => line.trim().length === 0)) {
throw Error(`Script has empty lines "${name}"`);
}
}
private static ensureCodeHasUniqueLines(name: string, code: string): void {
const lines = code.split('\n')
.filter((line) => this.mayBeUniqueLine(line));
if (lines.length === 0) {
return;
}
const duplicateLines = lines.filter((e, i, a) => a.indexOf(e) !== i);
if (duplicateLines.length !== 0) {
throw Error(`Duplicates detected in script "${name}":\n ${duplicateLines.join('\n')}`);
}
}
private static mayBeUniqueLine(codeLine: string): boolean {
const trimmed = codeLine.trim();
if (trimmed === ')' || trimmed === '(') { // "(" and ")" are used often in batch code
return false;
}
return true;
}
constructor(
public name: string,
public code: string,
public documentationUrls: ReadonlyArray<string>,
public isRecommended: boolean) {
public readonly name: string,
public readonly code: string,
public readonly revertCode: string,
public readonly documentationUrls: ReadonlyArray<string>,
public readonly isRecommended: boolean) {
super(name);
if (code == null || code.length === 0) {
throw new Error('Code is empty or null');
validateCode(name, code);
if (revertCode) {
validateCode(name, revertCode);
if (code === revertCode) {
throw new Error(`${name}: Code itself and its reverting code cannot be the same`);
}
}
Script.ensureCodeHasUniqueLines(name, code);
Script.ensureNoEmptyLines(name, code);
}
public canRevert(): boolean {
return Boolean(this.revertCode);
}
}
export { IScript } from './IScript';
function validateCode(name: string, code: string): void {
if (!code || code.length === 0) {
throw new Error(`Code of ${name} is empty or null`);
}
ensureCodeHasUniqueLines(name, code);
ensureNoEmptyLines(name, code);
}
function ensureNoEmptyLines(name: string, code: string): void {
if (code.split('\n').some((line) => line.trim().length === 0)) {
throw Error(`Script has empty lines "${name}"`);
}
}
function mayBeUniqueLine(codeLine: string): boolean {
const trimmed = codeLine.trim();
if (trimmed === ')' || trimmed === '(') { // "(" and ")" are used often in batch code
return false;
}
return true;
}
function ensureCodeHasUniqueLines(name: string, code: string): void {
const lines = code.split('\n')
.filter((line) => mayBeUniqueLine(line));
if (lines.length === 0) {
return;
}
const duplicateLines = lines.filter((e, i, a) => a.indexOf(e) !== i);
if (duplicateLines.length !== 0) {
throw Error(`Duplicates detected in script "${name}":\n ${duplicateLines.join('\n')}`);
}
}