mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: add openapi and swagger support
This commit is contained in:
@@ -23,6 +23,8 @@ import { dockerRouter } from "./routers/docker";
|
||||
import { composeRouter } from "./routers/compose";
|
||||
import { registryRouter } from "./routers/registry";
|
||||
import { clusterRouter } from "./routers/cluster";
|
||||
import { generateOpenAPIDocumentFromTRPCRouter } from "openapi-trpc";
|
||||
|
||||
/**
|
||||
* This is the primary router for your server.
|
||||
*
|
||||
@@ -39,6 +41,7 @@ export const appRouter = createTRPCRouter({
|
||||
redis: redisRouter,
|
||||
mongo: mongoRouter,
|
||||
mariadb: mariadbRouter,
|
||||
compose: composeRouter,
|
||||
user: userRouter,
|
||||
domain: domainRouter,
|
||||
destination: destinationRouter,
|
||||
@@ -50,10 +53,15 @@ export const appRouter = createTRPCRouter({
|
||||
security: securityRouter,
|
||||
redirects: redirectsRouter,
|
||||
port: portRouter,
|
||||
compose: composeRouter,
|
||||
registry: registryRouter,
|
||||
cluster: clusterRouter,
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
export type AppRouter = typeof appRouter;
|
||||
export const doc = generateOpenAPIDocumentFromTRPCRouter(appRouter, {
|
||||
pathPrefix: "/api/trpc",
|
||||
processOperation(op) {
|
||||
op.security = [{ bearerAuth: [] }];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,13 +27,15 @@ import { createAppAuth } from "@octokit/auth-app";
|
||||
import { haveGithubRequirements } from "@/server/utils/providers/github";
|
||||
|
||||
export const adminRouter = createTRPCRouter({
|
||||
one: adminProcedure.query(async () => {
|
||||
const { sshPrivateKey, ...rest } = await findAdmin();
|
||||
return {
|
||||
haveSSH: !!sshPrivateKey,
|
||||
...rest,
|
||||
};
|
||||
}),
|
||||
one: adminProcedure
|
||||
.meta({ openapi: { method: "GET", path: "/say-hello" } })
|
||||
.query(async () => {
|
||||
const { sshPrivateKey, ...rest } = await findAdmin();
|
||||
return {
|
||||
haveSSH: !!sshPrivateKey,
|
||||
...rest,
|
||||
};
|
||||
}),
|
||||
createUserInvitation: adminProcedure
|
||||
.input(apiCreateUserInvitation)
|
||||
.mutation(async ({ input }) => {
|
||||
|
||||
@@ -59,29 +59,6 @@ export const projectRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
createCLI: protectedProcedure
|
||||
.input(apiCreateProject)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
try {
|
||||
console.log(ctx);
|
||||
if (ctx.user.rol === "user") {
|
||||
await checkProjectAccess(ctx.user.authId, "create");
|
||||
}
|
||||
const project = await createProject(input);
|
||||
if (ctx.user.rol === "user") {
|
||||
await addNewProject(ctx.user.authId, project.projectId);
|
||||
}
|
||||
|
||||
return project;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to create the project",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
one: protectedProcedure
|
||||
.input(apiFindOneProject)
|
||||
.query(async ({ input, ctx }) => {
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
} from "../services/settings";
|
||||
import { canAccessToTraefikFiles } from "../services/user";
|
||||
import { recreateDirectory } from "@/server/utils/filesystem/directory";
|
||||
import { doc } from "../root";
|
||||
|
||||
export const settingsRouter = createTRPCRouter({
|
||||
reloadServer: adminProcedure.mutation(async () => {
|
||||
@@ -242,5 +243,22 @@ export const settingsRouter = createTRPCRouter({
|
||||
}
|
||||
return readConfigInPath(input.path);
|
||||
}),
|
||||
|
||||
getOpenApiDocument: protectedProcedure.query((): unknown => {
|
||||
doc.components = {
|
||||
securitySchemes: {
|
||||
bearerAuth: {
|
||||
type: "http",
|
||||
scheme: "bearer",
|
||||
bearerFormat: "JWT",
|
||||
},
|
||||
},
|
||||
};
|
||||
doc.info = {
|
||||
title: "Dokploy API",
|
||||
description: "Endpoints for dokploy",
|
||||
version: getDokployVersion(),
|
||||
};
|
||||
return doc;
|
||||
}),
|
||||
});
|
||||
// apt-get install apache2-utils
|
||||
|
||||
@@ -16,11 +16,15 @@ import { createTraefikConfig } from "@/server/utils/traefik/application";
|
||||
import { docker } from "@/server/constants";
|
||||
import { getAdvancedStats } from "@/server/monitoring/utilts";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
export type Application = typeof applications.$inferSelect;
|
||||
|
||||
export const createApplication = async (
|
||||
input: typeof apiCreateApplication._type,
|
||||
) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("app");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -14,10 +14,14 @@ import { COMPOSE_PATH } from "@/server/constants";
|
||||
import { cloneGithubRepository } from "@/server/utils/providers/github";
|
||||
import { cloneGitRepository } from "@/server/utils/providers/git";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
|
||||
export type Compose = typeof compose.$inferSelect;
|
||||
|
||||
export const createCompose = async (input: typeof apiCreateCompose._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("compose");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -6,10 +6,14 @@ import { pullImage } from "@/server/utils/docker/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq, getTableColumns } from "drizzle-orm";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
|
||||
export type Mariadb = typeof mariadb.$inferSelect;
|
||||
|
||||
export const createMariadb = async (input: typeof apiCreateMariaDB._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("mariadb");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -6,10 +6,14 @@ import { pullImage } from "@/server/utils/docker/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq, getTableColumns } from "drizzle-orm";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
|
||||
export type Mongo = typeof mongo.$inferSelect;
|
||||
|
||||
export const createMongo = async (input: typeof apiCreateMongo._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("postgres");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -6,10 +6,15 @@ import { pullImage } from "@/server/utils/docker/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq, getTableColumns } from "drizzle-orm";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
|
||||
export type MySql = typeof mysql.$inferSelect;
|
||||
|
||||
export const createMysql = async (input: typeof apiCreateMySql._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("mysql");
|
||||
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -6,10 +6,14 @@ import { pullImage } from "@/server/utils/docker/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq, getTableColumns } from "drizzle-orm";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
|
||||
export type Postgres = typeof postgres.$inferSelect;
|
||||
|
||||
export const createPostgres = async (input: typeof apiCreatePostgres._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("postgres");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -6,11 +6,15 @@ import { pullImage } from "@/server/utils/docker/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { validUniqueServerAppName } from "./project";
|
||||
import { generateAppName } from "@/server/db/schema/utils";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
|
||||
export type Redis = typeof redis.$inferSelect;
|
||||
|
||||
// https://github.com/drizzle-team/drizzle-orm/discussions/1483#discussioncomment-7523881
|
||||
export const createRedis = async (input: typeof apiCreateRedis._type) => {
|
||||
input.appName =
|
||||
`${input.appName}-${generatePassword(6)}` || generateAppName("redis");
|
||||
if (input.appName) {
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import superjson from "superjson";
|
||||
import { ZodError } from "zod";
|
||||
import { validateBearerToken, validateRequest } from "../auth/auth";
|
||||
import type { Session, User } from "lucia";
|
||||
import type { OperationMeta } from "openapi-trpc";
|
||||
|
||||
/**
|
||||
* 1. CONTEXT
|
||||
@@ -94,19 +95,22 @@ export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
||||
* errors on the backend.
|
||||
*/
|
||||
|
||||
const t = initTRPC.context<typeof createTRPCContext>().create({
|
||||
transformer: superjson,
|
||||
errorFormatter({ shape, error }) {
|
||||
return {
|
||||
...shape,
|
||||
data: {
|
||||
...shape.data,
|
||||
zodError:
|
||||
error.cause instanceof ZodError ? error.cause.flatten() : null,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
const t = initTRPC
|
||||
.meta<OperationMeta>()
|
||||
.context<typeof createTRPCContext>()
|
||||
.create({
|
||||
transformer: superjson,
|
||||
errorFormatter({ shape, error }) {
|
||||
return {
|
||||
...shape,
|
||||
data: {
|
||||
...shape.data,
|
||||
zodError:
|
||||
error.cause instanceof ZodError ? error.cause.flatten() : null,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
|
||||
|
||||
Reference in New Issue
Block a user