mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-05-19 06:03:01 -04:00
chore(deps): bump drizzle-orm from 1.0.0-beta.9-e89174b to 1.0.0-beta.15-859cf75 (#501)
* chore(deps): bump drizzle-orm Bumps [drizzle-orm](https://github.com/drizzle-team/drizzle-orm) from 1.0.0-beta.9-e89174b to 1.0.0-beta.15-859cf75. - [Release notes](https://github.com/drizzle-team/drizzle-orm/releases) - [Commits](https://github.com/drizzle-team/drizzle-orm/commits) --- updated-dependencies: - dependency-name: drizzle-orm dependency-version: 1.0.0-beta.15-859cf75 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * refactor: convert async transactions to sync + .run() * chore: formatting * chore: add lefthook dep --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nicolas Meienberger <github@thisprops.com>
This commit is contained in:
@@ -38,20 +38,22 @@ const assignUserToOrganization = async (userId: string, organizationId: string)
|
||||
|
||||
const existingMembership = await db.query.member.findFirst({ where: { userId } });
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
db.transaction((tx) => {
|
||||
if (existingMembership) {
|
||||
await tx.update(member).set({ organizationId }).where(eq(member.id, existingMembership.id));
|
||||
tx.update(member).set({ organizationId }).where(eq(member.id, existingMembership.id)).run();
|
||||
} else {
|
||||
await tx.insert(member).values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
organizationId,
|
||||
userId,
|
||||
role: "member",
|
||||
createdAt: new Date(),
|
||||
});
|
||||
tx.insert(member)
|
||||
.values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
organizationId,
|
||||
userId,
|
||||
role: "member",
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
await tx.delete(sessionsTable).where(eq(sessionsTable.userId, userId));
|
||||
tx.delete(sessionsTable).where(eq(sessionsTable.userId, userId)).run();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ const changeUsername = async (oldUsername: string, newUsername: string) => {
|
||||
);
|
||||
}
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.update(usersTable).set({ username: normalizedUsername }).where(eq(usersTable.id, user.id));
|
||||
await tx.delete(sessionsTable).where(eq(sessionsTable.userId, user.id));
|
||||
db.transaction((tx) => {
|
||||
tx.update(usersTable).set({ username: normalizedUsername }).where(eq(usersTable.id, user.id)).run();
|
||||
tx.delete(sessionsTable).where(eq(sessionsTable.userId, user.id)).run();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ const disable2FA = async (username: string) => {
|
||||
throw new Error(`User "${username}" does not have 2FA enabled`);
|
||||
}
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.update(usersTable).set({ twoFactorEnabled: false }).where(eq(usersTable.id, user.id));
|
||||
await tx.delete(twoFactor).where(eq(twoFactor.userId, user.id));
|
||||
db.transaction((tx) => {
|
||||
tx.update(usersTable).set({ twoFactorEnabled: false }).where(eq(usersTable.id, user.id)).run();
|
||||
tx.delete(twoFactor).where(eq(twoFactor.userId, user.id)).run();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -47,36 +47,50 @@ const resolveLegacySecret = async (options: { legacySecret?: string; legacySecre
|
||||
const rekeyTwoFactor = async (legacySecret: string) => {
|
||||
const legacyAuthSecret = await deriveSecretFromBase(legacySecret, "better-auth");
|
||||
const currentAuthSecret = await cryptoUtils.deriveSecret("better-auth");
|
||||
const records = await db.query.twoFactor.findMany({});
|
||||
const errors: Array<{ userId: string; error: string }> = [];
|
||||
const updates: Array<{ id: string; userId: string; secret: string; backupCodes: string }> = [];
|
||||
|
||||
return db.transaction(async (tx) => {
|
||||
const records = await tx.query.twoFactor.findMany({});
|
||||
const errors: Array<{ userId: string; error: string }> = [];
|
||||
let updated = 0;
|
||||
for (const record of records) {
|
||||
try {
|
||||
const decryptedSecret = await symmetricDecrypt({ key: legacyAuthSecret, data: record.secret });
|
||||
const decryptedBackupCodes = await symmetricDecrypt({
|
||||
key: legacyAuthSecret,
|
||||
data: record.backupCodes,
|
||||
});
|
||||
|
||||
for (const record of records) {
|
||||
updates.push({
|
||||
id: record.id,
|
||||
userId: record.userId,
|
||||
secret: await symmetricEncrypt({ key: currentAuthSecret, data: decryptedSecret }),
|
||||
backupCodes: await symmetricEncrypt({ key: currentAuthSecret, data: decryptedBackupCodes }),
|
||||
});
|
||||
} catch (error) {
|
||||
errors.push({ userId: record.userId, error: toMessage(error) });
|
||||
}
|
||||
}
|
||||
|
||||
let updated = 0;
|
||||
|
||||
db.transaction((tx) => {
|
||||
for (const record of updates) {
|
||||
try {
|
||||
const decryptedSecret = await symmetricDecrypt({ key: legacyAuthSecret, data: record.secret });
|
||||
const decryptedBackupCodes = await symmetricDecrypt({
|
||||
key: legacyAuthSecret,
|
||||
data: record.backupCodes,
|
||||
});
|
||||
|
||||
await tx
|
||||
.update(twoFactor)
|
||||
tx.update(twoFactor)
|
||||
.set({
|
||||
secret: await symmetricEncrypt({ key: currentAuthSecret, data: decryptedSecret }),
|
||||
backupCodes: await symmetricEncrypt({ key: currentAuthSecret, data: decryptedBackupCodes }),
|
||||
secret: record.secret,
|
||||
backupCodes: record.backupCodes,
|
||||
})
|
||||
.where(eq(twoFactor.id, record.id));
|
||||
.where(eq(twoFactor.id, record.id))
|
||||
.run();
|
||||
|
||||
updated += 1;
|
||||
} catch (error) {
|
||||
errors.push({ userId: record.userId, error: toMessage(error) });
|
||||
}
|
||||
}
|
||||
|
||||
return { total: records.length, updated, errors };
|
||||
});
|
||||
|
||||
return { total: records.length, updated, errors };
|
||||
};
|
||||
|
||||
export const rekey2FACommand = new Command("rekey-2fa")
|
||||
|
||||
@@ -18,19 +18,19 @@ const resetPassword = async (username: string, newPassword: string) => {
|
||||
}
|
||||
|
||||
const newPasswordHash = await hashPassword(newPassword);
|
||||
const legacyHash = user.passwordHash ? await Bun.password.hash(newPassword) : null;
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
await tx
|
||||
.update(account)
|
||||
db.transaction((tx) => {
|
||||
tx.update(account)
|
||||
.set({ password: newPasswordHash })
|
||||
.where(and(eq(account.userId, user.id), eq(account.providerId, "credential")));
|
||||
.where(and(eq(account.userId, user.id), eq(account.providerId, "credential")))
|
||||
.run();
|
||||
|
||||
if (user.passwordHash) {
|
||||
const legacyHash = await Bun.password.hash(newPassword);
|
||||
await tx.update(usersTable).set({ passwordHash: legacyHash }).where(eq(usersTable.id, user.id));
|
||||
if (legacyHash) {
|
||||
tx.update(usersTable).set({ passwordHash: legacyHash }).where(eq(usersTable.id, user.id)).run();
|
||||
}
|
||||
|
||||
await tx.delete(sessionsTable).where(eq(sessionsTable.userId, user.id));
|
||||
tx.delete(sessionsTable).where(eq(sessionsTable.userId, user.id)).run();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -27,72 +27,91 @@ export const convertLegacyUserOnFirstLogin = async (ctx: AuthMiddlewareContext)
|
||||
const isValid = await Bun.password.verify(body.password, legacyUser.passwordHash ?? "");
|
||||
|
||||
if (isValid) {
|
||||
await db.transaction(async (tx) => {
|
||||
const newUserId = crypto.randomUUID();
|
||||
const accountId = crypto.randomUUID();
|
||||
const newUserId = crypto.randomUUID();
|
||||
const accountId = crypto.randomUUID();
|
||||
|
||||
const oldMembership = await tx.query.member.findFirst({
|
||||
where: { userId: legacyUser.id },
|
||||
with: {
|
||||
organization: true,
|
||||
},
|
||||
});
|
||||
const oldMembership = await db.query.member.findFirst({
|
||||
where: { userId: legacyUser.id },
|
||||
with: {
|
||||
organization: true,
|
||||
},
|
||||
});
|
||||
|
||||
await tx.delete(usersTable).where(eq(usersTable.id, legacyUser.id));
|
||||
const passwordHash = await hashPassword(body.password);
|
||||
|
||||
await tx.insert(usersTable).values({
|
||||
id: newUserId,
|
||||
username: legacyUser.username,
|
||||
email: legacyUser.email,
|
||||
name: legacyUser.name,
|
||||
hasDownloadedResticPassword: legacyUser.hasDownloadedResticPassword,
|
||||
emailVerified: false,
|
||||
role: "admin", // In legacy system, the only user is an admin
|
||||
});
|
||||
let newOrganizationData: {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
createdAt: Date;
|
||||
metadata: {
|
||||
resticPassword: string;
|
||||
};
|
||||
} | null = null;
|
||||
|
||||
await tx.insert(account).values({
|
||||
id: accountId,
|
||||
providerId: "credential",
|
||||
accountId: legacyUser.username,
|
||||
userId: newUserId,
|
||||
password: await hashPassword(body.password),
|
||||
if (!oldMembership?.organization) {
|
||||
const resticPassword = cryptoUtils.generateResticPassword();
|
||||
newOrganizationData = {
|
||||
id: Bun.randomUUIDv7(),
|
||||
name: `${legacyUser.name}'s Workspace`,
|
||||
slug: legacyUser.email.split("@")[0] + "-" + Math.random().toString(36).slice(-4),
|
||||
createdAt: new Date(),
|
||||
});
|
||||
metadata: {
|
||||
resticPassword: await cryptoUtils.sealSecret(resticPassword),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
db.transaction((tx) => {
|
||||
tx.delete(usersTable).where(eq(usersTable.id, legacyUser.id)).run();
|
||||
|
||||
tx.insert(usersTable)
|
||||
.values({
|
||||
id: newUserId,
|
||||
username: legacyUser.username,
|
||||
email: legacyUser.email,
|
||||
name: legacyUser.name,
|
||||
hasDownloadedResticPassword: legacyUser.hasDownloadedResticPassword,
|
||||
emailVerified: false,
|
||||
role: "admin", // In legacy system, the only user is an admin
|
||||
})
|
||||
.run();
|
||||
|
||||
tx.insert(account)
|
||||
.values({
|
||||
id: accountId,
|
||||
providerId: "credential",
|
||||
accountId: legacyUser.username,
|
||||
userId: newUserId,
|
||||
password: passwordHash,
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.run();
|
||||
|
||||
// Migrate organization membership to the new user
|
||||
// The old membership was cascade-deleted when the old user was deleted
|
||||
if (oldMembership?.organization) {
|
||||
await tx.insert(member).values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: newUserId,
|
||||
organizationId: oldMembership.organization.id,
|
||||
role: oldMembership.role,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
} else {
|
||||
const orgId = Bun.randomUUIDv7();
|
||||
const slug = legacyUser.email.split("@")[0] + "-" + Math.random().toString(36).slice(-4);
|
||||
tx.insert(member)
|
||||
.values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: newUserId,
|
||||
organizationId: oldMembership.organization.id,
|
||||
role: oldMembership.role,
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.run();
|
||||
} else if (newOrganizationData) {
|
||||
tx.insert(organization).values(newOrganizationData).run();
|
||||
|
||||
const resticPassword = cryptoUtils.generateResticPassword();
|
||||
const metadata = {
|
||||
resticPassword: await cryptoUtils.sealSecret(resticPassword),
|
||||
};
|
||||
|
||||
await tx.insert(organization).values({
|
||||
id: orgId,
|
||||
name: `${legacyUser.name}'s Workspace`,
|
||||
slug: slug,
|
||||
createdAt: new Date(),
|
||||
metadata,
|
||||
});
|
||||
|
||||
await tx.insert(member).values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: newUserId,
|
||||
organizationId: orgId,
|
||||
role: "owner",
|
||||
createdAt: new Date(),
|
||||
});
|
||||
tx.insert(member)
|
||||
.values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: newUserId,
|
||||
organizationId: newOrganizationData.id,
|
||||
role: "owner",
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.run();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -6,32 +6,19 @@ import {
|
||||
type MiddlewareOptions,
|
||||
} from "better-auth";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import {
|
||||
admin,
|
||||
createAuthMiddleware,
|
||||
twoFactor,
|
||||
username,
|
||||
organization,
|
||||
} from "better-auth/plugins";
|
||||
import { admin, createAuthMiddleware, twoFactor, username, organization } from "better-auth/plugins";
|
||||
import { UnauthorizedError } from "http-errors-enhanced";
|
||||
import { convertLegacyUserOnFirstLogin } from "./auth-middlewares/convert-legacy-user";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { config } from "../core/config";
|
||||
import { db } from "../db/db";
|
||||
import { cryptoUtils } from "../utils/crypto";
|
||||
import {
|
||||
organization as organizationTable,
|
||||
member,
|
||||
usersTable,
|
||||
} from "../db/schema";
|
||||
import { organization as organizationTable, member, usersTable } from "../db/schema";
|
||||
import { ensureOnlyOneUser } from "./auth-middlewares/only-one-user";
|
||||
import { authService } from "../modules/auth/auth.service";
|
||||
import { tanstackStartCookies } from "better-auth/tanstack-start";
|
||||
|
||||
export type AuthMiddlewareContext = MiddlewareContext<
|
||||
MiddlewareOptions,
|
||||
AuthContext<BetterAuthOptions>
|
||||
>;
|
||||
export type AuthMiddlewareContext = MiddlewareContext<MiddlewareOptions, AuthContext<BetterAuthOptions>>;
|
||||
|
||||
export const auth = betterAuth({
|
||||
secret: await cryptoUtils.deriveSecret("better-auth"),
|
||||
@@ -72,45 +59,41 @@ export const auth = betterAuth({
|
||||
return { data: user };
|
||||
},
|
||||
after: async (user) => {
|
||||
const slug =
|
||||
user.email.split("@")[0] +
|
||||
"-" +
|
||||
Math.random().toString(36).slice(-4);
|
||||
const slug = user.email.split("@")[0] + "-" + Math.random().toString(36).slice(-4);
|
||||
|
||||
const resticPassword = cryptoUtils.generateResticPassword();
|
||||
const metadata = {
|
||||
resticPassword:
|
||||
await cryptoUtils.sealSecret(resticPassword),
|
||||
resticPassword: await cryptoUtils.sealSecret(resticPassword),
|
||||
};
|
||||
|
||||
try {
|
||||
await db.transaction(async (tx) => {
|
||||
db.transaction((tx) => {
|
||||
const orgId = Bun.randomUUIDv7();
|
||||
|
||||
await tx.insert(organizationTable).values({
|
||||
name: `${user.name}'s Workspace`,
|
||||
slug: slug,
|
||||
id: orgId,
|
||||
createdAt: new Date(),
|
||||
metadata,
|
||||
});
|
||||
tx.insert(organizationTable)
|
||||
.values({
|
||||
name: `${user.name}'s Workspace`,
|
||||
slug: slug,
|
||||
id: orgId,
|
||||
createdAt: new Date(),
|
||||
metadata,
|
||||
})
|
||||
.run();
|
||||
|
||||
await tx.insert(member).values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: user.id,
|
||||
role: "owner",
|
||||
organizationId: orgId,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
tx.insert(member)
|
||||
.values({
|
||||
id: Bun.randomUUIDv7(),
|
||||
userId: user.id,
|
||||
role: "owner",
|
||||
organizationId: orgId,
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.run();
|
||||
});
|
||||
} catch {
|
||||
await db
|
||||
.delete(usersTable)
|
||||
.where(eq(usersTable.id, user.id));
|
||||
await db.delete(usersTable).where(eq(usersTable.id, user.id));
|
||||
|
||||
throw new Error(
|
||||
`Failed to create organization for user ${user.id}`,
|
||||
);
|
||||
throw new Error(`Failed to create organization for user ${user.id}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -123,9 +106,7 @@ export const auth = betterAuth({
|
||||
});
|
||||
|
||||
if (!orgMembership) {
|
||||
throw new UnauthorizedError(
|
||||
"User does not belong to any organization",
|
||||
);
|
||||
throw new UnauthorizedError("User does not belong to any organization");
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -320,16 +320,14 @@ const reorderSchedules = async (scheduleIds: number[]) => {
|
||||
}
|
||||
}
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
db.transaction((tx) => {
|
||||
const now = Date.now();
|
||||
await Promise.all(
|
||||
scheduleIds.map((scheduleId, index) =>
|
||||
tx
|
||||
.update(backupSchedulesTable)
|
||||
.set({ sortOrder: index, updatedAt: now })
|
||||
.where(and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId))),
|
||||
),
|
||||
);
|
||||
for (const [index, scheduleId] of scheduleIds.entries()) {
|
||||
tx.update(backupSchedulesTable)
|
||||
.set({ sortOrder: index, updatedAt: now })
|
||||
.where(and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)))
|
||||
.run();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
27
bun.lock
27
bun.lock
@@ -42,7 +42,7 @@
|
||||
"date-fns": "^4.1.0",
|
||||
"dither-plugin": "^1.1.1",
|
||||
"dotenv": "^17.2.4",
|
||||
"drizzle-orm": "^1.0.0-beta.12-a5629fb",
|
||||
"drizzle-orm": "^1.0.0-beta.15-859cf75",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"hono": "^4.11.9",
|
||||
"hono-openapi": "^1.2.0",
|
||||
@@ -88,6 +88,7 @@
|
||||
"bun-types": "^1.3.6",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"drizzle-kit": "^1.0.0-beta.15-859cf75",
|
||||
"lefthook": "^2.1.1",
|
||||
"lightningcss": "^1.31.1",
|
||||
"nitro": "^3.0.1-alpha.2",
|
||||
"oxfmt": "^0.31.0",
|
||||
@@ -1074,7 +1075,7 @@
|
||||
|
||||
"drizzle-kit": ["drizzle-kit@1.0.0-beta.15-859cf75", "", { "dependencies": { "@drizzle-team/brocli": "^0.11.0", "@js-temporal/polyfill": "^0.5.1", "esbuild": "^0.25.10", "jiti": "^2.6.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-Y36s1XQGVb1PgU3aRNgufp1K3D2VkIifu8kv4Ubsmxi+Dq+N7KMklnpp7Knu/XC4FZi2MHPPG3v3o097r0/TcQ=="],
|
||||
|
||||
"drizzle-orm": ["drizzle-orm@1.0.0-beta.9-e89174b", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql": "^0.48.5", "@effect/sql-pg": "^0.49.7", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.2.1", "@tursodatabase/database-common": ">=0.2.1", "@tursodatabase/database-wasm": ">=0.2.1", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=9.3.0", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql", "@effect/sql-pg", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-B5KR/qYMZ0JMOurK+0xi1ObpOQcgrjaC9wHUiU2eTJjLemuh2CoQIw6yur68NxZG6Xcd0b9qghUNC/78/bEfbg=="],
|
||||
"drizzle-orm": ["drizzle-orm@1.0.0-beta.15-859cf75", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql": "^0.48.5", "@effect/sql-pg": "^0.49.7", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@sinclair/typebox": ">=0.34.8", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.2.1", "@tursodatabase/database-common": ">=0.2.1", "@tursodatabase/database-wasm": ">=0.2.1", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "arktype": ">=2.0.0", "better-sqlite3": ">=9.3.0", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5", "typebox": ">=1.0.0", "valibot": ">=1.0.0-beta.7", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql", "@effect/sql-pg", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@sinclair/typebox", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "arktype", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "mysql2", "pg", "postgres", "sql.js", "sqlite3", "typebox", "valibot", "zod"] }, "sha512-dGVb2Q70H2AV6513hkOXR3Ud0FeGXLdugVq3YehoqkGIVTJrkuo0gRnCcW/dfI00O07t3T4HSh4clF/D/o/IsQ=="],
|
||||
|
||||
"ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
|
||||
|
||||
@@ -1234,6 +1235,28 @@
|
||||
|
||||
"kysely": ["kysely@0.28.11", "", {}, "sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg=="],
|
||||
|
||||
"lefthook": ["lefthook@2.1.1", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.1", "lefthook-darwin-x64": "2.1.1", "lefthook-freebsd-arm64": "2.1.1", "lefthook-freebsd-x64": "2.1.1", "lefthook-linux-arm64": "2.1.1", "lefthook-linux-x64": "2.1.1", "lefthook-openbsd-arm64": "2.1.1", "lefthook-openbsd-x64": "2.1.1", "lefthook-windows-arm64": "2.1.1", "lefthook-windows-x64": "2.1.1" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-Tl9h9c+sG3ShzTHKuR3LAIblnnh+Mgxnm2Ul7yu9cu260Z27LEbO3V6Zw4YZFP59/2rlD42pt/llYsQCkkCFzw=="],
|
||||
|
||||
"lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-O/RS1j03/Fnq5zCzEb2r7UOBsqPeBuf1C5pMkIJcO4TSE6hf3rhLUkcorKc2M5ni/n5zLGtzQUXHV08/fSAT3Q=="],
|
||||
|
||||
"lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-mm/kdKl81ROPoYnj9XYk5JDqj+/6Al8w/SSPDfhItkLJyl4pqS+hWUOP6gDGrnuRk8S0DvJ2+hzhnDsQnZohWQ=="],
|
||||
|
||||
"lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-F7JXlKmjxGqGbCWPLND0bVB4DMQezIe48pEwTlUQZbxh450c2gP5Q8FdttMZKOT163kBGGTqJAJSEC6zW+QSxA=="],
|
||||
|
||||
"lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Po8/lJMqNzKSZPuEI46dLuWoBoXtAxCuRpeOh6DAV/M4RhBynaCu8rLMZ9BqF7cVbZEWoplOmYo6HdOuiYpCkQ=="],
|
||||
|
||||
"lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mI2ljFgPEqHxI8vrN9nKgnVu63Rz1KisDbPwlvs7BTYNwq3sncdK5ukpGR4zzWdh6saNJ5tCtHEtep5GQI11nw=="],
|
||||
|
||||
"lefthook-linux-x64": ["lefthook-linux-x64@2.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-m3G/FaxC+crxeg9XeaUuHfEoL+i9gbkg2Hp2KD2IcVVIxprqlyqf0Hb8zbLV2NMXuo5RSGokJu44oAoTO3Ou2g=="],
|
||||
|
||||
"lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-gz/8FJPvhjOdOFt1GmFvuvDOe+W+BBRjoeAT1/mTgkN7HCXMXgqNjjvakQKQeGz1I1v08wXG1ZNf5y+T9XBCDQ=="],
|
||||
|
||||
"lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-ch3lyMUtbmtWUufaQVn4IoEs/2hjK51XqaCdY1mh5ca//VctR1peknIwQ5feHu+vATCDviWQ7HsdNDewm3HMPg=="],
|
||||
|
||||
"lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mm3PZhKDs9FE/jQDimkfWxtoj9xQ2k8uw2MdhtC825bhvIh+MEi0WFj/MOW+ug0RBg0I55tGYzZ5aVuozAWpTQ=="],
|
||||
|
||||
"lefthook-windows-x64": ["lefthook-windows-x64@2.1.1", "", { "os": "win32", "cpu": "x64" }, "sha512-1L2oGIzmhfOTxfwbe5mpSQ+m3ilpvGNymwIhn4UHq6hwHsUL6HEhODqx02GfBn6OXpVIr56bvdBAusjL/SVYGQ=="],
|
||||
|
||||
"libsql": ["libsql@0.5.22", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.22", "@libsql/darwin-x64": "0.5.22", "@libsql/linux-arm-gnueabihf": "0.5.22", "@libsql/linux-arm-musleabihf": "0.5.22", "@libsql/linux-arm64-gnu": "0.5.22", "@libsql/linux-arm64-musl": "0.5.22", "@libsql/linux-x64-gnu": "0.5.22", "@libsql/linux-x64-musl": "0.5.22", "@libsql/win32-x64-msvc": "0.5.22" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"postinstall": "lefthook install",
|
||||
"lint": "oxlint --type-aware",
|
||||
"dev": "NODE_ENV=development bunx --bun vite",
|
||||
"build": "vite build",
|
||||
@@ -63,7 +64,7 @@
|
||||
"date-fns": "^4.1.0",
|
||||
"dither-plugin": "^1.1.1",
|
||||
"dotenv": "^17.2.4",
|
||||
"drizzle-orm": "^1.0.0-beta.12-a5629fb",
|
||||
"drizzle-orm": "^1.0.0-beta.15-859cf75",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"hono": "^4.11.9",
|
||||
"hono-openapi": "^1.2.0",
|
||||
@@ -109,6 +110,7 @@
|
||||
"bun-types": "^1.3.6",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"drizzle-kit": "^1.0.0-beta.15-859cf75",
|
||||
"lefthook": "^2.1.1",
|
||||
"lightningcss": "^1.31.1",
|
||||
"nitro": "^3.0.1-alpha.2",
|
||||
"oxfmt": "^0.31.0",
|
||||
|
||||
Reference in New Issue
Block a user