Update drizzle-zod dependency and enhance deployment tracking features

- Downgraded the drizzle-zod package from version 0.7.1 to 0.5.1 for compatibility.
- Added new fields `startedAt` and `finishedAt` to the deployment schema to track deployment timing.
- Enhanced deployment creation logic to set `startedAt` and `finishedAt` timestamps during deployment processes.
- Improved the ShowDeployments and ShowSchedulesLogs components to display deployment duration using a new Badge component.
- Refactored deployment removal logic to streamline the process of cleaning up old deployments.
This commit is contained in:
Mauricio Siu
2025-05-03 00:12:49 -06:00
parent 43ab1aa7b8
commit a5fb5532fd
12 changed files with 5763 additions and 159 deletions

View File

@@ -9,12 +9,13 @@ import {
CardTitle, CardTitle,
} from "@/components/ui/card"; } from "@/components/ui/card";
import { type RouterOutputs, api } from "@/utils/api"; import { type RouterOutputs, api } from "@/utils/api";
import { RocketIcon } from "lucide-react"; import { RocketIcon, Clock } from "lucide-react";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { CancelQueues } from "./cancel-queues"; import { CancelQueues } from "./cancel-queues";
import { RefreshToken } from "./refresh-token"; import { RefreshToken } from "./refresh-token";
import { ShowDeployment } from "./show-deployment"; import { ShowDeployment } from "./show-deployment";
import { Badge } from "@/components/ui/badge";
import { formatDuration } from "../schedules/show-schedules-logs";
interface Props { interface Props {
applicationId: string; applicationId: string;
} }
@@ -96,8 +97,23 @@ export const ShowDeployments = ({ applicationId }: Props) => {
)} )}
</div> </div>
<div className="flex flex-col items-end gap-2"> <div className="flex flex-col items-end gap-2">
<div className="text-sm capitalize text-muted-foreground"> <div className="text-sm capitalize text-muted-foreground flex items-center gap-2">
<DateTooltip date={deployment.createdAt} /> <DateTooltip date={deployment.createdAt} />
{deployment.startedAt && deployment.finishedAt && (
<Badge
variant="outline"
className="text-[10px] gap-1 flex items-center"
>
<Clock className="size-3" />
{formatDuration(
Math.floor(
(new Date(deployment.finishedAt).getTime() -
new Date(deployment.startedAt).getTime()) /
1000,
),
)}
</Badge>
)}
</div> </div>
<Button <Button

View File

@@ -13,7 +13,8 @@ import {
import type { RouterOutputs } from "@/utils/api"; import type { RouterOutputs } from "@/utils/api";
import { useState } from "react"; import { useState } from "react";
import { ShowDeployment } from "../deployments/show-deployment"; import { ShowDeployment } from "../deployments/show-deployment";
import { ClipboardList } from "lucide-react"; import { ClipboardList, Clock } from "lucide-react";
import { Badge } from "@/components/ui/badge";
interface Props { interface Props {
deployments: RouterOutputs["deployment"]["all"]; deployments: RouterOutputs["deployment"]["all"];
@@ -21,6 +22,13 @@ interface Props {
children?: React.ReactNode; children?: React.ReactNode;
} }
export const formatDuration = (seconds: number) => {
if (seconds < 60) return `${seconds}s`;
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes}m ${remainingSeconds}s`;
};
export const ShowSchedulesLogs = ({ export const ShowSchedulesLogs = ({
deployments, deployments,
serverId, serverId,
@@ -73,8 +81,23 @@ export const ShowSchedulesLogs = ({
)} )}
</div> </div>
<div className="flex flex-col items-end gap-2"> <div className="flex flex-col items-end gap-2">
<div className="text-sm capitalize text-muted-foreground"> <div className="flex items-center gap-2 text-sm text-muted-foreground">
<DateTooltip date={deployment.createdAt} /> <DateTooltip date={deployment.createdAt} />
{deployment.startedAt && deployment.finishedAt && (
<Badge
variant="outline"
className="text-[10px] gap-1 flex items-center"
>
<Clock className="size-3" />
{formatDuration(
Math.floor(
(new Date(deployment.finishedAt).getTime() -
new Date(deployment.startedAt).getTime()) /
1000,
),
)}
</Badge>
)}
</div> </div>
<Button <Button

View File

@@ -9,12 +9,13 @@ import {
CardTitle, CardTitle,
} from "@/components/ui/card"; } from "@/components/ui/card";
import { type RouterOutputs, api } from "@/utils/api"; import { type RouterOutputs, api } from "@/utils/api";
import { RocketIcon } from "lucide-react"; import { RocketIcon, Clock } from "lucide-react";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { CancelQueuesCompose } from "./cancel-queues-compose"; import { CancelQueuesCompose } from "./cancel-queues-compose";
import { RefreshTokenCompose } from "./refresh-token-compose"; import { RefreshTokenCompose } from "./refresh-token-compose";
import { ShowDeploymentCompose } from "./show-deployment-compose"; import { ShowDeploymentCompose } from "./show-deployment-compose";
import { Badge } from "@/components/ui/badge";
import { formatDuration } from "@/components/dashboard/application/schedules/show-schedules-logs";
interface Props { interface Props {
composeId: string; composeId: string;
} }
@@ -96,8 +97,23 @@ export const ShowDeploymentsCompose = ({ composeId }: Props) => {
)} )}
</div> </div>
<div className="flex flex-col items-end gap-2"> <div className="flex flex-col items-end gap-2">
<div className="text-sm capitalize text-muted-foreground"> <div className="text-sm capitalize text-muted-foreground flex items-center gap-2">
<DateTooltip date={deployment.createdAt} /> <DateTooltip date={deployment.createdAt} />
{deployment.startedAt && deployment.finishedAt && (
<Badge
variant="outline"
className="text-[10px] gap-1 flex items-center"
>
<Clock className="size-3" />
{formatDuration(
Math.floor(
(new Date(deployment.finishedAt).getTime() -
new Date(deployment.startedAt).getTime()) /
1000,
),
)}
</Badge>
)}
</div> </div>
<Button <Button

View File

@@ -0,0 +1,2 @@
ALTER TABLE "deployment" ADD COLUMN "startedAt" text;--> statement-breakpoint
ALTER TABLE "deployment" ADD COLUMN "finishedAt" text;

File diff suppressed because it is too large Load Diff

View File

@@ -673,6 +673,13 @@
"when": 1746232483345, "when": 1746232483345,
"tag": "0095_friendly_cobalt_man", "tag": "0095_friendly_cobalt_man",
"breakpoints": true "breakpoints": true
},
{
"idx": 96,
"version": "7",
"when": 1746252086587,
"tag": "0096_special_may_parker",
"breakpoints": true
} }
] ]
} }

View File

@@ -104,7 +104,7 @@
"dockerode": "4.0.2", "dockerode": "4.0.2",
"dotenv": "16.4.5", "dotenv": "16.4.5",
"drizzle-orm": "^0.39.1", "drizzle-orm": "^0.39.1",
"drizzle-zod": "0.7.1", "drizzle-zod": "0.5.1",
"fancy-ansi": "^0.1.3", "fancy-ansi": "^0.1.3",
"hi-base32": "^0.5.1", "hi-base32": "^0.5.1",
"i18next": "^23.16.4", "i18next": "^23.16.4",

View File

@@ -54,7 +54,7 @@
"dockerode": "4.0.2", "dockerode": "4.0.2",
"dotenv": "16.4.5", "dotenv": "16.4.5",
"drizzle-orm": "^0.39.1", "drizzle-orm": "^0.39.1",
"drizzle-zod": "0.7.1", "drizzle-zod": "0.5.1",
"hi-base32": "^0.5.1", "hi-base32": "^0.5.1",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"lodash": "4.17.21", "lodash": "4.17.21",

View File

@@ -47,6 +47,8 @@ export const deployments = pgTable("deployment", {
createdAt: text("createdAt") createdAt: text("createdAt")
.notNull() .notNull()
.$defaultFn(() => new Date().toISOString()), .$defaultFn(() => new Date().toISOString()),
startedAt: text("startedAt"),
finishedAt: text("finishedAt"),
errorMessage: text("errorMessage"), errorMessage: text("errorMessage"),
scheduleId: text("scheduleId").references( scheduleId: text("scheduleId").references(
(): AnyPgColumn => schedules.scheduleId, (): AnyPgColumn => schedules.scheduleId,

View File

@@ -1,6 +1,6 @@
import { relations } from "drizzle-orm"; import { relations } from "drizzle-orm";
import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core"; import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
import { createInsertSchema, createUpdateSchema } from "drizzle-zod"; import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { z } from "zod"; import { z } from "zod";
import { applications } from "./application"; import { applications } from "./application";
@@ -78,6 +78,6 @@ export const schedulesRelations = relations(schedules, ({ one, many }) => ({
export const createScheduleSchema = createInsertSchema(schedules); export const createScheduleSchema = createInsertSchema(schedules);
export const updateScheduleSchema = createUpdateSchema(schedules).extend({ export const updateScheduleSchema = createScheduleSchema.extend({
scheduleId: z.string().min(1), scheduleId: z.string().min(1),
}); });

View File

@@ -59,6 +59,7 @@ export const createDeployment = async (
try { try {
await removeLastTenDeployments( await removeLastTenDeployments(
deployment.applicationId, deployment.applicationId,
"application",
application.serverId, application.serverId,
); );
const { LOGS_PATH } = paths(!!application.serverId); const { LOGS_PATH } = paths(!!application.serverId);
@@ -90,6 +91,7 @@ export const createDeployment = async (
status: "running", status: "running",
logPath: logFilePath, logPath: logFilePath,
description: deployment.description || "", description: deployment.description || "",
startedAt: new Date().toISOString(),
}) })
.returning(); .returning();
if (deploymentCreate.length === 0 || !deploymentCreate[0]) { if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
@@ -109,6 +111,8 @@ export const createDeployment = async (
logPath: "", logPath: "",
description: deployment.description || "", description: deployment.description || "",
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
startedAt: new Date().toISOString(),
finishedAt: new Date().toISOString(),
}) })
.returning(); .returning();
await updateApplicationStatus(application.applicationId, "error"); await updateApplicationStatus(application.applicationId, "error");
@@ -130,8 +134,9 @@ export const createDeploymentPreview = async (
deployment.previewDeploymentId, deployment.previewDeploymentId,
); );
try { try {
await removeLastTenPreviewDeploymenById( await removeLastTenDeployments(
deployment.previewDeploymentId, deployment.previewDeploymentId,
"previewDeployment",
previewDeployment?.application?.serverId, previewDeployment?.application?.serverId,
); );
@@ -167,6 +172,7 @@ export const createDeploymentPreview = async (
logPath: logFilePath, logPath: logFilePath,
description: deployment.description || "", description: deployment.description || "",
previewDeploymentId: deployment.previewDeploymentId, previewDeploymentId: deployment.previewDeploymentId,
startedAt: new Date().toISOString(),
}) })
.returning(); .returning();
if (deploymentCreate.length === 0 || !deploymentCreate[0]) { if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
@@ -186,6 +192,8 @@ export const createDeploymentPreview = async (
logPath: "", logPath: "",
description: deployment.description || "", description: deployment.description || "",
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
startedAt: new Date().toISOString(),
finishedAt: new Date().toISOString(),
}) })
.returning(); .returning();
await updatePreviewDeployment(deployment.previewDeploymentId, { await updatePreviewDeployment(deployment.previewDeploymentId, {
@@ -207,8 +215,9 @@ export const createDeploymentCompose = async (
) => { ) => {
const compose = await findComposeById(deployment.composeId); const compose = await findComposeById(deployment.composeId);
try { try {
await removeLastTenComposeDeployments( await removeLastTenDeployments(
deployment.composeId, deployment.composeId,
"compose",
compose.serverId, compose.serverId,
); );
const { LOGS_PATH } = paths(!!compose.serverId); const { LOGS_PATH } = paths(!!compose.serverId);
@@ -240,6 +249,7 @@ echo "Initializing deployment" >> ${logFilePath};
description: deployment.description || "", description: deployment.description || "",
status: "running", status: "running",
logPath: logFilePath, logPath: logFilePath,
startedAt: new Date().toISOString(),
}) })
.returning(); .returning();
if (deploymentCreate.length === 0 || !deploymentCreate[0]) { if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
@@ -259,6 +269,8 @@ echo "Initializing deployment" >> ${logFilePath};
logPath: "", logPath: "",
description: deployment.description || "", description: deployment.description || "",
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
startedAt: new Date().toISOString(),
finishedAt: new Date().toISOString(),
}) })
.returning(); .returning();
await updateCompose(compose.composeId, { await updateCompose(compose.composeId, {
@@ -285,14 +297,13 @@ export const createDeploymentSchedule = async (
schedule.application?.serverId || schedule.application?.serverId ||
schedule.compose?.serverId || schedule.compose?.serverId ||
schedule.server?.serverId; schedule.server?.serverId;
await removeDeploymentsSchedule(deployment.scheduleId, serverId); await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId);
const { SCHEDULES_PATH } = paths(!!serverId); const { SCHEDULES_PATH } = paths(!!serverId);
const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss");
const fileName = `${schedule.appName}-${formattedDateTime}.log`; const fileName = `${schedule.appName}-${formattedDateTime}.log`;
const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName); const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName);
if (serverId) { if (serverId) {
console.log("serverId", serverId);
const server = await findServerById(serverId); const server = await findServerById(serverId);
const command = ` const command = `
@@ -316,6 +327,7 @@ export const createDeploymentSchedule = async (
status: "running", status: "running",
logPath: logFilePath, logPath: logFilePath,
description: deployment.description || "", description: deployment.description || "",
startedAt: new Date().toISOString(),
}) })
.returning(); .returning();
if (deploymentCreate.length === 0 || !deploymentCreate[0]) { if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
@@ -336,6 +348,8 @@ export const createDeploymentSchedule = async (
logPath: "", logPath: "",
description: deployment.description || "", description: deployment.description || "",
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
startedAt: new Date().toISOString(),
finishedAt: new Date().toISOString(),
}) })
.returning(); .returning();
@@ -372,144 +386,15 @@ export const removeDeploymentsByApplicationId = async (
.returning(); .returning();
}; };
const removeLastTenDeployments = async ( const getDeploymentsByType = async (
applicationId: string, id: string,
serverId: string | null, type: "application" | "compose" | "server" | "schedule" | "previewDeployment",
) => { ) => {
const deploymentList = await db.query.deployments.findMany({ const deploymentList = await db.query.deployments.findMany({
where: eq(deployments.applicationId, applicationId), where: eq(deployments[`${type}Id`], id),
orderBy: desc(deployments.createdAt), orderBy: desc(deployments.createdAt),
}); });
return deploymentList;
if (deploymentList.length > 10) {
const deploymentsToDelete = deploymentList.slice(9);
if (serverId) {
let command = "";
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
command += `
rm -rf ${logPath};
`;
await removeDeployment(oldDeployment.deploymentId);
}
await execAsyncRemote(serverId, command);
} else {
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
if (existsSync(logPath)) {
await fsPromises.unlink(logPath);
}
await removeDeployment(oldDeployment.deploymentId);
}
}
}
};
const removeLastTenComposeDeployments = async (
composeId: string,
serverId: string | null,
) => {
const deploymentList = await db.query.deployments.findMany({
where: eq(deployments.composeId, composeId),
orderBy: desc(deployments.createdAt),
});
if (deploymentList.length > 10) {
if (serverId) {
let command = "";
const deploymentsToDelete = deploymentList.slice(9);
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
command += `
rm -rf ${logPath};
`;
await removeDeployment(oldDeployment.deploymentId);
}
await execAsyncRemote(serverId, command);
} else {
const deploymentsToDelete = deploymentList.slice(9);
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
if (existsSync(logPath)) {
await fsPromises.unlink(logPath);
}
await removeDeployment(oldDeployment.deploymentId);
}
}
}
};
export const removeLastTenPreviewDeploymenById = async (
previewDeploymentId: string,
serverId: string | null,
) => {
const deploymentList = await db.query.deployments.findMany({
where: eq(deployments.previewDeploymentId, previewDeploymentId),
orderBy: desc(deployments.createdAt),
});
if (deploymentList.length > 10) {
const deploymentsToDelete = deploymentList.slice(9);
if (serverId) {
let command = "";
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
command += `
rm -rf ${logPath};
`;
await removeDeployment(oldDeployment.deploymentId);
}
await execAsyncRemote(serverId, command);
} else {
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
if (existsSync(logPath)) {
await fsPromises.unlink(logPath);
}
await removeDeployment(oldDeployment.deploymentId);
}
}
}
};
export const removeDeploymentsSchedule = async (
scheduleId: string,
serverId?: string | null,
) => {
const deploymentList = await db.query.deployments.findMany({
where: eq(deployments.scheduleId, scheduleId),
orderBy: desc(deployments.createdAt),
});
if (deploymentList.length > 10) {
const deploymentsToDelete = deploymentList.slice(9);
if (serverId) {
let command = "";
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
command += `
rm -rf ${logPath};
`;
await removeDeployment(oldDeployment.deploymentId);
}
await execAsyncRemote(serverId, command);
} else {
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
if (existsSync(logPath)) {
await fsPromises.unlink(logPath);
}
await removeDeployment(oldDeployment.deploymentId);
}
}
}
}; };
export const removeDeployments = async (application: Application) => { export const removeDeployments = async (application: Application) => {
@@ -524,6 +409,38 @@ export const removeDeployments = async (application: Application) => {
await removeDeploymentsByApplicationId(applicationId); await removeDeploymentsByApplicationId(applicationId);
}; };
const removeLastTenDeployments = async (
id: string,
type: "application" | "compose" | "server" | "schedule" | "previewDeployment",
serverId?: string | null,
) => {
const deploymentList = await getDeploymentsByType(id, type);
if (deploymentList.length > 10) {
const deploymentsToDelete = deploymentList.slice(10);
if (serverId) {
let command = "";
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
command += `
rm -rf ${logPath};
`;
await removeDeployment(oldDeployment.deploymentId);
}
await execAsyncRemote(serverId, command);
} else {
for (const oldDeployment of deploymentsToDelete) {
const logPath = path.join(oldDeployment.logPath);
if (existsSync(logPath)) {
await fsPromises.unlink(logPath);
}
await removeDeployment(oldDeployment.deploymentId);
}
}
}
};
export const removeDeploymentsByPreviewDeploymentId = async ( export const removeDeploymentsByPreviewDeploymentId = async (
previewDeployment: PreviewDeployment, previewDeployment: PreviewDeployment,
serverId: string | null, serverId: string | null,
@@ -605,6 +522,10 @@ export const updateDeploymentStatus = async (
.update(deployments) .update(deployments)
.set({ .set({
status: deploymentStatus, status: deploymentStatus,
finishedAt:
deploymentStatus === "done" || deploymentStatus === "error"
? new Date().toISOString()
: null,
}) })
.where(eq(deployments.deploymentId, deploymentId)) .where(eq(deployments.deploymentId, deploymentId))
.returning(); .returning();

18
pnpm-lock.yaml generated
View File

@@ -302,8 +302,8 @@ importers:
specifier: ^0.39.1 specifier: ^0.39.1
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7) version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-zod: drizzle-zod:
specifier: 0.7.1 specifier: 0.5.1
version: 0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8) version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
fancy-ansi: fancy-ansi:
specifier: ^0.1.3 specifier: ^0.1.3
version: 0.1.3 version: 0.1.3
@@ -664,8 +664,8 @@ importers:
specifier: ^0.39.1 specifier: ^0.39.1
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7) version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-zod: drizzle-zod:
specifier: 0.7.1 specifier: 0.5.1
version: 0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8) version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
hi-base32: hi-base32:
specifier: ^0.5.1 specifier: ^0.5.1
version: 0.5.1 version: 0.5.1
@@ -4549,11 +4549,11 @@ packages:
sqlite3: sqlite3:
optional: true optional: true
drizzle-zod@0.7.1: drizzle-zod@0.5.1:
resolution: {integrity: sha512-nZzALOdz44/AL2U005UlmMqaQ1qe5JfanvLujiTHiiT8+vZJTBFhj3pY4Vk+L6UWyKFfNmLhk602Hn4kCTynKQ==} resolution: {integrity: sha512-C/8bvzUH/zSnVfwdSibOgFjLhtDtbKYmkbPbUCq46QZyZCH6kODIMSOgZ8R7rVjoI+tCj3k06MRJMDqsIeoS4A==}
peerDependencies: peerDependencies:
drizzle-orm: '>=0.36.0' drizzle-orm: '>=0.23.13'
zod: '>=3.0.0' zod: '*'
eastasianwidth@0.2.0: eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@@ -11191,7 +11191,7 @@ snapshots:
react: 18.2.0 react: 18.2.0
sqlite3: 5.1.7 sqlite3: 5.1.7
drizzle-zod@0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8): drizzle-zod@0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8):
dependencies: dependencies:
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7) drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
zod: 3.23.8 zod: 3.23.8