nsgm-cli
Version:
A CLI tool to run Next/Style-components and Graphql/Mysql fullstack project
328 lines (327 loc) • 11.2 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Prompt = void 0;
const inquirer_1 = __importDefault(require("inquirer"));
const console_1 = require("./console");
/**
* 交互式提示工具类
*/
class Prompt {
/**
* 确认提示
*/
static async confirm(message, defaultValue = false) {
const { confirmed } = await inquirer_1.default.prompt({
type: "confirm",
name: "confirmed",
message,
default: defaultValue,
});
return confirmed;
}
/**
* 输入提示
*/
static async input(message, defaultValue, validate) {
const config = {
type: "input",
name: "value",
message,
validate: validate || (() => true),
};
if (defaultValue !== undefined) {
config.default = defaultValue;
}
const { value } = await inquirer_1.default.prompt(config);
return value;
}
/**
* 密码输入
*/
static async password(message, validate) {
const { value } = await inquirer_1.default.prompt({
type: "password",
name: "value",
message,
validate: validate || (() => true),
});
return value;
}
/**
* 单选提示
*/
static async select(message, choices) {
const { selected } = await inquirer_1.default.prompt({
type: "list",
name: "selected",
message,
choices,
});
return selected;
}
/**
* 多选提示
*/
static async multiSelect(message, choices) {
const { selected } = await inquirer_1.default.prompt({
type: "checkbox",
name: "selected",
message,
choices,
});
return selected;
}
/**
* 自定义提示
*/
static async custom(questions) {
return await inquirer_1.default.prompt(questions);
}
/**
* 项目初始化向导
*/
static async initWizard() {
console_1.Console.title("🚀 NSGM 项目初始化向导");
console_1.Console.newLine();
const answers = await inquirer_1.default.prompt([
{
type: "input",
name: "projectName",
message: "项目目录:",
default: "my-nsgm-project",
validate: (input) => {
if (!input.trim())
return "项目目录不能为空";
// 允许路径格式,包括相对路径和绝对路径
if (!/^[a-zA-Z0-9\-_./\\]+$/.test(input))
return "项目目录只能包含字母、数字、横线、下划线和路径分隔符";
return true;
},
},
{
type: "input",
name: "description",
message: "项目描述:",
default: "A NSGM fullstack project",
},
{
type: "input",
name: "author",
message: "作者:",
default: "Your Name",
},
]);
// 设置默认配置
const result = {
...answers,
database: true,
features: ["nextjs", "styled-components", "graphql", "mysql", "typescript", "eslint"],
};
return result;
}
/**
* 控制器创建向导
*/
static async createControllerWizard() {
console_1.Console.title("📝 创建控制器向导 (包含完整CRUD + 导入导出 + 批量删除功能)");
console_1.Console.newLine();
const answers = await inquirer_1.default.prompt([
{
type: "input",
name: "dictionary",
message: "项目目录:",
default: ".",
validate: (input) => {
if (!input.trim())
return "项目目录不能为空";
return true;
},
},
{
type: "input",
name: "controller",
message: "控制器名称:",
validate: (input) => {
if (!input.trim())
return "控制器名称不能为空";
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input))
return "控制器名称必须以字母开头,只能包含字母和数字";
return true;
},
},
{
type: "input",
name: "description",
message: "控制器描述:",
default: (answers) => `${answers.controller} 控制器`,
},
{
type: "confirm",
name: "useCustomFields",
message: "是否自定义字段配置?(默认字段: id, name, create_date, update_date)",
default: false,
},
]);
// 设置默认action为manage(包含完整的CRUD + 导入 + 导出 + 批量删除功能)
answers.action = "manage";
answers.includeDatabase = true;
if (answers.useCustomFields) {
// 如果用户选择自定义字段,收集字段定义
answers.fields = await this.collectFieldDefinitions();
}
else {
// 使用默认字段配置
answers.fields = [
{ name: "id", type: "integer", required: true, comment: "主键", isPrimaryKey: true, isAutoIncrement: true },
{
name: "name",
type: "varchar",
length: 100,
required: true,
comment: "名称",
showInList: true,
showInForm: true,
searchable: true,
},
{ name: "create_date", type: "timestamp", required: true, comment: "创建时间", isSystemField: true },
{ name: "update_date", type: "timestamp", required: true, comment: "更新时间", isSystemField: true },
];
}
return answers;
}
/**
* 收集字段定义 (简化版本)
*/
static async collectFieldDefinitions() {
const fields = [];
// 默认添加ID字段
fields.push({
name: "id",
type: "integer",
required: true,
comment: "主键",
isPrimaryKey: true,
isAutoIncrement: true,
});
console_1.Console.info("💡 输入字段信息,输入空白字段名结束添加");
let fieldIndex = 1;
while (true) {
const fieldName = await this.input(`字段${fieldIndex} 名称 (留空结束):`);
if (!fieldName.trim())
break;
// 验证字段名
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(fieldName)) {
console_1.Console.error("字段名称格式无效,请重新输入");
continue;
}
if (fields.some((f) => f.name === fieldName) || ["create_date", "update_date"].includes(fieldName)) {
console_1.Console.error("字段名称已存在或为系统保留字段,请重新输入");
continue;
}
// 简化的字段类型选择
const fieldType = await this.select("字段类型:", [
"varchar",
"text",
"integer",
"decimal",
"boolean",
"date",
"datetime",
]);
// 只对需要长度的类型询问长度
let length;
if (fieldType === "varchar") {
length = await this.input("字符串长度:", "255");
}
else if (fieldType === "decimal") {
length = await this.input("小数精度 (如: 10,2):", "10,2");
}
// 简化配置:只询问是否必填和注释
const required = await this.confirm("是否必填:", true);
const comment = await this.input("字段注释:", fieldName);
const field = {
name: fieldName,
type: fieldType,
required,
comment,
showInList: true, // 默认在列表显示
showInForm: true, // 默认在表单显示
searchable: fieldType === "varchar", // varchar类型默认可搜索
};
// 只有当length有值时才添加
if (length) {
field.length = length;
}
fields.push(field);
fieldIndex++;
}
// 自动添加系统字段
fields.push({
name: "create_date",
type: "timestamp",
required: true,
comment: "创建时间",
isSystemField: true,
}, {
name: "update_date",
type: "timestamp",
required: true,
comment: "更新时间",
isSystemField: true,
});
return fields;
}
/**
* 控制器删除向导
*/
static async deleteControllerWizard() {
console_1.Console.title("🗑️ 删除控制器向导");
console_1.Console.newLine();
const answers = await inquirer_1.default.prompt([
{
type: "input",
name: "dictionary",
message: "项目目录:",
default: ".",
validate: (input) => {
if (!input.trim())
return "项目目录不能为空";
return true;
},
},
{
type: "input",
name: "controller",
message: "控制器名称:",
validate: (input) => {
if (!input.trim())
return "控制器名称不能为空";
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input))
return "控制器名称必须以字母开头,只能包含字母和数字";
return true;
},
},
{
type: "list",
name: "action",
message: "删除范围:",
choices: [
{ name: "删除所有相关文件", value: "all" },
{ name: "仅删除指定操作", value: "manage" },
],
default: "all",
},
{
type: "confirm",
name: "deleteDatabase",
message: "是否同时删除数据库表?",
default: false,
},
]);
return answers;
}
}
exports.Prompt = Prompt;