Skip to content
Snippets Groups Projects
create-app.ts 3.59 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* eslint-disable import/no-extraneous-dependencies */
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
    import path from "path";
    
    import { green, yellow } from "picocolors";
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
    import { tryGitInit } from "./helpers/git";
    import { isFolderEmpty } from "./helpers/is-folder-empty";
    import { getOnline } from "./helpers/is-online";
    import { isWriteable } from "./helpers/is-writeable";
    import { makeDir } from "./helpers/make-dir";
    
    import fs from "fs";
    import terminalLink from "terminal-link";
    
    import type { InstallTemplateArgs } from "./helpers";
    import { installTemplate } from "./helpers";
    
    import { writeDevcontainer } from "./helpers/devcontainer";
    
    import { templatesDir } from "./helpers/dir";
    
    import { toolsRequireConfig } from "./helpers/tools";
    
    export type InstallAppArgs = Omit<
      InstallTemplateArgs,
      "appName" | "root" | "isOnline" | "customApiPath"
    > & {
      appPath: string;
      frontend: boolean;
    };
    
    
    export async function createApp({
    
      appPath,
      packageManager,
      eslint,
    
      openAiKey,
    
      communityProjectPath,
    
      postInstallAction,
    
      dataSource,
    
    }: InstallAppArgs): Promise<void> {
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      const root = path.resolve(appPath);
    
    
      if (!(await isWriteable(path.dirname(root)))) {
        console.error(
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
          "The application path is not writable, please check folder permissions and try again.",
        );
    
        console.error(
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
          "It is likely you do not have write permissions for this folder.",
        );
        process.exit(1);
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      const appName = path.basename(root);
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      await makeDir(root);
    
      if (!isFolderEmpty(root, appName)) {
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
        process.exit(1);
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      const useYarn = packageManager === "yarn";
      const isOnline = !useYarn || (await getOnline());
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      console.log(`Creating a new LlamaIndex app in ${green(root)}.`);
      console.log();
    
      const args = {
        appName,
        root,
        template,
        framework,
        engine,
        ui,
        packageManager,
        isOnline,
        eslint,
    
        openAiKey,
    
        communityProjectPath,
    
        postInstallAction,
    
        dataSource,
    
      if (frontend) {
        // install backend
        const backendRoot = path.join(root, "backend");
        await makeDir(backendRoot);
    
        await installTemplate({ ...args, root: backendRoot, backend: true });
    
        // install frontend
        const frontendRoot = path.join(root, "frontend");
        await makeDir(frontendRoot);
    
        await installTemplate({
          ...args,
          root: frontendRoot,
          framework: "nextjs",
          customApiPath: `http://localhost:${externalPort ?? 8000}/api/chat`,
          backend: false,
        });
    
        // copy readme for fullstack
        await fs.promises.copyFile(
    
          path.join(templatesDir, "README-fullstack.md"),
    
          path.join(root, "README.md"),
        );
      } else {
    
        await installTemplate({ ...args, backend: true, forBackend: framework });
    
      if (tryGitInit(root)) {
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
        console.log("Initialized a git repository.");
        console.log();
    
      await writeDevcontainer(root, templatesDir, framework, frontend);
    
    
      if (toolsRequireConfig(tools)) {
        console.log(
    
            `You have selected tools that require configuration. Please configure them in the ${terminalLink(
              "tools_config.json",
              `file://${root}/tools_config.json`,
            )} file.`,
          ),
        );
      }
    
      console.log("");
      console.log(`${green("Success!")} Created ${appName} at ${appPath}`);
    
      console.log(
        `Now have a look at the ${terminalLink(
          "README.md",
          `file://${root}/README.md`,
        )} and learn how to get started.`,
      );
    
    Marcus Schiesser's avatar
    Marcus Schiesser committed
      console.log();