mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-19 22:25:22 +02:00
Merge branch 'canary' into feat/introduce-license-key-pay
This commit is contained in:
@@ -31,7 +31,6 @@ interface HealthCheckFormProps {
|
||||
|
||||
export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [testCommands, setTestCommands] = useState<string[]>([]);
|
||||
|
||||
const queryMap = {
|
||||
postgres: () =>
|
||||
@@ -72,6 +71,8 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
||||
},
|
||||
});
|
||||
|
||||
const testCommands = form.watch("Test") || [];
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.healthCheckSwarm) {
|
||||
const hc = data.healthCheckSwarm;
|
||||
@@ -82,7 +83,6 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
||||
StartPeriod: hc.StartPeriod,
|
||||
Retries: hc.Retries,
|
||||
});
|
||||
setTestCommands(hc.Test || []);
|
||||
}
|
||||
}, [data, form]);
|
||||
|
||||
@@ -117,17 +117,20 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
||||
};
|
||||
|
||||
const addTestCommand = () => {
|
||||
setTestCommands([...testCommands, ""]);
|
||||
form.setValue("Test", [...testCommands, ""]);
|
||||
};
|
||||
|
||||
const updateTestCommand = (index: number, value: string) => {
|
||||
const newCommands = [...testCommands];
|
||||
newCommands[index] = value;
|
||||
setTestCommands(newCommands);
|
||||
form.setValue("Test", newCommands);
|
||||
};
|
||||
|
||||
const removeTestCommand = (index: number) => {
|
||||
setTestCommands(testCommands.filter((_, i) => i !== index));
|
||||
form.setValue(
|
||||
"Test",
|
||||
testCommands.filter((_: string, i: number) => i !== index),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -140,7 +143,7 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
||||
http://localhost:3000/health"])
|
||||
</FormDescription>
|
||||
<div className="space-y-2 mt-2">
|
||||
{testCommands.map((cmd, index) => (
|
||||
{testCommands.map((cmd: string, index: number) => (
|
||||
<div key={index} className="flex gap-2">
|
||||
<Input
|
||||
value={cmd}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
export { HealthCheckForm } from "./health-check-form";
|
||||
export { RestartPolicyForm } from "./restart-policy-form";
|
||||
export { PlacementForm } from "./placement-form";
|
||||
export { UpdateConfigForm } from "./update-config-form";
|
||||
export { RollbackConfigForm } from "./rollback-config-form";
|
||||
export { ModeForm } from "./mode-form";
|
||||
export { LabelsForm } from "./labels-form";
|
||||
export { StopGracePeriodForm } from "./stop-grace-period-form";
|
||||
export { EndpointSpecForm } from "./endpoint-spec-form";
|
||||
export { HealthCheckForm } from "./health-check-form";
|
||||
export { LabelsForm } from "./labels-form";
|
||||
export { ModeForm } from "./mode-form";
|
||||
export { PlacementForm } from "./placement-form";
|
||||
export { RestartPolicyForm } from "./restart-policy-form";
|
||||
export { RollbackConfigForm } from "./rollback-config-form";
|
||||
export { StopGracePeriodForm } from "./stop-grace-period-form";
|
||||
export { UpdateConfigForm } from "./update-config-form";
|
||||
export { filterEmptyValues, hasValues } from "./utils";
|
||||
|
||||
@@ -17,9 +17,7 @@ import { Input } from "@/components/ui/input";
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
const PreferenceSchema = z.object({
|
||||
Spread: z.object({
|
||||
SpreadDescriptor: z.string(),
|
||||
}),
|
||||
SpreadDescriptor: z.string(),
|
||||
});
|
||||
|
||||
const PlatformSchema = z.object({
|
||||
@@ -116,7 +114,14 @@ export const PlacementForm = ({ id, type }: PlacementFormProps) => {
|
||||
mysqlId: id || "",
|
||||
mariadbId: id || "",
|
||||
mongoId: id || "",
|
||||
placementSwarm: hasAnyValue ? formData : null,
|
||||
placementSwarm: hasAnyValue
|
||||
? {
|
||||
...formData,
|
||||
Preferences: formData.Preferences?.map((p) => ({
|
||||
Spread: { SpreadDescriptor: p.SpreadDescriptor },
|
||||
})),
|
||||
}
|
||||
: null,
|
||||
});
|
||||
|
||||
toast.success("Placement updated successfully");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
||||
"files": {
|
||||
"ignoreUnknown": true,
|
||||
"includes": [
|
||||
"**",
|
||||
"!**/.docker",
|
||||
|
||||
@@ -47,7 +47,7 @@ import {
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { sshKeys } from "./ssh-key";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
export const sourceType = pgEnum("sourceType", [
|
||||
"docker",
|
||||
"git",
|
||||
@@ -287,7 +287,12 @@ export const applicationsRelations = relations(
|
||||
);
|
||||
|
||||
const createSchema = createInsertSchema(applications, {
|
||||
appName: z.string(),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
createdAt: z.string(),
|
||||
applicationId: z.string(),
|
||||
autoDeploy: z.boolean(),
|
||||
|
||||
@@ -16,7 +16,7 @@ import { schedules } from "./schedule";
|
||||
import { server } from "./server";
|
||||
import { applicationStatus, triggerType } from "./shared";
|
||||
import { sshKeys } from "./ssh-key";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
export const sourceTypeCompose = pgEnum("sourceTypeCompose", [
|
||||
"git",
|
||||
"github",
|
||||
@@ -147,6 +147,12 @@ export const composeRelations = relations(compose, ({ one, many }) => ({
|
||||
|
||||
const createSchema = createInsertSchema(compose, {
|
||||
name: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
description: z.string(),
|
||||
env: z.string().optional(),
|
||||
composeFile: z.string().optional(),
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
type UpdateConfigSwarm,
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
|
||||
export const mariadb = pgTable("mariadb", {
|
||||
mariadbId: text("mariadbId")
|
||||
@@ -96,7 +96,12 @@ export const mariadbRelations = relations(mariadb, ({ one, many }) => ({
|
||||
const createSchema = createInsertSchema(mariadb, {
|
||||
mariadbId: z.string(),
|
||||
name: z.string().min(1),
|
||||
appName: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
createdAt: z.string(),
|
||||
databaseName: z.string().min(1),
|
||||
databaseUser: z.string().min(1),
|
||||
@@ -138,20 +143,18 @@ const createSchema = createInsertSchema(mariadb, {
|
||||
endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),
|
||||
});
|
||||
|
||||
export const apiCreateMariaDB = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
databaseRootPassword: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
serverId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiCreateMariaDB = createSchema.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
databaseRootPassword: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
serverId: true,
|
||||
});
|
||||
|
||||
export const apiFindOneMariaDB = createSchema
|
||||
.pick({
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
type UpdateConfigSwarm,
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
|
||||
export const mongo = pgTable("mongo", {
|
||||
mongoId: text("mongoId")
|
||||
@@ -98,7 +98,12 @@ export const mongoRelations = relations(mongo, ({ one, many }) => ({
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(mongo, {
|
||||
appName: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
createdAt: z.string(),
|
||||
mongoId: z.string(),
|
||||
name: z.string().min(1),
|
||||
@@ -135,19 +140,17 @@ const createSchema = createInsertSchema(mongo, {
|
||||
endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),
|
||||
});
|
||||
|
||||
export const apiCreateMongo = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
serverId: true,
|
||||
replicaSets: true,
|
||||
})
|
||||
.required();
|
||||
export const apiCreateMongo = createSchema.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
serverId: true,
|
||||
replicaSets: true,
|
||||
});
|
||||
|
||||
export const apiFindOneMongo = createSchema
|
||||
.pick({
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
type UpdateConfigSwarm,
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
|
||||
export const mysql = pgTable("mysql", {
|
||||
mysqlId: text("mysqlId")
|
||||
@@ -93,7 +93,12 @@ export const mysqlRelations = relations(mysql, ({ one, many }) => ({
|
||||
|
||||
const createSchema = createInsertSchema(mysql, {
|
||||
mysqlId: z.string(),
|
||||
appName: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
createdAt: z.string(),
|
||||
name: z.string().min(1),
|
||||
databaseName: z.string().min(1),
|
||||
@@ -135,20 +140,18 @@ const createSchema = createInsertSchema(mysql, {
|
||||
endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),
|
||||
});
|
||||
|
||||
export const apiCreateMySql = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
databaseRootPassword: true,
|
||||
serverId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiCreateMySql = createSchema.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
databaseRootPassword: true,
|
||||
serverId: true,
|
||||
});
|
||||
|
||||
export const apiFindOneMySql = createSchema
|
||||
.pick({
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
type UpdateConfigSwarm,
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
|
||||
export const postgres = pgTable("postgres", {
|
||||
postgresId: text("postgresId")
|
||||
@@ -94,6 +94,12 @@ export const postgresRelations = relations(postgres, ({ one, many }) => ({
|
||||
const createSchema = createInsertSchema(postgres, {
|
||||
postgresId: z.string(),
|
||||
name: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
databasePassword: z
|
||||
.string()
|
||||
.regex(/^[a-zA-Z0-9@#%^&*()_+\-=[\]{}|;:,.<>?~`]*$/, {
|
||||
@@ -128,19 +134,17 @@ const createSchema = createInsertSchema(postgres, {
|
||||
endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),
|
||||
});
|
||||
|
||||
export const apiCreatePostgres = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
serverId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiCreatePostgres = createSchema.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
serverId: true,
|
||||
});
|
||||
|
||||
export const apiFindOnePostgres = createSchema
|
||||
.pick({
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
type UpdateConfigSwarm,
|
||||
UpdateConfigSwarmSchema,
|
||||
} from "./shared";
|
||||
import { generateAppName } from "./utils";
|
||||
import { APP_NAME_MESSAGE, APP_NAME_REGEX, generateAppName } from "./utils";
|
||||
|
||||
export const redis = pgTable("redis", {
|
||||
redisId: text("redisId")
|
||||
@@ -88,7 +88,12 @@ export const redisRelations = relations(redis, ({ one, many }) => ({
|
||||
|
||||
const createSchema = createInsertSchema(redis, {
|
||||
redisId: z.string(),
|
||||
appName: z.string().min(1),
|
||||
appName: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(63)
|
||||
.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)
|
||||
.optional(),
|
||||
createdAt: z.string(),
|
||||
name: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
@@ -117,17 +122,15 @@ const createSchema = createInsertSchema(redis, {
|
||||
endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),
|
||||
});
|
||||
|
||||
export const apiCreateRedis = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
serverId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiCreateRedis = createSchema.pick({
|
||||
name: true,
|
||||
appName: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
environmentId: true,
|
||||
description: true,
|
||||
serverId: true,
|
||||
});
|
||||
|
||||
export const apiFindOneRedis = createSchema
|
||||
.pick({
|
||||
|
||||
@@ -6,6 +6,12 @@ const alphabet = "abcdefghijklmnopqrstuvwxyz123456789";
|
||||
|
||||
const customNanoid = customAlphabet(alphabet, 6);
|
||||
|
||||
/** App name: letters, numbers, dots, underscores, hyphens only (no spaces). Safe for shell/Docker. */
|
||||
export const APP_NAME_REGEX = /^[a-zA-Z0-9._-]+$/;
|
||||
|
||||
export const APP_NAME_MESSAGE =
|
||||
"App name can only contain letters, numbers, dots, underscores and hyphens";
|
||||
|
||||
export const generateAppName = (type: string) => {
|
||||
const verb = faker.hacker.verb().replace(/ /g, "-");
|
||||
const adjective = faker.hacker.adjective().replace(/ /g, "-");
|
||||
|
||||
@@ -18,7 +18,7 @@ export type Mariadb = typeof mariadb.$inferSelect;
|
||||
export const createMariadb = async (input: typeof apiCreateMariaDB._type) => {
|
||||
const appName = buildAppName("mariadb", input.appName);
|
||||
|
||||
const valid = await validUniqueServerAppName(input.appName);
|
||||
const valid = await validUniqueServerAppName(appName);
|
||||
if (!valid) {
|
||||
throw new TRPCError({
|
||||
code: "CONFLICT",
|
||||
|
||||
Reference in New Issue
Block a user