Newer
Older
import { copy } from "../helpers/copy";
import { install } from "../helpers/install";
import fs from "fs/promises";
import os from "os";
import path from "path";
import { bold, cyan } from "picocolors";
Marcus Schiesser
committed
import { version } from "../package.json";
import { InstallTemplateArgs } from "./types";
/**
* Install a LlamaIndex internal template to a given `root` directory.
*/
const installTSTemplate = async ({
appName,
root,
packageManager,
isOnline,
template,
Marcus Schiesser
committed
framework,
engine,
/**
* Copy the template files to the target directory.
*/
console.log("\nInitializing project with template:", template, "\n");
const templatePath = path.join(__dirname, "types", template, framework);
const copySource = ["**"];
if (!eslint) copySource.push("!eslintrc.json");
await copy(copySource, root, {
parents: true,
cwd: templatePath,
rename(name) {
switch (name) {
case "gitignore":
case "eslintrc.json": {
return `.${name}`;
}
// README.md is ignored by webpack-asset-relocator-loader used by ncc:
// https://github.com/vercel/webpack-asset-relocator-loader/blob/e9308683d47ff507253e37c9bcbb99474603192b/src/asset-relocator.js#L227
/**
* Copy the selected chat engine files to the target directory and reference it.
*/
const compPath = path.join(__dirname, "components");
if (engine && (framework === "express" || framework === "nextjs")) {
console.log("\nUsing chat engine:", engine, "\n");
const enginePath = path.join(compPath, "engines", engine);
relativeEngineDestPath =
framework === "nextjs"
? path.join("app", "api", "chat")
: path.join("src", "controllers");
await copy("**", path.join(root, relativeEngineDestPath, "engine"), {
parents: true,
cwd: enginePath,
});
}
/**
* Copy the selected UI files to the target directory and reference it.
*/
if (framework === "nextjs") {
console.log("\nUsing UI:", ui, "\n");
const uiPath = path.join(compPath, "ui", ui);
const componentsPath = path.join("app", "components");
await copy("**", path.join(root, componentsPath, "ui"), {
parents: true,
cwd: uiPath,
});
}
Marcus Schiesser
committed
* Update the package.json scripts.
Marcus Schiesser
committed
const packageJsonFile = path.join(root, "package.json");
const packageJson: any = JSON.parse(
await fs.readFile(packageJsonFile, "utf8"),
);
packageJson.name = appName;
packageJson.version = "0.1.0";
Marcus Schiesser
committed
packageJson.dependencies = {
...packageJson.dependencies,
llamaindex: version,
};
if (framework === "nextjs" && customApiPath) {
console.log(
"\nUsing external API with custom API path:",
customApiPath,
"\n",
);
// remove the default api folder
const apiPath = path.join(root, "app", "api");
await fs.rm(apiPath, { recursive: true });
// modify the dev script to use the custom api path
packageJson.scripts = {
...packageJson.scripts,
dev: `NEXT_PUBLIC_CHAT_API=${customApiPath} next dev`,
};
}
if (engine === "context" && relativeEngineDestPath) {
// add generate script if using context engine
packageJson.scripts = {
...packageJson.scripts,
generate: `node ${path.join(
relativeEngineDestPath,
"engine",
"generate.mjs",
)}`,
};
}
if (framework === "nextjs" && ui === "shadcn") {
// add shadcn dependencies to package.json
packageJson.dependencies = {
...packageJson.dependencies,
"tailwind-merge": "^2",
"@radix-ui/react-slot": "^1",
"class-variance-authority": "^0.7",
"lucide-react": "^0.291",
remark: "^14.0.3",
"remark-code-import": "^1.2.0",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
};
packageJson.devDependencies = {
...packageJson.devDependencies,
"@types/react-syntax-highlighter": "^15.5.6",
Marcus Schiesser
committed
if (!eslint) {
// Remove packages starting with "eslint" from devDependencies
packageJson.devDependencies = Object.fromEntries(
Object.entries(packageJson.devDependencies).filter(
([key]) => !key.startsWith("eslint"),
),
);
Marcus Schiesser
committed
packageJsonFile,
for (const dependency in packageJson.dependencies)
Marcus Schiesser
committed
console.log("\nInstalling devDependencies:");
for (const dependency in packageJson.devDependencies)
console.log(`- ${cyan(dependency)}`);
const installPythonTemplate = async ({
}: Pick<InstallTemplateArgs, "root" | "framework" | "template">) => {
console.log("\nInitializing Python project with template:", template, "\n");
const templatePath = path.join(__dirname, "types", template, framework);
await copy("**", root, {
parents: true,
cwd: templatePath,
rename(name) {
switch (name) {
case "gitignore": {
return `.${name}`;
}
// README.md is ignored by webpack-asset-relocator-loader used by ncc:
// https://github.com/vercel/webpack-asset-relocator-loader/blob/e9308683d47ff507253e37c9bcbb99474603192b/src/asset-relocator.js#L227
case "README-template.md": {
return "README.md";
}
default: {
return name;
}
}
},
});
console.log(
"\nPython project, dependencies won't be installed automatically.\n",
);
};
export const installTemplate = async (props: InstallTemplateArgs) => {
process.chdir(props.root);
if (props.framework === "fastapi") {
await installPythonTemplate(props);
} else {
await installTSTemplate(props);
}
};