Skip to content

Instantly share code, notes, and snippets.

@flisboac
Created April 25, 2019 05:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flisboac/0e3af4cf132b08fab92e933a9479f479 to your computer and use it in GitHub Desktop.
Save flisboac/0e3af4cf132b08fab92e933a9479f479 to your computer and use it in GitHub Desktop.
interface IValidQuestionValidation {
success: true;
value: string;
}
interface IInvalidQuestionValidation {
success: false;
message: string;
}
type IQuestionValidation = IInvalidQuestionValidation | IValidQuestionValidation;
declare function writeln(message: string): any;
declare function ioQuestion(message: string): Promise<string>;
async function question(
message: string,
validator: ((input: string) => IQuestionValidation | Promise<IQuestionValidation>),
options?: {
maxTries?: number,
overtryMessage?: string,
},
) {
options = options || {};
let tries = 0;
const maxTries = options.maxTries || 3;
while (tries <= maxTries) {
tries++;
const value = await ioQuestion(message);
const validation = await Promise.resolve(validator(value));
if (!validation.success) {
writeln(`OOPS! ${validation.message}`);
} else {
return validation.value;
}
}
throw new Error(options.overtryMessage || "Try again!");
}
async function getName<T extends object>(previousData: T) {
const name = await question('What is your name?', value => {
const minLength = 8;
if (!value) {
return {
success: false,
message: "Please provide a name.",
};
}
if (value.length <= minLength) {
return {
success: false,
message: `Your name must have at least ${minLength} character(s).`,
};
}
return {
success: true,
value,
};
});
return {
...previousData,
name,
};
}
async function getAge<T extends object>(previousData: T) {
const age = await question('What is your age?', value => {
if (!value) {
return {
success: false,
message: "Please inform your age.",
};
}
if (/\d+/.test(value)) {
return {
success: false,
message: "Please inform a valid age.",
};
}
return {
success: true,
value,
};
});
return {
...previousData,
age: parseInt(age, 10),
};
}
async function main() {
const data = await Promise.resolve({})
.then(getAge)
.then(getName);
if (data.age < 18) {
writeln(`Hello, ${data.name}! It seems you're too young to proceed.`);
} else {
writeln(`Welcome, ${data.name}! Have your beer! C[¨]`);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment