2025-05-27 04:00:34 +00:00

172 lines
4.6 KiB
JavaScript

import { spawn } from "node:child_process";
import { fileURLToPath } from "url";
import { dirname, resolve } from "path";
import os from "os";
export default defineEventHandler(async (event) => {
try {
const { tableName, tableSchema, autoIncrementColumn } =
await readBody(event);
if (!tableName || !tableSchema) {
return {
statusCode: 400,
message: "Bad Request",
};
}
// Create Table
const isTableCreated = await createTable(
tableName,
tableSchema,
autoIncrementColumn
);
if (isTableCreated.statusCode !== 200)
return {
statusCode: 500,
message: isTableCreated.message,
};
// Run Prisma Command
const isPrismaCommandRun = await runPrismaCommand();
if (!isPrismaCommandRun)
return {
statusCode: 500,
message: "Prisma Command Failed",
};
return {
statusCode: 200,
message: "Table Created",
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
message: "Internal Server Error",
};
}
});
async function createTable(tableName, tableSchema) {
try {
let rawSchema = ``;
for (let i = 0; i < tableSchema.length; i++) {
const column = tableSchema[i];
// Sanitize rawSchema
if (column.type.includes("[[") && column.type.includes("]]")) {
const FKTableName = column.type.replace("[[", "").replace("]]", "");
const primaryKey = await prisma.$queryRawUnsafe(
"SHOW COLUMNS from " + FKTableName + " where `Key` = 'PRI'"
);
rawSchema += `${column.name} INT NOT NULL, FOREIGN KEY (${column.name}) REFERENCES ${FKTableName}(${primaryKey[0].Field})`;
} else {
rawSchema += `${column.name}
${column.type}${column.length ? "(" + column.length + ")" : ""}
${column.defaultValue ? " DEFAULT " + column.defaultValue : ""}
${column.nullable ? " NULL" : " NOT NULL "}
${column.primaryKey ? " PRIMARY KEY AUTO_INCREMENT" : ""}`;
}
if (i < tableSchema.length - 1) rawSchema += ", ";
}
const sqlStatement = `CREATE TABLE ${tableName} (${rawSchema})`;
console.log(sqlStatement);
const createTable = await prisma.$queryRawUnsafe(sqlStatement);
if (!createTable)
return {
statusCode: 500,
message: "Table Creation Failed",
};
return {
statusCode: 200,
message: "Table Created",
};
} catch (error) {
console.log(error.message);
// Get Message
if (error.message.includes("already exists")) {
return {
statusCode: 500,
message: `Table '${tableName}' already exists!`,
};
}
if (error.message.includes("1064")) {
return {
statusCode: 500,
message: "Please ensure the SQL syntax is correct!",
};
}
return {
statusCode: 500,
message: "Table Creation Failed",
};
}
}
async function runPrismaCommand() {
try {
console.log("---------- Run Prisma Command ----------");
const __dirname = dirname(fileURLToPath(import.meta.url));
const directory = resolve(__dirname, "../..");
// Command to execute
const command = "npx prisma db pull && npx prisma generate";
// Determine the appropriate shell command based on the platform
let shellCommand;
let spawnOptions;
switch (os.platform()) {
case "win32":
shellCommand = `Start-Process cmd -ArgumentList '/c cd "${directory}" && ${command}' -Verb RunAs`;
spawnOptions = {
shell: "powershell.exe",
args: ["-Command", shellCommand],
};
break;
case "darwin":
case "linux":
shellCommand = `cd "${directory}" && ${command}`;
spawnOptions = {
shell: "sh",
args: ["-c", shellCommand],
};
break;
default:
console.error("Unsupported platform:", os.platform());
return false;
}
// Spawn child process using the appropriate shell command
const childProcess = spawn(spawnOptions.shell, spawnOptions.args, {
stdio: "inherit",
});
// Listen for child process events
return new Promise((resolve, reject) => {
childProcess.on("close", (code) => {
if (code === 0) {
console.log("Prisma commands executed successfully");
resolve(true);
} else {
console.error(`Child process exited with code ${code}`);
reject(new Error(`Child process exited with code ${code}`));
}
});
});
} catch (error) {
console.error("Error running Prisma commands:", error);
return false;
}
}