编程式 API

在您的 Node.js 应用程序中以编程方式使用 Better-T-Stack

概述

Better-T-Stack CLI 可以在您的 Node.js 应用程序中以编程方式使用,允许您通过 JavaScript/TypeScript 代码而不是 shell 命令来创建项目、添加功能和管理配置。

安装

在您的 Node.js 项目中安装包:

npm install create-better-t-stack
# 或
pnpm add create-better-t-stack
# 或
bun add create-better-t-stack

快速开始

基本项目创建

import { init } from "create-better-t-stack";

async function createProject() {
  const result = await init("my-app", {
    yes: true, // 使用默认值,无提示
    frontend: ["tanstack-router"],
    backend: "hono",
    database: "sqlite",
    orm: "drizzle",
    auth: "better-auth",
    packageManager: "bun",
    install: false, // 不自动安装依赖
    disableAnalytics: true, // 禁用分析
  });

  if (result.success) {
    console.log(`✅ 项目创建于: ${result.projectDirectory}`);
    console.log(`📝 可重现命令: ${result.reproducibleCommand}`);
    console.log(`⏱️  耗时: ${result.elapsedTimeMs}ms`);
  } else {
    console.error(`❌ 失败: ${result.error}`);
  }
}

createProject();

目录冲突处理

import { init } from "create-better-t-stack";

const result = await init("existing-folder", {
  yes: true,
  directoryConflict: "increment", // 创建 "existing-folder-1"
  renderTitle: false, // 隐藏 ASCII 艺术字
});

禁用分析

您可以禁用分析:

import { init } from "create-better-t-stack";

const result = await init("my-private-project", {
  yes: true,
  disableAnalytics: true, // 不会发送任何分析数据
  frontend: ["tanstack-router"],
  backend: "hono",
});

注意: 分析通过提供使用模式洞察帮助改进 Better-T-Stack。禁用后,不会收集或传输任何数据。

API 参考

init(projectName?, options?)

创建一个新的 Better-T-Stack 项目。

参数:

  • projectName (string, 可选): 项目名称或目录路径
  • options (CreateInput, 可选): 配置选项

返回: Promise<InitResult>

示例:

const result = await init("my-project", {
  frontend: ["next"],
  backend: "hono",
  database: "postgres",
  orm: "drizzle"
});

sponsors()

显示 Better-T-Stack 赞助商(与 CLI 相同)。

返回: Promise<void>

docs()

在浏览器中打开文档(与 CLI 相同)。

返回: Promise<void>

builder()

打开基于 Web 的堆栈构建器(与 CLI 相同)。

返回: Promise<void>

类型定义

CreateInput

项目创建的配置选项:

interface CreateInput {
  projectName?: string;
  yes?: boolean;                    // 跳过提示,使用默认值
  yolo?: boolean;                   // 绕过验证(不推荐)
  verbose?: boolean;               // 显示 JSON 结果(仅 CLI,编程式始终返回结果)
  database?: Database;              // "none" | "sqlite" | "postgres" | "mysql" | "mongodb"
  orm?: ORM;                        // "none" | "drizzle" | "prisma" | "mongoose"
  auth?: boolean;                   // 包含身份验证
  frontend?: Frontend[];            // 前端框架数组
  addons?: Addons[];               // 附加组件数组
  examples?: Examples[];           // 示例数组
  git?: boolean;                   // 初始化 git 仓库
  packageManager?: PackageManager; // "npm" | "pnpm" | "bun"
  install?: boolean;               // 安装依赖
  dbSetup?: DatabaseSetup;         // 数据库托管设置
  backend?: Backend;               // 后端框架
  runtime?: Runtime;               // 运行时环境
  api?: API;                       // API 类型
  webDeploy?: WebDeploy;          // Web 部署设置
  serverDeploy?: ServerDeploy;    // 服务器部署设置
  directoryConflict?: DirectoryConflict; // "merge" | "overwrite" | "increment" | "error"
  renderTitle?: boolean;           // 显示 ASCII 艺术字标题
  disableAnalytics?: boolean;      // 禁用分析和遥测
}

InitResult

init() 返回的结果对象:

interface InitResult {
  success: boolean;                // 操作是否成功
  projectConfig: ProjectConfig;    // 最终项目配置
  reproducibleCommand: string;     // 重新创建项目的 CLI 命令
  timeScaffolded: string;          // 创建时间的 ISO 时间戳
  elapsedTimeMs: number;          // 耗时(毫秒)
  projectDirectory: string;        // 项目的绝对路径
  relativePath: string;           // 项目的相对路径
  error?: string;                 // 失败时的错误消息
}

配置选项

目录冲突解决

控制如何处理现有目录:

// 与现有文件合并(注意冲突)
directoryConflict: "merge"

// 完全覆盖现有目录
directoryConflict: "overwrite"

// 创建带有递增名称的新目录 (my-app-1)
directoryConflict: "increment"

// 如果目录存在则抛出错误
directoryConflict: "error"

标题渲染

控制 CLI 输出外观:

// 隐藏 ASCII 艺术字标题(适用于自动化脚本)
renderTitle: false

// 显示 ASCII 艺术字标题(默认)
renderTitle: true

YOLO 模式

绕过验证检查(不推荐):

// 跳过兼容性验证
yolo: true

错误处理

编程式 API 使用与 CLI 不同的错误处理:

目录冲突

目录冲突错误返回结构化结果而不是抛出异常:

const result = await init("existing-dir", {
  directoryConflict: "error"
});

if (!result.success) {
  console.log(result.error); // "目录存在且不为空..."
  // 优雅处理而不是进程退出
}

验证错误

验证错误仍然抛出异常(保持 CLI 兼容性):

try {
  await init("test", {
    database: "mongodb",
    orm: "drizzle" // 无效组合
  });
} catch (error) {
  console.error(error.message); // "MongoDB 需要 Mongoose 或 Prisma ORM"
}

从 CLI 迁移

CLI 命令到编程式 API

将 CLI 命令转换为编程式调用:

# CLI 命令
create-better-t-stack my-app \
  --frontend tanstack-router \
  --backend hono \
  --database postgres \
  --orm drizzle \
  --auth better-auth \
  --yes
// 编程式等效
const result = await init("my-app", {
  frontend: ["tanstack-router"],
  backend: "hono",
  database: "postgres",
  orm: "drizzle",
  auth: "better-auth",
  yes: true
});

处理提示

CLI 提示变为显式选项:

// 代替交互式提示,指定所有选项
const result = await init("my-app", {
  yes: true, // 跳过所有提示
  frontend: ["tanstack-router"],
  backend: "hono",
  database: "postgres",
  orm: "drizzle",
  auth: "better-auth",
  addons: ["biome", "turborepo"],
  examples: ["todo"],
  packageManager: "bun",
  install: false,
  git: true
});