UNPKG

sensai

Version:

Because even AI needs a master

132 lines (131 loc) 4.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return _default; } }); const _promises = require("node:fs/promises"); const _nodepath = require("node:path"); const _nodechild_process = require("node:child_process"); const _fs = require("../utils/fs"); const _constants = require("../constants"); const _object = require("../utils/object"); const _default = async ()=>{ try { await Promise.all([ setupSensaiTypes(), setupTsConfig(), setupPackageJson(), setupGitIgnore() ]); } catch (error) { // TODO we should never have errors or make sure one error does not prevent the others to run console.error(error); } }; /** * Add types needed by sensai to facilitate developement experience with Typescript. * Those types are added to the artifacts folder `.sensai` as they should never be modified * by the user. * * @note we will rewrite sensai types everytime the user runs the development server. */ const setupSensaiTypes = async (rootPath = process.cwd())=>{ const artifacts = (0, _nodepath.join)(rootPath, `.${_constants.ARTIFACTS_NAMESPACE}`, "types"); await (0, _promises.mkdir)(artifacts, { recursive: true }); await (0, _fs.write)((0, _nodepath.join)(artifacts, "sensai.d.ts"), ` declare global { const guard: typeof import('sensai/guard')['default'] } export { guard } `); }; /** * Create or update typescript configuration file (tsconfig.json) */ const setupTsConfig = async (rootPath = process.cwd())=>{ const filePath = (0, _nodepath.join)(rootPath, "tsconfig.json"); const hasTsConfig = await (0, _fs.hasFile)(filePath); const config = { exclude: [ "node_modules", "dist" ], include: [ ".sensai/types/**/*.ts", "**/*.ts", "**/*.tsx" ] }; if (hasTsConfig) { try { const { default: json } = require(filePath); // console.log("UPDATE TSCONFIG"); await (0, _fs.write)(filePath, JSON.stringify((0, _object.merge)(json, config), null, 2)); } catch (error) { console.error(error); } } else { // console.log("CREATE TSCONFIG"); await (0, _fs.write)(filePath, JSON.stringify(config, null, 2)); } }; /** * Install dependencies such as typescript and node types if they are missing. */ const setupPackageJson = async ()=>{ // filter dependencies to install const deps = (await Promise.all([ "typescript", "@types/node" ].map(async (name)=>{ const bool = await hasDependency(name); if (!bool) return name; }))).filter(Boolean); if (deps.length > 0) await installDevDependency(deps); }; // TODO We might need a more robust solution, as a dependency might exist in node_modules but not in the package.json const hasDependency = async (name)=>{ const depPath = (0, _nodepath.join)(process.cwd(), "node_modules", name); return (0, _fs.hasFile)(depPath); }; const installDevDependency = async (deps, engine = getPackageManager())=>{ return new Promise(async (resolve, reject)=>{ (0, _nodechild_process.exec)(`${engine} install --save-dev ${deps.join(" ")}`, (error, _stdout, stderr)=>{ if (error) { reject(error); return; } if (stderr) { reject(stderr); return; } resolve(true); }); }); }; /** * Get package manager. */ const getPackageManager = ()=>{ const userAgent = process.env.npm_config_user_agent || ""; if (userAgent.startsWith("pnpm")) return "pnpm"; if (userAgent.startsWith("yarn")) return "yarn"; if (userAgent.startsWith("bun")) return "bun"; return "npm"; }; const artifactsRegexp = new RegExp(`(^|\\n)\\.${_constants.ARTIFACTS_NAMESPACE}(\/)?($|\\n)`); /** * We will silently add sensai artofacts to the git ignore file if it exists. */ const setupGitIgnore = async (rootPath = process.cwd())=>{ const filePath = (0, _nodepath.join)(rootPath, ".gitignore"); if (await (0, _fs.hasFile)(filePath)) { const gitignore = await (0, _promises.readFile)(filePath, "utf-8"); const hasIgnore = artifactsRegexp.test(gitignore); if (!hasIgnore) { await (0, _fs.write)(filePath, `${gitignore}\n\n# Sensai build artifacts\n.${_constants.ARTIFACTS_NAMESPACE}/`); } } };