templates-mo
Version:
Templates is a scaffolding framework that makes code generation simple, dynamic, and reusable. Generate files, parts of your app, or whole project structures—without the repetitive copy-pasting
145 lines (110 loc) • 3.42 kB
text/typescript
import * as is from 'is';
import logger from '@tps/utilities/logger';
import {
SettingsFilePrompt,
AnswersHash,
ValidateFn,
DefaultFn,
WhenFn,
AnswersData,
} from '@tps/types/settings';
import type Prompter from './prompter';
export default class Prompt {
public name: SettingsFilePrompt['name'];
public message: SettingsFilePrompt['message'];
public description: SettingsFilePrompt['description'];
public aliases: SettingsFilePrompt['aliases'];
public tpsType: SettingsFilePrompt['tpsType'];
public type: SettingsFilePrompt['type'];
public default: SettingsFilePrompt['default'];
public hidden: SettingsFilePrompt['hidden'];
public choices?: SettingsFilePrompt['choices'];
public validate: SettingsFilePrompt['validate'];
public filter: SettingsFilePrompt['filter'];
public transformer: SettingsFilePrompt['transformer'];
public when: SettingsFilePrompt['when'];
public pageSize: SettingsFilePrompt['pageSize'];
public prefix: SettingsFilePrompt['prefix'];
public suffix: SettingsFilePrompt['suffix'];
constructor(prompt: SettingsFilePrompt, prompter: Prompter) {
logger.prompt.info('Prompt %O', prompt);
this.aliases = prompt.aliases || [];
this.tpsType = prompt.tpsType || 'package';
if (!['package', 'data'].includes(this.tpsType)) {
throw new Error(
"Invalid prop type in prompts. tpsType must be either 'package' or 'data'",
);
}
// inquire props
this.name = prompt.name;
this.type = prompt.type;
this.message = prompt.message;
this.description = prompt.description;
// let defaultValue;
// const isPrompterDefaultIndex = ['list', 'rawlist', 'expand'].includes(
// prompt.type
// );
// if (isPrompterDefaultIndex) {
// let defaultFromChoices = this.choices[prompt.default];
// if (is.func(this.filter)) {
// defaultFromChoices = this.filter(defaultFromChoices);
// }
// defaultValue = defaultFromChoices;
// } else {
// defaultValue = prompt.default;
// }
this.hidden = prompt.hidden ?? false;
this.choices = prompt.choices;
this.pageSize = prompt.pageSize;
this.prefix = prompt.prefix;
this.suffix = prompt.suffix;
this.filter = prompt.filter;
this.transformer = prompt.transformer;
this.default = this.wrapFunc(
prompt.default,
(fn: DefaultFn, inquirerAnswers: AnswersHash) => {
return fn({
...prompter.answers,
...inquirerAnswers,
});
},
);
this.when = this.wrapFunc(
prompt.when,
(fn: WhenFn, inquirerAnswers: AnswersHash) => {
return fn({
...prompter.answers,
...inquirerAnswers,
});
},
);
this.validate = this.wrapFunc(
prompt.validate,
(fn: ValidateFn, input: string, inquirerAnswers: AnswersHash) => {
return fn(input, {
...prompter.answers,
...inquirerAnswers,
});
},
);
}
private wrapFunc(d, wrapper) {
return d instanceof Function ? (...args) => wrapper(d, ...args) : d;
}
isData(): boolean {
return this.tpsType === 'data';
}
isPkg(): boolean {
return !this.isData();
}
getDefaultValue(answers: AnswersHash): AnswersData {
return this.default instanceof Function
? this.default(answers)
: this.default;
}
answerWith<T>(answers: Record<string, T>): T {
const canAnswerBy = [this.name, ...this.aliases];
const didAnswerBy = canAnswerBy.find((by) => is.defined(answers[by]));
return !didAnswerBy ? undefined : answers[didAnswerBy];
}
}