diff --git a/apps/dokploy/__test__/libsql/create-schema.test.ts b/apps/dokploy/__test__/libsql/create-schema.test.ts new file mode 100644 index 000000000..c8e398079 --- /dev/null +++ b/apps/dokploy/__test__/libsql/create-schema.test.ts @@ -0,0 +1,66 @@ +import { apiCreateLibsql } from "@dokploy/server/db/schema"; +import { APP_NAME_MESSAGE } from "@dokploy/server/db/schema/utils"; +import { describe, expect, it } from "vitest"; + +describe("apiCreateLibsql appName", () => { + const validBase = { + name: "My libSQL", + dockerImage: "ghcr.io/tursodatabase/libsql-server:v0.24.32", + environmentId: "env-1", + description: null, + databaseUser: "admin", + databasePassword: "secretPassword1", + sqldNode: "primary" as const, + sqldPrimaryUrl: null, + enableNamespaces: false, + serverId: null, + }; + + it.each([ + ["a space", "my libsql"], + ["an at sign", "repro@lib"], + ["a slash", "team/libsql"], + ["a colon", "libsql:1"], + ])("refuses an appName with %s", (_, appName) => { + const result = apiCreateLibsql.safeParse({ ...validBase, appName }); + expect(result.success).toBe(false); + if (!result.success) { + const appNameIssues = result.error.issues.filter( + (issue) => issue.path[0] === "appName", + ); + expect(appNameIssues.map((issue) => issue.message)).toEqual([ + APP_NAME_MESSAGE, + ]); + } + }); + + it("accepts an appName of letters, numbers, dots, underscores and hyphens", () => { + const result = apiCreateLibsql.safeParse({ + ...validBase, + appName: "my-libsql.db_1", + }); + expect(result.success).toBe(true); + }); + + it("refuses an appName longer than 63 characters", () => { + const result = apiCreateLibsql.safeParse({ + ...validBase, + appName: "a".repeat(64), + }); + expect(result.success).toBe(false); + if (!result.success) { + const appNameIssues = result.error.issues.filter( + (issue) => issue.path[0] === "appName", + ); + expect(appNameIssues.map((issue) => issue.code)).toEqual(["too_big"]); + } + }); + + it("accepts an appName of 63 characters", () => { + const result = apiCreateLibsql.safeParse({ + ...validBase, + appName: "a".repeat(63), + }); + expect(result.success).toBe(true); + }); +}); diff --git a/packages/server/src/db/schema/libsql.ts b/packages/server/src/db/schema/libsql.ts index 0307991ae..9658ad93a 100644 --- a/packages/server/src/db/schema/libsql.ts +++ b/packages/server/src/db/schema/libsql.ts @@ -35,6 +35,8 @@ import { UpdateConfigSwarmSchema, } from "./shared"; import { + APP_NAME_MESSAGE, + APP_NAME_REGEX, DATABASE_PASSWORD_MESSAGE, DATABASE_PASSWORD_REGEX, encryptedText, @@ -115,7 +117,7 @@ export const libsqlRelations = relations(libsql, ({ one, many }) => ({ const createSchema = createInsertSchema(libsql, { libsqlId: 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), createdAt: z.string(), databaseUser: z.string().min(1), databasePassword: z.string().regex(DATABASE_PASSWORD_REGEX, {