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
146 lines (145 loc) • 6.74 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const is = __importStar(require("is"));
const inquirer = __importStar(require("inquirer"));
const helpers_1 = require("../utilities/helpers");
const logger_1 = __importDefault(require("../utilities/logger"));
const errors_1 = require("../errors");
const prompt_1 = __importDefault(require("./prompt"));
const DEFAULT_OPTIONS = {
default: false,
showHiddenPrompts: false,
};
class Prompter {
constructor(prompts, opts = {}) {
logger_1.default.prompter.info('Prompts: %n', prompts);
this.opts = Object.assign(Object.assign({}, DEFAULT_OPTIONS), opts);
this.answers = {};
this.prompts = prompts.map((p) => new prompt_1.default(p, this));
this.answered = 0;
}
needsAnswers() {
return this.hasPrompts() && this.prompts.length !== this.answered;
}
hasPrompts() {
return !!this.prompts.length;
}
getPrompt(name) {
const prompt = this.prompts.find((p) => p.name === name);
if (!prompt)
throw new errors_1.PromptNoPromptFoundError(name);
return prompt;
}
setAnswers(answers) {
if (!is.object(answers)) {
throw new errors_1.PromptInvalidAnswersError(answers);
}
this.prompts.forEach((prompt) => {
const answer = prompt.answerWith(answers);
if (is.defined(answer)) {
this.setAnswer(prompt.name, answer);
}
});
return this.answers;
}
setAnswer(name, answer) {
if (!(0, helpers_1.hasProp)(this.answers, name)) {
this.answered += 1;
}
logger_1.default.prompter.info('Answer set: %n', {
[name]: answer,
});
this.answers[name] = answer;
}
_getPromptsThatNeedAnswers() {
return this.prompts.filter((p) => !this.hasAnswerToPrompt(p));
}
hasAnswerToPrompt(promptOrName, answers = this.answers) {
const prompt = is.string(promptOrName)
? this.getPrompt(promptOrName)
: promptOrName;
return is.defined(answers[prompt.name]);
}
getAnswers() {
return __awaiter(this, void 0, void 0, function* () {
logger_1.default.prompter.info('Fetching answers...');
let promptsLeft = this._getPromptsThatNeedAnswers();
if (!this.needsAnswers())
return this.answers;
logger_1.default.prompter.info('Current Answers: %n', this.answers);
logger_1.default.prompter.info('Prompts that need answers: %n', promptsLeft.map((p) => p.name));
if (this.opts.default) {
const allDefaults = {};
promptsLeft.forEach((prompt) => {
// TODO: should default to null
allDefaults[prompt.name] = prompt.getDefaultValue(Object.assign(Object.assign({}, allDefaults), this.answers));
});
return this.setAnswers(allDefaults);
}
const hiddenPrompts = promptsLeft.filter((prompt) => prompt.hidden);
// remove hidden prompts if we arent showing them
if (!this.opts.showHiddenPrompts) {
promptsLeft = promptsLeft.filter((prompt) => !prompt.hidden);
}
if (promptsLeft.length) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const newAnswers = yield inquirer.prompt(promptsLeft);
this.setAnswers(newAnswers);
}
// Calculate hidden prompts after user prompts so user answers can be used
if (!this.opts.showHiddenPrompts) {
const allHiddenDefaults = {};
logger_1.default.prompter.info('Hidden prompts: %n', hiddenPrompts.map((p) => p.name));
hiddenPrompts.forEach((prompt) => {
const defaultValue = prompt.getDefaultValue(Object.assign(Object.assign({}, allHiddenDefaults), this.answers));
// TODO: getDefaultValue really should be doing this but dont want to break any functionality with `default` option
allHiddenDefaults[prompt.name] = defaultValue !== null && defaultValue !== void 0 ? defaultValue : null;
});
logger_1.default.prompter.info('Hidden answers: %n', allHiddenDefaults);
this.setAnswers(allHiddenDefaults);
}
const allDefaults = {};
promptsLeft.forEach((prompt) => {
// TODO: should default to null
allDefaults[prompt.name] = prompt.getDefaultValue(Object.assign(Object.assign({}, allDefaults), this.answers));
});
return this.setAnswers(Object.assign(Object.assign({}, allDefaults), this.answers));
});
}
}
exports.default = Prompter;