mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: migration
This commit is contained in:
14
apps/mig/server/db/drizzle.config.ts
Normal file
14
apps/mig/server/db/drizzle.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { defineConfig } from "drizzle-kit";
|
||||
|
||||
export default defineConfig({
|
||||
schema: "./server/db/schema/index.ts",
|
||||
dialect: "postgresql",
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_URL || "",
|
||||
},
|
||||
out: "drizzle",
|
||||
migrations: {
|
||||
table: "migrations",
|
||||
schema: "public",
|
||||
},
|
||||
});
|
||||
21
apps/mig/server/db/index.ts
Normal file
21
apps/mig/server/db/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { type PostgresJsDatabase, drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "./schema";
|
||||
|
||||
declare global {
|
||||
var db: PostgresJsDatabase<typeof schema> | undefined;
|
||||
}
|
||||
|
||||
export let db: PostgresJsDatabase<typeof schema>;
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
db = drizzle(postgres(process.env.DATABASE_URL || ""), {
|
||||
schema,
|
||||
});
|
||||
} else {
|
||||
if (!global.db)
|
||||
global.db = drizzle(postgres(process.env.DATABASE_URL || ""), {
|
||||
schema,
|
||||
});
|
||||
|
||||
db = global.db;
|
||||
}
|
||||
21
apps/mig/server/db/migration.ts
Normal file
21
apps/mig/server/db/migration.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
||||
import postgres from "postgres";
|
||||
|
||||
const connectionString = process.env.DATABASE_URL || "";
|
||||
|
||||
const sql = postgres(connectionString, { max: 1 });
|
||||
const db = drizzle(sql);
|
||||
|
||||
export const migration = async () =>
|
||||
await migrate(db, { migrationsFolder: "drizzle" })
|
||||
.then(() => {
|
||||
console.log("Migration complete");
|
||||
sql.end();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("Migration failed", error);
|
||||
})
|
||||
.finally(() => {
|
||||
sql.end();
|
||||
});
|
||||
23
apps/mig/server/db/reset.ts
Normal file
23
apps/mig/server/db/reset.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
// Credits to Louistiti from Drizzle Discord: https://discord.com/channels/1043890932593987624/1130802621750448160/1143083373535973406
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
|
||||
const connectionString = process.env.DATABASE_URL || "";
|
||||
|
||||
const pg = postgres(connectionString, { max: 1 });
|
||||
const db = drizzle(pg);
|
||||
|
||||
const clearDb = async (): Promise<void> => {
|
||||
try {
|
||||
const tablesQuery = sql<string>`DROP SCHEMA public CASCADE; CREATE SCHEMA public; DROP schema drizzle CASCADE;`;
|
||||
const tables = await db.execute(tablesQuery);
|
||||
console.log(tables);
|
||||
await pg.end();
|
||||
} catch (error) {
|
||||
console.error("Error to clean database", error);
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
clearDb();
|
||||
1
apps/mig/server/db/schema/index.ts
Normal file
1
apps/mig/server/db/schema/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@dokploy/server/db/schema";
|
||||
35
apps/mig/server/db/seed.ts
Normal file
35
apps/mig/server/db/seed.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import bc from "bcrypt";
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import { users } from "./schema";
|
||||
|
||||
const connectionString = process.env.DATABASE_URL || "";
|
||||
|
||||
const pg = postgres(connectionString, { max: 1 });
|
||||
const db = drizzle(pg);
|
||||
|
||||
function password(txt: string) {
|
||||
return bc.hashSync(txt, 10);
|
||||
}
|
||||
|
||||
async function seed() {
|
||||
console.log("> Seed:", process.env.DATABASE_PATH, "\n");
|
||||
|
||||
// const authenticationR = await db
|
||||
// .insert(users)
|
||||
// .values([
|
||||
// {
|
||||
// email: "user1@hotmail.com",
|
||||
// password: password("12345671"),
|
||||
// },
|
||||
// ])
|
||||
// .onConflictDoNothing()
|
||||
// .returning();
|
||||
|
||||
// console.log("\nSemillas Update:", authenticationR.length);
|
||||
}
|
||||
|
||||
seed().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
46
apps/mig/server/db/validations/domain.ts
Normal file
46
apps/mig/server/db/validations/domain.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const domain = z
|
||||
.object({
|
||||
host: z.string().min(1, { message: "Add a hostname" }),
|
||||
path: z.string().min(1).optional(),
|
||||
port: z
|
||||
.number()
|
||||
.min(1, { message: "Port must be at least 1" })
|
||||
.max(65535, { message: "Port must be 65535 or below" })
|
||||
.optional(),
|
||||
https: z.boolean().optional(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]).optional(),
|
||||
})
|
||||
.superRefine((input, ctx) => {
|
||||
if (input.https && !input.certificateType) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["certificateType"],
|
||||
message: "Required",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const domainCompose = z
|
||||
.object({
|
||||
host: z.string().min(1, { message: "Host is required" }),
|
||||
path: z.string().min(1).optional(),
|
||||
port: z
|
||||
.number()
|
||||
.min(1, { message: "Port must be at least 1" })
|
||||
.max(65535, { message: "Port must be 65535 or below" })
|
||||
.optional(),
|
||||
https: z.boolean().optional(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]).optional(),
|
||||
serviceName: z.string().min(1, { message: "Service name is required" }),
|
||||
})
|
||||
.superRefine((input, ctx) => {
|
||||
if (input.https && !input.certificateType) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["certificateType"],
|
||||
message: "Required",
|
||||
});
|
||||
}
|
||||
});
|
||||
37
apps/mig/server/db/validations/index.ts
Normal file
37
apps/mig/server/db/validations/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const sshKeyCreate = z.object({
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
publicKey: z.string().refine(
|
||||
(key) => {
|
||||
const rsaPubPattern = /^ssh-rsa\s+([A-Za-z0-9+/=]+)\s*(.*)?\s*$/;
|
||||
const ed25519PubPattern = /^ssh-ed25519\s+([A-Za-z0-9+/=]+)\s*(.*)?\s*$/;
|
||||
return rsaPubPattern.test(key) || ed25519PubPattern.test(key);
|
||||
},
|
||||
{
|
||||
message: "Invalid public key format",
|
||||
},
|
||||
),
|
||||
privateKey: z.string().refine(
|
||||
(key) => {
|
||||
const rsaPrivPattern =
|
||||
/^-----BEGIN RSA PRIVATE KEY-----\n([A-Za-z0-9+/=\n]+)-----END RSA PRIVATE KEY-----\s*$/;
|
||||
const ed25519PrivPattern =
|
||||
/^-----BEGIN OPENSSH PRIVATE KEY-----\n([A-Za-z0-9+/=\n]+)-----END OPENSSH PRIVATE KEY-----\s*$/;
|
||||
return rsaPrivPattern.test(key) || ed25519PrivPattern.test(key);
|
||||
},
|
||||
{
|
||||
message: "Invalid private key format",
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
export const sshKeyUpdate = sshKeyCreate.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
});
|
||||
|
||||
export const sshKeyType = z.object({
|
||||
type: z.enum(["rsa", "ed25519"]).optional(),
|
||||
});
|
||||
Reference in New Issue
Block a user