This commit introduces two pipes: `inlinePowerShell`, `escapeDoubleQuotes`. The types when used together allows writing adding clean and real PowerShell scripts as they are (without inlinining or escaping them), removing the need to have hard-coded inlining/escaping. It enables writing better PowerShell, makes it easier to maintain and extend PowerShell scripts. Also allows writing more stable code with less "unseen" bugs due to manual escaping/inlining. This commit naturally reveals and fixes double quotes not being escaped in "Empty trash bin" script. This is solved by unifying the use of RunPowerShell function by all scripts using PowerShell. The function inlines and escapes the scripts as compile time to be send them to PowerShell.exe as an argument and then invokes PowerShell.exe with generated ugly code.
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import { IPipe } from './IPipe';
|
|
import { InlinePowerShell } from './PipeDefinitions/InlinePowerShell';
|
|
import { EscapeDoubleQuotes } from './PipeDefinitions/EscapeDoubleQuotes';
|
|
|
|
const RegisteredPipes = [
|
|
new EscapeDoubleQuotes(),
|
|
new InlinePowerShell(),
|
|
];
|
|
|
|
export interface IPipeFactory {
|
|
get(pipeName: string): IPipe;
|
|
}
|
|
|
|
export class PipeFactory implements IPipeFactory {
|
|
private readonly pipes = new Map<string, IPipe>();
|
|
constructor(pipes: readonly IPipe[] = RegisteredPipes) {
|
|
if (pipes.some((pipe) => !pipe)) {
|
|
throw new Error('undefined pipe in list');
|
|
}
|
|
for (const pipe of pipes) {
|
|
this.registerPipe(pipe);
|
|
}
|
|
}
|
|
public get(pipeName: string): IPipe {
|
|
validatePipeName(pipeName);
|
|
if (!this.pipes.has(pipeName)) {
|
|
throw new Error(`Unknown pipe: "${pipeName}"`);
|
|
}
|
|
return this.pipes.get(pipeName);
|
|
}
|
|
private registerPipe(pipe: IPipe): void {
|
|
validatePipeName(pipe.name);
|
|
if (this.pipes.has(pipe.name)) {
|
|
throw new Error(`Pipe name must be unique: "${pipe.name}"`);
|
|
}
|
|
this.pipes.set(pipe.name, pipe);
|
|
}
|
|
}
|
|
|
|
function validatePipeName(name: string) {
|
|
if (!name) {
|
|
throw new Error('empty pipe name');
|
|
}
|
|
if (!/^[a-z][A-Za-z]*$/.test(name)) {
|
|
throw new Error(`Pipe name should be camelCase: "${name}"`);
|
|
}
|
|
}
|