Created
April 25, 2019 05:12
-
-
Save flisboac/0e3af4cf132b08fab92e933a9479f479 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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