返回介绍

选择项目模板

发布于 2024-09-15 23:43:08 字数 3620 浏览 0 评论 0 收藏 0

提供创建项目的基本信息选择:

  • 创建类型:决定创建的是项目还是页面
  • 项目名称:决定文件夹名称
  • 项目模板:决定项目类型
// ./createTemplate.js
import path from "node:path";
import { homedir } from "node:os";
import {
  makeList,
  log,
  makeInput,
  getLatestVersion,
  request,
  printErrorLog,
} from "@oweqian/utils";

const ADD_TYPE_PROJECT = "project";
const ADD_TYPE_PAGE = "page";
const ADD_TYPE = [
  {
    name: "项目",
    value: ADD_TYPE_PROJECT,
  },
  {
    name: "页面",
    value: ADD_TYPE_PAGE,
  },
];

const TEMP_HOME = ".cli-oweqian";

/**
 * 选择创建类型
 * 决定创建的是项目或者页面
 */
function getAddType() {
  return makeList({
    choices: ADD_TYPE,
    message: "请选择初始化类型",
    defaultValue: ADD_TYPE_PROJECT,
  });
}

/**
 * 输入项目名称
 */
function getAddName() {
  return makeInput({
    message: "请输入项目名称",
    defaultValue: "",
    validate: (v) => {
      if (v.length > 0) {
        return true;
      }
      return "项目名称必须输入";
    },
  });
}

/**
 * 选择项目模板
 */
function getAddTemplate(choices) {
  return makeList({
    choices,
    message: "请选择项目模板",
  });
}

/**
 * 选择所在团队
 * 不同的团队有不同的项目模板
 */
function getAddTeam(team) {
  return makeList({
    choices: team.map((item) => ({ name: item, value: item })),
    message: "请选择团队",
  });
}

/**
 * 模板缓存目录
 * os.homedir(): 返回当前用户的主目录的字符串路径
 */
function makeTargetPath() {
  return path.resolve(`${homedir()}/${TEMP_HOME}`, "addTemplate");
}

/**
 * 通过 API 获取项目模板
 */
async function getTemplateFromAPI() {
  try {
    const data = await request({
      url: "/v1/project",
      method: "get",
    });
    log.verbose("template", data);
    return data;
  } catch (e) {
    printErrorLog(e);
    return null;
  }
}

async function createTemplate(name, opts) {
  // 通过 API 获取项目模板
  const ADD_TEMPLATE = await getTemplateFromAPI();
  if (!ADD_TEMPLATE) {
    throw new Error("项目模板不存在");
  }

  /**
   * name:项目名称
   * type:创建类型(值:project/page)
   * template:模板名称
   */
  const { type = null, template = null } = opts;

  // 项目名称
  let addName;
  // 选择的创建类型
  let addType;
  // 选择的模板信息
  let selectedTemplate;

  // 兼容交互式(Options)和非交互式项目创建逻辑
  if (type) {
    addType = type;
  } else {
    addType = await getAddType();
  }
  log.verbose("addType", addType);

  if (addType === ADD_TYPE_PROJECT) {
    if (name) {
      addName = name;
    } else {
      addName = await getAddName();
    }
    log.verbose("addName", addName);

    if (template) {
      selectedTemplate = ADD_TEMPLATE.find((tp) => tp.value === template);
      if (!selectedTemplate) {
        throw new Error(`项目模板 ${template} 不存在`);
      }
    } else {
      // 获取团队信息
      let teamList = ADD_TEMPLATE.map((_) => _.team);
      teamList = [...new Set(teamList)];

      const addTeam = await getAddTeam(teamList);
      log.verbose("addTeam", addTeam);

      // 根据选择的团队信息过滤模板
      let addTemplate = await getAddTemplate(
        ADD_TEMPLATE.filter((_) => _.team === addTeam)
      );
      log.verbose("addTemplate", addTemplate);

      selectedTemplate = ADD_TEMPLATE.find((_) => _.value === addTemplate);
    }
    log.verbose("selectedTemplate", selectedTemplate);

    // 通过 package 名称从 npm 获取最新版本号
    const latestVersion = await getLatestVersion(selectedTemplate.npmName);
    log.verbose("latestVersion", latestVersion);
    selectedTemplate.version = latestVersion;

    // 模板缓存目录
    const targetPath = makeTargetPath();

    return {
      type: addType,
      name: addName,
      template: selectedTemplate,
      targetPath,
    };
  } else {
    throw new Error(`类型 ${addType} 不支持`);
  }
}

export default createTemplate;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文