Newer
Older
/* eslint-disable import/no-extraneous-dependencies */
import retry from "async-retry";
import fs from "fs";
import path from "path";
import { cyan, green, red } from "picocolors";
import type { RepoInfo } from "./helpers/examples";
import {
downloadAndExtractExample,
downloadAndExtractRepo,
existsInRepo,
} from "./helpers/examples";
import type { PackageManager } from "./helpers/get-pkg-manager";
import { tryGitInit } from "./helpers/git";
import { install } from "./helpers/install";
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 type { TemplateMode, TemplateType } from "./templates";
import { getTemplateFile, installTemplate } from "./templates";
export class DownloadError extends Error {}
export async function createApp({
appPath,
packageManager,
example,
examplePath,
tailwind,
eslint,
srcDir,
importAlias,
}: {
appPath: string;
packageManager: PackageManager;
example?: string;
examplePath?: string;
tailwind: boolean;
eslint: boolean;
srcDir: boolean;
importAlias: string;
let repoInfo: RepoInfo | undefined;
const mode: TemplateMode = "nextjs";
const template: TemplateType = "simple";
if (error.code !== "ERR_INVALID_URL") {
console.error(error);
process.exit(1);
`"${example}"`,
)}. Only GitHub repositories are supported. Please use a GitHub URL and try again.`,
);
process.exit(1);
if (!repoInfo) {
console.error(
`Found invalid GitHub URL: ${red(
`"${example}"`,
)}. Please fix the URL and try again.`,
);
process.exit(1);
if (!found) {
console.error(
`Could not locate the repository for ${red(
`"${example}"`,
)}. Please check that the repository exists and try again.`,
);
process.exit(1);
} else if (example !== "__internal-testing-retry") {
const found = await existsInRepo(example);
if (!found) {
console.error(
`Could not locate an example named ${red(
)}. It could be due to the following:\n`,
`1. Your spelling of example ${red(
`2. You might not be connected to the internet or you are behind a proxy.`,
);
process.exit(1);
if (!(await isWriteable(path.dirname(root)))) {
console.error(
"The application path is not writable, please check folder permissions and try again.",
);
"It is likely you do not have write permissions for this folder.",
);
process.exit(1);
const useYarn = packageManager === "yarn";
const isOnline = !useYarn || (await getOnline());
const originalDirectory = process.cwd();
console.log(`Creating a new LlamaIndex app in ${green(root)}.`);
console.log();
const packageJsonPath = path.join(root, "package.json");
let hasPackageJson = false;
if (example) {
/**
* If an example repository is provided, clone it.
*/
try {
if (repoInfo) {
console.log(
`Downloading files from repo ${cyan(
example,
)}. This might take a moment.`,
);
console.log();
await retry(() => downloadAndExtractRepo(root, repoInfo2), {
retries: 3,
} else {
console.log(
`Downloading files for example ${cyan(
example,
)}. This might take a moment.`,
);
console.log();
await retry(() => downloadAndExtractExample(root, example), {
retries: 3,
}
} catch (reason) {
function isErrorLike(err: unknown): err is { message: string } {
return (
typeof (err as { message?: unknown }).message === "string"
);
isErrorLike(reason) ? reason.message : reason + "",
);
}
// Copy `.gitignore` if the application did not provide one
if (!fs.existsSync(ignorePath)) {
fs.copyFileSync(
getTemplateFile({ template, mode, file: "gitignore" }),
ignorePath,
);
}
// Copy `next-env.d.ts` to any example that is typescript
if (fs.existsSync(tsconfigPath)) {
fs.copyFileSync(
getTemplateFile({ template, mode: "nextjs", file: "next-env.d.ts" }),
path.join(root, "next-env.d.ts"),
);
console.log("Installing packages. This might take a couple of minutes.");
console.log();
await install(packageManager, isOnline);
console.log();
}
} else {
/**
* If an example repository is not provided for cloning, proceed
* by installing from a template.
*/
await installTemplate({
appName,
root,
template,
mode,
packageManager,
isOnline,
tailwind,
eslint,
srcDir,
importAlias,
console.log("Initialized a git repository.");
console.log();
if (path.join(originalDirectory, appName) === appPath) {
console.log(`${green("Success!")} Created ${appName} at ${appPath}`);
console.log("Inside that directory, you can run several commands:");
console.log();
console.log(cyan(` ${packageManager} ${useYarn ? "" : "run "}dev`));
console.log(" Starts the development server.");
console.log();
console.log(cyan(` ${packageManager} ${useYarn ? "" : "run "}build`));
console.log(" Builds the app for production.");
console.log();
console.log(cyan(` ${packageManager} start`));
console.log(" Runs the built app in production mode.");
console.log();
console.log("We suggest that you begin by typing:");
console.log();
console.log(cyan(" cd"), cdpath);
console.log(` ${cyan(`${packageManager} ${useYarn ? "" : "run "}dev`)}`);