Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0e1603c
first change to libsql
Lokowitz Oct 20, 2025
000d6ad
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Oct 21, 2025
acf23cc
merge upstream
Lokowitz Oct 21, 2025
d20dead
add local test
Lokowitz Oct 21, 2025
ac04eec
migrations
Lokowitz Oct 21, 2025
fcad3a1
set min version to 1.11.2
Lokowitz Oct 21, 2025
80be0da
test
Lokowitz Oct 21, 2025
7755334
Merge remote-tracking branch 'upstream/main' into db-switch
Lokowitz Oct 21, 2025
3555a20
merge main
Lokowitz Oct 21, 2025
c751929
more logs in migration
Lokowitz Oct 21, 2025
6fe5916
update version
Lokowitz Oct 21, 2025
1d25812
updatre const
Lokowitz Oct 21, 2025
779f0d3
fix typo
Lokowitz Oct 21, 2025
ab98944
fix migration check
Lokowitz Oct 21, 2025
35ee3af
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Nov 16, 2025
5209f2d
update migration
Lokowitz Nov 16, 2025
b8a2aef
change migration version
Lokowitz Nov 16, 2025
40c0d11
remove temp test
Lokowitz Nov 16, 2025
9512604
change version
Lokowitz Nov 16, 2025
1287deb
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Nov 17, 2025
721e4c9
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Nov 17, 2025
7335c20
Revert "migrations"
Lokowitz Nov 20, 2025
3a5f103
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Nov 20, 2025
cc2326b
add current migrations
Lokowitz Nov 20, 2025
704b4cc
update migrations
Lokowitz Nov 20, 2025
2ad634e
fix revert
Lokowitz Nov 20, 2025
3c8ee9a
first batch of moving migration scripts to libsql
Lokowitz Dec 1, 2025
49f306c
migrate to libsql
Lokowitz Dec 1, 2025
88ea974
update to libsql
Lokowitz Dec 1, 2025
17cfb21
no errors in build, ready for tests
Lokowitz Dec 1, 2025
1bbb2ef
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Dec 15, 2025
9302a65
merge upstream
Lokowitz Dec 15, 2025
cc696ee
package lock
Lokowitz Dec 15, 2025
2812481
Merge remote-tracking branch 'upstream/dev' into db-switch
Lokowitz Dec 21, 2025
e3acfbf
update lock
Lokowitz Dec 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,323 changes: 3,288 additions & 5,035 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@faker-js/faker": "10.1.0",
"@headlessui/react": "2.2.9",
"@hookform/resolvers": "5.2.2",
"@libsql/client": "0.15.15",
"@monaco-editor/react": "4.7.0",
"@node-rs/argon2": "2.0.2",
"@oslojs/crypto": "1.0.1",
Expand Down Expand Up @@ -70,7 +71,6 @@
"@tanstack/react-table": "8.21.3",
"arctic": "3.7.0",
"axios": "1.13.2",
"better-sqlite3": "11.9.1",
"canvas-confetti": "1.9.4",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
Expand Down Expand Up @@ -144,7 +144,6 @@
"@esbuild-plugins/tsconfig-paths": "0.1.2",
"@tailwindcss/postcss": "4.1.18",
"@tanstack/react-query-devtools": "5.91.1",
"@types/better-sqlite3": "7.6.13",
"@types/cookie-parser": "1.4.10",
"@types/cors": "2.8.19",
"@types/crypto-js": "4.2.2",
Expand Down
6 changes: 3 additions & 3 deletions server/db/sqlite/driver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { drizzle as DrizzleSqlite } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import { drizzle as DrizzleSqlite } from "drizzle-orm/libsql";
import { createClient } from "@libsql/client";
import * as schema from "./schema/schema";
import path from "path";
import fs from "fs";
Expand All @@ -12,7 +12,7 @@ export const exists = checkFileExists(location);
bootstrapVolume();

function createDb() {
const sqlite = new Database(location);
const sqlite = createClient({ url: "file:" + location });
return DrizzleSqlite(sqlite, {
schema
});
Expand Down
2 changes: 1 addition & 1 deletion server/db/sqlite/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { migrate } from "drizzle-orm/libsql/migrator";
import { db } from "./driver";
import path from "path";

Expand Down
4 changes: 2 additions & 2 deletions server/private/routers/auth/quickStart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { users } from "@server/db";
import { fromError } from "zod-validation-error";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import { eq, and, sql } from "drizzle-orm";
import moment from "moment";
import { generateId } from "@server/auth/sessions/app";
Expand Down Expand Up @@ -490,7 +490,7 @@ export async function quickStart(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (config.getRawConfig().app.log_failed_attempts) {
logger.info(
`Account already exists with that email. Email: ${email}. IP: ${req.ip}.`
Expand Down
4 changes: 2 additions & 2 deletions server/private/routers/remoteExitNode/createRemoteExitNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { z } from "zod";
import { remoteExitNodes } from "@server/db";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import moment from "moment";
import { generateSessionToken } from "@server/auth/sessions/app";
import { createRemoteExitNodeSession } from "#private/auth/sessions/remoteExitNode";
Expand Down Expand Up @@ -246,7 +246,7 @@ export async function createRemoteExitNode(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import HttpCode from "@server/types/HttpCode";
import { remoteExitNodes } from "@server/db";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import moment from "moment";
import { generateId } from "@server/auth/sessions/app";
import { hashPassword } from "@server/auth/password";
Expand Down Expand Up @@ -84,7 +84,7 @@ export async function quickStartRemoteExitNode(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
Expand Down
4 changes: 2 additions & 2 deletions server/routers/auth/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { z } from "zod";
import { fromError } from "zod-validation-error";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import { sendEmailVerificationCode } from "../../auth/sendEmailVerificationCode";
import { eq, and } from "drizzle-orm";
import moment from "moment";
Expand Down Expand Up @@ -256,7 +256,7 @@ export async function signup(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (config.getRawConfig().app.log_failed_attempts) {
logger.info(
`Account already exists with that email. Email: ${email}. IP: ${req.ip}.`
Expand Down
4 changes: 2 additions & 2 deletions server/routers/newt/createNewt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { z } from "zod";
import { newts } from "@server/db";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import moment from "moment";
import { generateSessionToken } from "@server/auth/sessions/app";
import { createNewtSession } from "@server/auth/sessions/newt";
Expand Down Expand Up @@ -82,7 +82,7 @@ export async function createNewt(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
Expand Down
4 changes: 2 additions & 2 deletions server/routers/olm/createOlm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { z } from "zod";
import { newts } from "@server/db";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import moment from "moment";
import { generateSessionToken } from "@server/auth/sessions/app";
import { createNewtSession } from "@server/auth/sessions/newt";
Expand Down Expand Up @@ -82,7 +82,7 @@ export async function createNewt(
status: HttpCode.OK
});
} catch (e) {
if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
if (e instanceof LibsqlError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
Expand Down
6 changes: 3 additions & 3 deletions server/setup/migrationsSqlite.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#! /usr/bin/env node
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { migrate } from "drizzle-orm/libsql/migrator";
import { db, exists } from "../db/sqlite";
import path from "path";
import semver from "semver";
import { versionMigrations } from "../db/sqlite";
import { __DIRNAME, APP_PATH, APP_VERSION } from "@server/lib/consts";
import { SqliteError } from "better-sqlite3";
import { LibsqlError } from "@libsql/client";
import fs from "fs";
import m1 from "./scriptsSqlite/1.0.0-beta1";
import m2 from "./scriptsSqlite/1.0.0-beta2";
Expand Down Expand Up @@ -180,7 +180,7 @@ async function executeScripts() {
);
} catch (e) {
if (
e instanceof SqliteError &&
e instanceof LibsqlError &&
e.code === "SQLITE_CONSTRAINT_UNIQUE"
) {
console.error("Migration has already run! Skipping...");
Expand Down
19 changes: 12 additions & 7 deletions server/setup/scriptsSqlite/1.0.0-beta12.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { db } from "../../db/sqlite";
import { configFilePath1, configFilePath2 } from "@server/lib/consts";
import { sql } from "drizzle-orm";
import { APP_PATH, configFilePath1, configFilePath2 } from "@server/lib/consts";
import { createClient } from "@libsql/client";
import path from "path";
import fs from "fs";
import yaml from "js-yaml";

const version = "1.0.0-beta.12";

export default async function migration() {
console.log("Running setup script 1.0.0-beta.12...");
console.log(`Running setup script ${version}...`);

const location = path.join(APP_PATH, "db", "db.sqlite");
const db = createClient({ url: "file:" + location });

try {
// Determine which config file exists
Expand Down Expand Up @@ -47,9 +52,9 @@ export default async function migration() {
}

try {
db.transaction((trx) => {
trx.run(sql`ALTER TABLE 'resources' ADD 'isBaseDomain' integer;`);
});
await db.execute(
`ALTER TABLE 'resources' ADD 'isBaseDomain' integer;`
);

console.log(`Added new column: isBaseDomain`);
} catch (e) {
Expand Down
39 changes: 22 additions & 17 deletions server/setup/scriptsSqlite/1.0.0-beta13.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { db } from "../../db/sqlite";
import { sql } from "drizzle-orm";
import { APP_PATH } from "@server/lib/consts";
import { createClient } from "@libsql/client";
import path from "path";

const version = "1.0.0-beta.13";

export default async function migration() {
console.log(`Running setup script ${version}...`);

const location = path.join(APP_PATH, "db", "db.sqlite");
const db = createClient({ url: "file:" + location });

try {
db.transaction((trx) => {
trx.run(sql`CREATE TABLE resourceRules (
ruleId integer PRIMARY KEY AUTOINCREMENT NOT NULL,
resourceId integer NOT NULL,
priority integer NOT NULL,
enabled integer DEFAULT true NOT NULL,
action text NOT NULL,
match text NOT NULL,
value text NOT NULL,
FOREIGN KEY (resourceId) REFERENCES resources(resourceId) ON UPDATE no action ON DELETE cascade
);`);
trx.run(
sql`ALTER TABLE resources ADD applyRules integer DEFAULT false NOT NULL;`
);
});
await db.execute(
`CREATE TABLE resourceRules (
ruleId integer PRIMARY KEY AUTOINCREMENT NOT NULL,
resourceId integer NOT NULL,
priority integer NOT NULL,
enabled integer DEFAULT true NOT NULL,
action text NOT NULL,
match text NOT NULL,
value text NOT NULL,
FOREIGN KEY (resourceId) REFERENCES resources(resourceId) ON UPDATE no action ON DELETE cascade
);`
);

await db.execute(
`ALTER TABLE resources ADD applyRules integer DEFAULT false NOT NULL;`
);

console.log(`Added new table and column: resourceRules, applyRules`);
} catch (e) {
Expand Down
90 changes: 51 additions & 39 deletions server/setup/scriptsSqlite/1.0.0-beta15.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { db } from "../../db/sqlite";
import { configFilePath1, configFilePath2 } from "@server/lib/consts";
import { APP_PATH, configFilePath1, configFilePath2 } from "@server/lib/consts";
import { createClient } from "@libsql/client";
import path from "path";
import fs from "fs";
import yaml from "js-yaml";
import { sql } from "drizzle-orm";
import { domains, orgDomains, resources } from "@server/db";

const version = "1.0.0-beta.15";

export default async function migration() {
console.log(`Running setup script ${version}...`);

const location = path.join(APP_PATH, "db", "db.sqlite");
const db = createClient({ url: "file:" + location });

let domain = "";

try {
Expand Down Expand Up @@ -70,25 +73,30 @@ export default async function migration() {
}

try {
db.transaction((trx) => {
trx.run(sql`CREATE TABLE 'domains' (
'domainId' text PRIMARY KEY NOT NULL,
'baseDomain' text NOT NULL,
'configManaged' integer DEFAULT false NOT NULL
);`);

trx.run(sql`CREATE TABLE 'orgDomains' (
'orgId' text NOT NULL,
'domainId' text NOT NULL,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade
);`);

trx.run(
sql`ALTER TABLE 'resources' ADD 'domainId' text REFERENCES domains(domainId);`
);
trx.run(sql`ALTER TABLE 'orgs' DROP COLUMN 'domain';`);
});
await db.execute(
`CREATE TABLE 'domains' (
'domainId' text PRIMARY KEY NOT NULL,
'baseDomain' text NOT NULL,
'configManaged' integer DEFAULT false NOT NULL
);`
);

await db.execute(
`CREATE TABLE 'orgDomains' (
'orgId' text NOT NULL,
'domainId' text NOT NULL,
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade,
FOREIGN KEY ('domainId') REFERENCES 'domains'('domainId') ON UPDATE no action ON DELETE cascade
);`
);

await db.execute(
`ALTER TABLE 'resources' ADD 'domainId' text REFERENCES domains(domainId);`
);

await db.execute(
`ALTER TABLE 'orgs' DROP COLUMN 'domain';`
);

console.log(`Migrated database schema`);
} catch (e) {
Expand All @@ -97,26 +105,30 @@ export default async function migration() {
}

try {
await db.transaction(async (trx) => {
await trx
.insert(domains)
.values({
domainId: "domain1",
baseDomain: domain,
configManaged: true
})
.execute();
await trx.update(resources).set({ domainId: "domain1" });
const existingOrgDomains = await trx.select().from(orgDomains);
for (const orgDomain of existingOrgDomains) {
await trx
.insert(orgDomains)
.values({ orgId: orgDomain.orgId, domainId: "domain1" })
.execute();
}
await db.execute({
sql: `INSERT INTO domains (domainId, baseDomain, configManaged) VALUES (?, ?, ?)`,
args: ["domain1", domain, 1]
});

await db.execute({
sql: `UPDATE resources SET domainId = ?`,
args: ["domain1"]
});

const existingOrgDomainsResult = await db.execute(`SELECT orgId FROM orgDomains`);
const existingOrgDomains = (existingOrgDomainsResult.rows as unknown) as Array<{
orgId: string;
}>;

for (const orgDomain of existingOrgDomains) {
await db.execute({
sql: `INSERT INTO orgDomains (orgId, domainId) VALUES (?, ?)`,
args: [orgDomain.orgId, "domain1"]
});
}

console.log(`Updated resources table with new domainId`);

} catch (e) {
console.log(
`Unable to update resources table with new domainId. Error: ${e}`
Expand Down
Loading
Loading