bknd is dead long live userbase
Run Tests / test (pull_request) Successful in 4m57s

This commit is contained in:
2026-09-27 19:34:06 +05:30
parent 05e0086fcd
commit 0bfcb5ad71
529 changed files with 2385 additions and 2924 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
playwright-report
test-results
bknd.config.*
userbase.config.*
__test__/helper.d.ts
.env.local
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, mock, test, beforeAll, afterAll } from "bun:test";
import { createApp as internalCreateApp, type CreateAppConfig } from "bknd";
import { createApp as internalCreateApp, type CreateAppConfig } from "userbase";
import { getDummyConnection } from "../../__test__/helper";
import { ModuleManager } from "modules/ModuleManager";
import { em, entity, text } from "data/prototype";
+1 -1
View File
@@ -1,7 +1,7 @@
import { describe, test, expect, beforeEach, beforeAll, afterAll } from "bun:test";
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
import type { McpServer } from "bknd/utils";
import type { McpServer } from "userbase/utils";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
+2 -2
View File
@@ -1,8 +1,8 @@
import { describe, test, expect, beforeEach, beforeAll, afterAll } from "bun:test";
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
import { getSystemMcp } from "modules/mcp/system-mcp";
import { pickKeys, type McpServer } from "bknd/utils";
import { entity, text } from "bknd";
import { pickKeys, type McpServer } from "userbase/utils";
import { entity, text } from "userbase";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
beforeAll(disableConsoleLog);
+1 -1
View File
@@ -4,7 +4,7 @@ import { getSystemMcp } from "modules/mcp/system-mcp";
import { registries } from "index";
import { StorageLocalAdapter } from "adapter/node/storage/StorageLocalAdapter";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
import type { McpServer } from "bknd/utils";
import type { McpServer } from "userbase/utils";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, test, expect, beforeAll, afterAll } from "bun:test";
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
import type { McpServer } from "bknd/utils";
import type { McpServer } from "userbase/utils";
import { disableConsoleLog, enableConsoleLog } from "core/utils/test";
beforeAll(() => disableConsoleLog());
+1 -1
View File
@@ -1,7 +1,7 @@
import { AppEvents } from "App";
import { describe, test, expect, beforeAll, mock, afterAll } from "bun:test";
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
import type { McpServer } from "bknd/utils";
import type { McpServer } from "userbase/utils";
import { disableConsoleLog, enableConsoleLog } from "core/utils/test";
beforeAll(disableConsoleLog);
@@ -2,7 +2,7 @@ import { describe, expect, test, beforeAll, afterAll } from "bun:test";
import { Guard, type GuardConfig } from "auth/authorize/Guard";
import { Permission } from "auth/authorize/Permission";
import { Role, type RoleSchema } from "auth/authorize/Role";
import { objectTransform, s } from "bknd/utils";
import { objectTransform, s } from "userbase/utils";
import { disableConsoleLog, enableConsoleLog } from "core/utils/test";
beforeAll(disableConsoleLog);
@@ -3,7 +3,7 @@ import { createApp } from "core/test/utils";
import type { CreateAppConfig } from "App";
import * as proto from "data/prototype";
import { mergeObject } from "core/utils/objects";
import type { App, DB } from "bknd";
import type { App, DB } from "userbase";
import type { CreateUserPayload } from "auth/AppAuth";
import { disableConsoleLog, enableConsoleLog } from "core/utils/test";
@@ -1,5 +1,5 @@
import { describe, it, expect } from "bun:test";
import { s } from "bknd/utils";
import { s } from "userbase/utils";
import { Permission } from "auth/authorize/Permission";
import { Policy } from "auth/authorize/Policy";
import { Hono } from "hono";
@@ -7,7 +7,7 @@ import { getPermissionRoutes, permission } from "auth/middlewares/permission.mid
import { auth } from "auth/middlewares/auth.middleware";
import { Guard, mergeFilters, type GuardConfig } from "auth/authorize/Guard";
import { Role, RolePermission } from "auth/authorize/Role";
import { Exception } from "bknd";
import { Exception } from "userbase";
import { convert } from "core/object/query/object-query";
describe("Permission", () => {
@@ -421,7 +421,7 @@ describe("permission middleware", () => {
);
const res = await hono.request("/test");
// expecting 500 because bknd should have handled it correctly
// expecting 500 because userbase should have handled it correctly
expect(res.status).toBe(500);
});
+5 -5
View File
@@ -1,9 +1,9 @@
import { describe, beforeAll, afterAll, test } from "bun:test";
import type { PostgresConnection } from "data/connection/postgres/PostgresConnection";
import { pg, postgresJs } from "bknd";
import { pg, postgresJs } from "userbase";
import { Pool } from "pg";
import postgres from "postgres";
import { disableConsoleLog, enableConsoleLog, $waitUntil } from "bknd/utils";
import { disableConsoleLog, enableConsoleLog, $waitUntil } from "userbase/utils";
import { $ } from "bun";
import { connectionTestSuite } from "data/connection/connection-test-suite";
import { bunTestRunner } from "adapter/bun/test";
@@ -15,7 +15,7 @@ const credentials = {
port: 5432,
user: "postgres",
password: "postgres",
database: "bknd",
database: "userbase",
};
async function cleanDatabase(connection: InstanceType<typeof PostgresConnection>) {
@@ -47,7 +47,7 @@ describe("postgres", () => {
}
if (!(await isPostgresRunning())) {
await $`docker run --rm --name bknd-test-postgres -d -e POSTGRES_PASSWORD=${credentials.password} -e POSTGRES_USER=${credentials.user} -e POSTGRES_DB=${credentials.database} -p ${credentials.port}:5432 postgres:17`;
await $`docker run --rm --name userbase-test-postgres -d -e POSTGRES_PASSWORD=${credentials.password} -e POSTGRES_USER=${credentials.user} -e POSTGRES_DB=${credentials.database} -p ${credentials.port}:5432 postgres:17`;
await $waitUntil("Postgres is running", isPostgresRunning, 500, 20);
await new Promise((resolve) => setTimeout(resolve, 500));
}
@@ -57,7 +57,7 @@ describe("postgres", () => {
afterAll(async () => {
if (await isPostgresRunning()) {
try {
await $`docker stop bknd-test-postgres`;
await $`docker stop userbase-test-postgres`;
} catch (e) {}
}
+2 -2
View File
@@ -1,10 +1,10 @@
import { describe, it, expect } from "bun:test";
import * as sDirect from "jsonv-ts";
import { s as sFromBknd } from "bknd/utils";
import { s as sFromUserbase } from "userbase/utils";
describe("jsonv-ts resolution", () => {
it("should resolve to a single instance", () => {
const sameNamespace = sDirect === (sFromBknd as unknown as typeof sDirect);
const sameNamespace = sDirect === (sFromUserbase as unknown as typeof sDirect);
// If this fails, two instances are being loaded via different specifiers/paths
expect(sameNamespace).toBe(true);
});
+1 -1
View File
@@ -5,7 +5,7 @@ import { format as sqlFormat } from "sql-formatter";
import type { em as protoEm } from "../src/data/prototype";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { slugify } from "bknd/utils";
import { slugify } from "userbase/utils";
import { type Connection, SqliteLocalConnection } from "data/connection";
import { EntityManager } from "data/entities/EntityManager";
@@ -57,11 +57,11 @@ const configs = {
},
users: {
normal: {
email: "normal@bknd.io",
email: "normal@userbase.io",
password: "12345678",
},
admin: {
email: "admin@bknd.io",
email: "admin@userbase.io",
password: "12345678",
role: "admin",
},
@@ -271,7 +271,7 @@ describe("integration auth", () => {
expect(
await app
.createUser({
email: "test@bknd.io",
email: "test@userbase.io",
password: "12345678",
})
.then((r) => r.role),
@@ -280,7 +280,7 @@ describe("integration auth", () => {
// throws error if role doesn't exist
expect(
app.createUser({
email: "test@bknd.io",
email: "test@userbase.io",
password: "12345678",
role: "doesnt exist",
}),
@@ -290,7 +290,7 @@ describe("integration auth", () => {
expect(
await app
.createUser({
email: "test2@bknd.io",
email: "test2@userbase.io",
password: "12345678",
role: "admin",
})
@@ -301,7 +301,7 @@ describe("integration auth", () => {
expect(
await $fns
.register({
email: "test3@bknd.io",
email: "test3@userbase.io",
password: "12345678",
role: "admin",
})
@@ -312,7 +312,7 @@ describe("integration auth", () => {
expect(
await $fns
.register({
email: "test3@bknd.io",
email: "test3@userbase.io",
password: "12345678",
})
.then((r) => r.data.user.role),
+1 -1
View File
@@ -136,7 +136,7 @@ describe("AppAuth", () => {
}
});
test("registers auth middleware for bknd routes only", async () => {
test("registers auth middleware for userbase routes only", async () => {
const app = createApp({
config: {
auth: {
@@ -25,7 +25,7 @@ async function createVersionedApp(
const { version, ...rest } = config;
const db = dummyConnection.kysely as Kysely<any>;
await sql`CREATE TABLE "__bknd" (
await sql`CREATE TABLE "__userbase" (
"id" integer not null primary key autoincrement,
"version" integer,
"type" text,
@@ -35,7 +35,7 @@ async function createVersionedApp(
)`.execute(db);
await db
.insertInto("__bknd")
.insertInto("__userbase")
.values({
version,
type: "config",
@@ -61,7 +61,7 @@ async function getRawConfig(
) {
const db = app.em.connection.kysely;
return await db
.selectFrom("__bknd")
.selectFrom("__userbase")
.selectAll()
.where("version", "=", opts?.version ?? CURRENT_VERSION)
.$if((opts?.types?.length ?? 0) > 0, (qb) => qb.where("type", "in", opts?.types))
@@ -546,7 +546,7 @@
"config": {
"access_key": "123",
"secret_access_key": "123",
"url": "https://123.r2.cloudflarestorage.com/bknd-123"
"url": "https://123.r2.cloudflarestorage.com/userbase-123"
}
}
},
+1 -1
View File
@@ -7,7 +7,7 @@ import { EntityManager } from "data/entities/EntityManager";
import { Module, type ModuleBuildContext } from "modules/Module";
import { getDummyConnection } from "../helper";
import { ModuleHelper } from "modules/ModuleHelper";
import { DebugLogger, McpServer } from "bknd/utils";
import { DebugLogger, McpServer } from "userbase/utils";
export function makeCtx(overrides?: Partial<ModuleBuildContext>): ModuleBuildContext {
const { dummyConnection } = getDummyConnection();
+21 -21
View File
@@ -1,6 +1,6 @@
import { describe, it, expect, beforeEach } from "vitest";
import { AppReduced, type AppType } from "ui/client/utils/AppReduced";
import type { BkndAdminProps } from "ui/Admin";
import type { UserbaseAdminProps } from "ui/Admin";
// Import the normalizeAdminPath function for testing
// Note: This assumes the function is exported or we need to test it indirectly through public methods
@@ -24,7 +24,7 @@ describe("AppReduced", () => {
describe("getSettingsPath", () => {
it("should return settings path with basepath", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -36,7 +36,7 @@ describe("AppReduced", () => {
});
it("should return settings path with empty basepath", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "",
logo_return_path: "/",
};
@@ -48,7 +48,7 @@ describe("AppReduced", () => {
});
it("should append additional path segments", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -60,7 +60,7 @@ describe("AppReduced", () => {
});
it("should normalize multiple slashes", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "//admin//",
logo_return_path: "/",
};
@@ -72,7 +72,7 @@ describe("AppReduced", () => {
});
it("should handle basepath without leading slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "admin",
logo_return_path: "/",
};
@@ -86,7 +86,7 @@ describe("AppReduced", () => {
describe("getAbsolutePath", () => {
it("should return absolute path with basepath", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -98,7 +98,7 @@ describe("AppReduced", () => {
});
it("should return base path when no path provided", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -110,7 +110,7 @@ describe("AppReduced", () => {
});
it("should normalize paths correctly", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "//admin//",
logo_return_path: "/",
};
@@ -124,7 +124,7 @@ describe("AppReduced", () => {
describe("options getter", () => {
it("should return merged options with defaults", () => {
const customOptions: BkndAdminProps["config"] = {
const customOptions: UserbaseAdminProps["config"] = {
basepath: "/custom-admin",
logo_return_path: "/custom-home",
};
@@ -139,7 +139,7 @@ describe("AppReduced", () => {
});
it("should use default logo_return_path when not provided", () => {
const customOptions: BkndAdminProps["config"] = {
const customOptions: UserbaseAdminProps["config"] = {
basepath: "/admin",
};
@@ -153,7 +153,7 @@ describe("AppReduced", () => {
describe("path normalization behavior", () => {
it("should normalize duplicate slashes in settings path", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -165,7 +165,7 @@ describe("AppReduced", () => {
});
it("should handle root path normalization", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/",
logo_return_path: "/",
};
@@ -179,7 +179,7 @@ describe("AppReduced", () => {
});
it("should preserve entity paths ending with slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -191,7 +191,7 @@ describe("AppReduced", () => {
});
it("should remove trailing slashes from non-entity paths", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -205,7 +205,7 @@ describe("AppReduced", () => {
describe("withBasePath - double slash fix (admin_basepath with trailing slash)", () => {
it("should not produce double slashes when admin_basepath has trailing slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -218,7 +218,7 @@ describe("AppReduced", () => {
});
it("should work correctly when admin_basepath has no trailing slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -230,7 +230,7 @@ describe("AppReduced", () => {
});
it("should handle absolute paths with admin_basepath trailing slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -243,7 +243,7 @@ describe("AppReduced", () => {
});
it("should handle settings path with admin_basepath trailing slash", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
@@ -258,7 +258,7 @@ describe("AppReduced", () => {
describe("edge cases", () => {
it("should handle undefined basepath", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
logo_return_path: "/",
};
@@ -270,7 +270,7 @@ describe("AppReduced", () => {
});
it("should handle null path segments", () => {
const options: BkndAdminProps["config"] = {
const options: UserbaseAdminProps["config"] = {
basepath: "/admin",
logo_return_path: "/",
};
+2 -2
View File
@@ -1,9 +1,9 @@
import pkg from "./package.json" with { type: "json" };
import c from "picocolors";
import { formatNumber } from "bknd/utils";
import { formatNumber } from "userbase/utils";
const deps = Object.keys(pkg.dependencies);
const external = ["jsonv-ts/*", "wrangler", "bknd", "bknd/*", ...deps];
const external = ["jsonv-ts/*", "wrangler", "userbase", "userbase/*", ...deps];
const result = await Bun.build({
entrypoints: ["./src/cli/index.ts"],
+8 -8
View File
@@ -83,8 +83,8 @@ const external = [
"node:test",
"node:assert/strict",
"@libsql/client",
"bknd",
/^bknd\/.*/,
"userbase",
/^userbase\/.*/,
"jsonv-ts",
/^jsonv-ts\/.*/,
] as const;
@@ -125,7 +125,7 @@ async function buildApi() {
async function rewriteClient(path: string) {
const bundle = await Bun.file(path).text();
await Bun.write(path, '"use client";\n' + bundle.replaceAll("ui/client", "bknd/client"));
await Bun.write(path, '"use client";\n' + bundle.replaceAll("ui/client", "userbase/client"));
}
/**
@@ -188,7 +188,7 @@ async function buildUi() {
/**
* Building UI Elements
* - tailwind-merge is mocked, no exclude
* - ui/client is external, and after built replaced with "bknd/client"
* - ui/client is external, and after built replaced with "userbase/client"
*/
async function buildUiElements() {
await tsup.build({
@@ -200,8 +200,8 @@ async function buildUiElements() {
outDir: "dist/ui/elements",
external: [
"ui/client",
"bknd",
/^bknd\/.*/,
"userbase",
/^userbase\/.*/,
"wouter",
"react",
"react-dom",
@@ -259,7 +259,7 @@ function baseConfig(adapter: string, overrides: Partial<tsup.Options> = {}): tsu
external: [
/^cloudflare*/,
/^@?hono.*?/,
/^(bknd|react|next|node).*?/,
/^(userbase|react|next|node).*?/,
/.*\.(html)$/,
...external,
...(Array.isArray(overrides.external) ? overrides.external : []),
@@ -305,7 +305,7 @@ async function buildAdapters() {
entry: ["src/adapter/cloudflare/proxy.ts"],
outDir: "dist/adapter/cloudflare",
metafile: false,
external: [/bknd/, "wrangler", "node:process"],
external: [/userbase/, "wrangler", "node:process"],
}),
),
+1 -1
View File
@@ -1,4 +1,4 @@
import { createApp } from "bknd/adapter/bun";
import { createApp } from "userbase/adapter/bun";
async function generate() {
console.info("Generating MCP documentation...");
+6 -6
View File
@@ -1,24 +1,24 @@
{
"name": "bknd",
"name": "userbase",
"type": "module",
"sideEffects": false,
"bin": "./dist/cli/index.js",
"version": "0.21.0-rc.1",
"version": "0.0.1",
"description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.",
"homepage": "https://bknd.io",
"homepage": "https://gitea.bsws.in/shishantbiswas/userbase",
"repository": {
"type": "git",
"url": "https://github.com/bknd-io/bknd.git"
"url": "https://gitea.bsws.in/shishantbiswas/userbase.git"
},
"bugs": {
"url": "https://github.com/bknd-io/bknd/issues"
"url": "https://gitea.bsws.in/shishantbiswas/userbase/issues"
},
"packageManager": "bun@1.3.3",
"engines": {
"node": ">=22.13"
},
"scripts": {
"dev": "BKND_CLI_LOG_LEVEL=debug vite",
"dev": "USERBASE_CLI_LOG_LEVEL=debug vite",
"build": "NODE_ENV=production bun run build.ts --minify --types",
"build:all": "rm -rf dist && bun run build:static && NODE_ENV=production bun run build.ts --minify --types --clean && bun run build:cli",
"build:ci": "mkdir -p dist/static/.vite && echo '{}' > dist/static/.vite/manifest.json && NODE_ENV=production bun run build.ts",
+2 -2
View File
@@ -1,10 +1,10 @@
import type { SafeUser } from "bknd";
import type { SafeUser } from "userbase";
import { AuthApi, type AuthApiOptions } from "auth/api/AuthApi";
import { DataApi, type DataApiOptions } from "data/api/DataApi";
import { decode } from "hono/jwt";
import { MediaApi, type MediaApiOptions } from "media/api/MediaApi";
import { SystemApi } from "modules/SystemApi";
import { omitKeys } from "bknd/utils";
import { omitKeys } from "userbase/utils";
import type { BaseModuleApiOptions } from "modules";
export type TApiUser = SafeUser;
+2 -2
View File
@@ -1,5 +1,5 @@
import type { CreateUserPayload } from "auth/AppAuth";
import { $console, McpClient } from "bknd/utils";
import { $console, McpClient } from "userbase/utils";
import { Event } from "core/events";
import type { em as prototypeEm } from "data/prototype";
import { Connection } from "data/connection/Connection";
@@ -346,7 +346,7 @@ export class App<
try {
// gracefully add the app id
c.res.headers.set("X-bknd-id", this._id);
c.res.headers.set("X-userbase-id", this._id);
} catch (e) {}
await this.emgr.emit(
+3 -3
View File
@@ -1,10 +1,10 @@
import type { TestRunner } from "core/test";
import type { BkndConfig, DefaultArgs } from "./index";
import type { UserbaseConfig, DefaultArgs } from "./index";
import type { App } from "App";
import { disableConsoleLog, enableConsoleLog } from "core/utils/test";
export function adapterTestSuite<
Config extends BkndConfig = BkndConfig,
Config extends UserbaseConfig = UserbaseConfig,
Args extends DefaultArgs = DefaultArgs,
>(
testRunner: TestRunner,
@@ -39,7 +39,7 @@ export function adapterTestSuite<
}),
beforeBuild,
onBuilt,
} as const satisfies BkndConfig;
} as const satisfies UserbaseConfig;
const app = await makeApp(
config as any,
+4 -4
View File
@@ -1,20 +1,20 @@
import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter";
import { type FrameworkUserbaseConfig, createFrameworkApp } from "userbase/adapter";
type AstroEnv = NodeJS.ProcessEnv;
type TAstro = {
request: Request;
};
export type AstroBkndConfig<Env = AstroEnv> = FrameworkBkndConfig<Env>;
export type AstroUserbaseConfig<Env = AstroEnv> = FrameworkUserbaseConfig<Env>;
export async function getApp<Env = AstroEnv>(
config: AstroBkndConfig<Env> = {},
config: AstroUserbaseConfig<Env> = {},
args: Env = import.meta.env as Env,
) {
return await createFrameworkApp(config, args);
}
export function serve<Env = AstroEnv>(
config: AstroBkndConfig<Env> = {},
config: AstroUserbaseConfig<Env> = {},
args: Env = import.meta.env as Env,
) {
return async (fnArgs: TAstro) => {
+7 -7
View File
@@ -1,11 +1,11 @@
import type { App } from "bknd";
import type { App } from "userbase";
import { handle } from "hono/aws-lambda";
import { serveStatic } from "@hono/node-server/serve-static";
import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter";
import { type RuntimeUserbaseConfig, createRuntimeApp } from "userbase/adapter";
type AwsLambdaEnv = object;
export type AwsLambdaBkndConfig<Env extends AwsLambdaEnv = AwsLambdaEnv> =
RuntimeBkndConfig<Env> & {
export type AwsLambdaUserbaseConfig<Env extends AwsLambdaEnv = AwsLambdaEnv> =
RuntimeUserbaseConfig<Env> & {
assets?:
| {
mode: "local";
@@ -18,10 +18,10 @@ export type AwsLambdaBkndConfig<Env extends AwsLambdaEnv = AwsLambdaEnv> =
};
export async function createApp<Env extends AwsLambdaEnv = AwsLambdaEnv>(
{ adminOptions = false, assets, ...config }: AwsLambdaBkndConfig<Env> = {},
{ adminOptions = false, assets, ...config }: AwsLambdaUserbaseConfig<Env> = {},
args: Env = {} as Env,
): Promise<App> {
let additional: Partial<RuntimeBkndConfig> = {
let additional: Partial<RuntimeUserbaseConfig> = {
adminOptions,
};
@@ -60,7 +60,7 @@ export async function createApp<Env extends AwsLambdaEnv = AwsLambdaEnv>(
}
export function serve<Env extends AwsLambdaEnv = AwsLambdaEnv>(
config: AwsLambdaBkndConfig<Env> = {},
config: AwsLambdaUserbaseConfig<Env> = {},
args: Env = {} as Env,
) {
return async (event) => {
@@ -1,6 +1,6 @@
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "bknd";
import { StorageAdapter, guessMimeType } from "bknd";
import { parse, s, isFile, isBlob } from "bknd/utils";
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "userbase";
import { StorageAdapter, guessMimeType } from "userbase";
import { parse, s, isFile, isBlob } from "userbase/utils";
export const opfsAdapterConfig = s.object(
{
@@ -7,20 +7,20 @@ import {
useState,
type ReactNode,
} from "react";
import { checksum } from "bknd/utils";
import { App, registries, sqlocal, type BkndConfig } from "bknd";
import { checksum } from "userbase/utils";
import { App, registries, sqlocal, type UserbaseConfig } from "userbase";
import { Route, Router, Switch } from "wouter";
import { ClientProvider } from "bknd/client";
import { ClientProvider } from "userbase/client";
import { SQLocalKysely } from "sqlocal/kysely";
import type { ClientConfig, DatabasePath } from "sqlocal";
import { OpfsStorageAdapter } from "bknd/adapter/browser";
import type { BkndAdminConfig } from "bknd/ui";
import { OpfsStorageAdapter } from "userbase/adapter/browser";
import type { UserbaseAdminConfig } from "userbase/ui";
const Admin = lazy(() =>
Promise.all([
import("bknd/ui"),
import("userbase/ui"),
// @ts-ignore
import("bknd/dist/styles.css"),
import("userbase/dist/styles.css"),
]).then(([mod]) => ({
default: mod.Admin,
})),
@@ -34,34 +34,34 @@ function safeViewTransition(fn: () => void) {
}
}
export type BrowserBkndConfig<Args = ImportMetaEnv> = Omit<
BkndConfig<Args>,
export type BrowserUserbaseConfig<Args = ImportMetaEnv> = Omit<
UserbaseConfig<Args>,
"connection" | "app"
> & {
adminConfig?: BkndAdminConfig;
adminConfig?: UserbaseAdminConfig;
connection?: ClientConfig | DatabasePath;
};
export type BkndBrowserAppProps = {
export type UserbaseBrowserAppProps = {
children: ReactNode;
header?: ReactNode;
loading?: ReactNode;
notFound?: ReactNode;
} & BrowserBkndConfig;
} & BrowserUserbaseConfig;
const BkndBrowserAppContext = createContext<{
const UserbaseBrowserAppContext = createContext<{
app: App;
hash: string;
}>(undefined!);
export function BkndBrowserApp({
export function UserbaseBrowserApp({
children,
adminConfig,
header,
loading,
notFound,
...config
}: BkndBrowserAppProps) {
}: UserbaseBrowserAppProps) {
const [app, setApp] = useState<App | undefined>(undefined);
const [hash, setHash] = useState<string>("");
const adminRoutePath = (adminConfig?.basepath ?? "") + "/*?";
@@ -90,7 +90,7 @@ export function BkndBrowserApp({
}
return (
<BkndBrowserAppContext.Provider value={{ app, hash }}>
<UserbaseBrowserAppContext.Provider value={{ app, hash }}>
<ClientProvider storage={window.localStorage} fetcher={app.server.request}>
{header}
<Router key={hash}>
@@ -110,12 +110,12 @@ export function BkndBrowserApp({
</Switch>
</Router>
</ClientProvider>
</BkndBrowserAppContext.Provider>
</UserbaseBrowserAppContext.Provider>
);
}
export function useApp() {
return useContext(BkndBrowserAppContext);
return useContext(UserbaseBrowserAppContext);
}
const Center = (props: React.HTMLAttributes<HTMLDivElement>) => (
@@ -133,7 +133,7 @@ const Center = (props: React.HTMLAttributes<HTMLDivElement>) => (
);
let initialized = false;
async function setup(config: BrowserBkndConfig = {}) {
async function setup(config: BrowserUserbaseConfig = {}) {
if (initialized) return;
initialized = true;
+1 -1
View File
@@ -1,2 +1,2 @@
export * from "./OpfsStorageAdapter";
export * from "./BkndBrowserApp";
export * from "./UserbaseBrowserApp";
+7 -7
View File
@@ -1,18 +1,18 @@
import path from "node:path";
import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter";
import { type RuntimeUserbaseConfig, createRuntimeApp } from "userbase/adapter";
import { registerLocalMediaAdapter } from ".";
import { config, type App } from "bknd";
import { config, type App } from "userbase";
import { serveStatic } from "hono/bun";
type BunEnv = Bun.Env;
export type BunBkndConfig<Env = BunEnv> = RuntimeBkndConfig<Env> &
export type BunUserbaseConfig<Env = BunEnv> = RuntimeUserbaseConfig<Env> &
Omit<Bun.Serve.Options<undefined, string>, "fetch">;
export async function createApp<Env = BunEnv>(
{ distPath, serveStatic: _serveStatic, ...config }: BunBkndConfig<Env> = {},
{ distPath, serveStatic: _serveStatic, ...config }: BunUserbaseConfig<Env> = {},
args: Env = Bun.env as Env,
) {
const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static");
const root = path.resolve(distPath ?? "./node_modules/userbase/dist", "static");
registerLocalMediaAdapter();
return await createRuntimeApp(
@@ -29,7 +29,7 @@ export async function createApp<Env = BunEnv>(
}
export function createHandler<Env = BunEnv>(
config: BunBkndConfig<Env> = {},
config: BunUserbaseConfig<Env> = {},
args: Env = Bun.env as Env,
) {
let app: App | undefined;
@@ -55,7 +55,7 @@ export function serve<Env = BunEnv>(
serveStatic,
beforeBuild,
...serveOptions
}: BunBkndConfig<Env> = {},
}: BunUserbaseConfig<Env> = {},
args: Env = Bun.env as Env,
) {
Bun.serve({
@@ -3,8 +3,8 @@ import {
genericSqlite,
type GenericSqliteConnection,
type GenericSqliteConnectionConfig,
} from "bknd";
import { omitKeys } from "bknd/utils";
} from "userbase";
import { omitKeys } from "userbase/utils";
export type BunSqliteConnection = GenericSqliteConnection<Database>;
export type BunSqliteConnectionConfig = Omit<
@@ -3,7 +3,7 @@ import { makeConfig, type CloudflareContext } from "./config";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
import { adapterTestSuite } from "adapter/adapter-test-suite";
import { bunTestRunner } from "adapter/bun/test";
import { type CloudflareBkndConfig, createApp } from "./cloudflare-workers.adapter";
import { type CloudflareUserbaseConfig, createApp } from "./cloudflare-workers.adapter";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
@@ -40,7 +40,7 @@ describe("cf adapter", () => {
expect(dynamicConfig.connection).toBeDefined();
});
adapterTestSuite<CloudflareBkndConfig, CloudflareContext<any>>(bunTestRunner, {
adapterTestSuite<CloudflareUserbaseConfig, CloudflareContext<any>>(bunTestRunner, {
makeApp: async (c, a) => {
return await createApp(c, { env: a } as any);
},
@@ -1,11 +1,11 @@
/// <reference types="@cloudflare/workers-types" />
import type { RuntimeBkndConfig } from "bknd/adapter";
import type { RuntimeUserbaseConfig } from "userbase/adapter";
import { Hono } from "hono";
import { serveStatic } from "hono/cloudflare-workers";
import type { App, MaybePromise } from "bknd";
import { $console } from "bknd/utils";
import { createRuntimeApp } from "bknd/adapter";
import type { App, MaybePromise } from "userbase";
import { $console } from "userbase/utils";
import { createRuntimeApp } from "userbase/adapter";
import { registerAsyncsExecutionContext, makeConfig, type CloudflareContext } from "./config";
declare global {
@@ -15,7 +15,7 @@ declare global {
}
export type CloudflareEnv = Cloudflare.Env;
export type CloudflareBkndConfig<Env = CloudflareEnv> = RuntimeBkndConfig<Env> & {
export type CloudflareUserbaseConfig<Env = CloudflareEnv> = RuntimeUserbaseConfig<Env> & {
bindings?: (args: Env) => MaybePromise<{
kv?: KVNamespace;
db?: D1Database;
@@ -34,7 +34,7 @@ export type CloudflareBkndConfig<Env = CloudflareEnv> = RuntimeBkndConfig<Env> &
};
export async function createApp<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env> = {},
config: CloudflareUserbaseConfig<Env> = {},
ctx: Partial<CloudflareContext<Env>> = {},
) {
const appConfig = await makeConfig(config, ctx);
@@ -57,7 +57,7 @@ export const getFresh = createApp;
let app: App | undefined;
export function serve<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env> = {},
config: CloudflareUserbaseConfig<Env> = {},
serveOptions?: (args: Env) => {
warm?: boolean;
},
+11 -10
View File
@@ -1,21 +1,22 @@
/// <reference types="@cloudflare/workers-types" />
import { Connection } from "bknd";
import { sqlite } from "bknd/adapter/sqlite";
import { makeConfig as makeAdapterConfig } from "bknd/adapter";
import { Connection } from "userbase";
import { sqlite } from "userbase/adapter/sqlite";
import { makeConfig as makeAdapterConfig } from "userbase/adapter";
import { registerMedia } from "./storage/StorageR2Adapter";
import { getBinding } from "./bindings";
import { d1Sqlite } from "./connection/D1Connection";
import type { CloudflareBkndConfig, CloudflareEnv } from ".";
import { App } from "bknd";
import type { CloudflareUserbaseConfig, CloudflareEnv } from ".";
import { App } from "userbase";
import type { Context as HonoContext, ExecutionContext } from "hono";
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
import { setCookie } from "hono/cookie";
export const constants = {
exec_async_event_id: "cf_register_waituntil",
cache_endpoint: "/__bknd/cache",
do_endpoint: "/__bknd/do",
cache_endpoint: "/__userbase/cache",
do_endpoint: "/__userbase/do",
d1_session: {
cookie: "cf_d1_session",
header: "x-cf-d1-session",
@@ -40,7 +41,7 @@ function getCookieValue(cookies: string | null, name: string) {
return null;
}
export function d1SessionHelper(config: CloudflareBkndConfig<any>) {
export function d1SessionHelper(config: CloudflareUserbaseConfig<any>) {
const headerKey = constants.d1_session.header;
const cookieKey = constants.d1_session.cookie;
const transport = config.d1?.transport;
@@ -90,7 +91,7 @@ export function d1SessionHelper(config: CloudflareBkndConfig<any>) {
let media_registered: boolean = false;
export async function makeConfig<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
config: CloudflareUserbaseConfig<Env>,
args?: Partial<CloudflareContext<Env>>,
) {
if (!media_registered && config.registerMedia !== false) {
@@ -1,6 +1,6 @@
/// <reference types="@cloudflare/workers-types" />
import { genericSqlite, type GenericSqliteConnection } from "bknd";
import { genericSqlite, type GenericSqliteConnection } from "userbase";
import type { QueryResult } from "kysely";
export type D1SqliteConnection = GenericSqliteConnection<D1Database>;
@@ -1,6 +1,6 @@
/// <reference types="@cloudflare/workers-types" />
import { genericSqlite, type GenericSqliteConnection } from "bknd";
import { genericSqlite, type GenericSqliteConnection } from "userbase";
import type { QueryResult } from "kysely";
export type DoSqliteConnection = GenericSqliteConnection<DurableObjectState["storage"]["sql"]>;
+2 -2
View File
@@ -5,7 +5,7 @@ export {
createApp,
serve,
type CloudflareEnv,
type CloudflareBkndConfig,
type CloudflareUserbaseConfig,
} from "./cloudflare-workers.adapter";
export { d1Sqlite, type D1ConnectionConfig };
export { doSqlite, type DoConnectionConfig } from "./connection/DoConnection";
@@ -18,7 +18,7 @@ export {
} from "./bindings";
export { constants, makeConfig, type CloudflareContext } from "./config";
export { StorageR2Adapter, registerMedia } from "./storage/StorageR2Adapter";
export { registries } from "bknd";
export { registries } from "userbase";
export { devFsVitePlugin, devFsWrite } from "./vite";
// for compatibility with old code
+5 -5
View File
@@ -2,12 +2,12 @@ import {
d1Sqlite,
getBinding,
registerMedia,
type CloudflareBkndConfig,
type CloudflareUserbaseConfig,
type CloudflareEnv,
} from "bknd/adapter/cloudflare";
} from "userbase/adapter/cloudflare";
import type { GetPlatformProxyOptions, PlatformProxy } from "wrangler";
import process from "node:process";
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
export type WithPlatformProxyOptions = {
/**
@@ -42,7 +42,7 @@ async function getPlatformProxy(opts?: GetPlatformProxyOptions) {
}
export function withPlatformProxy<Env extends CloudflareEnv>(
config: CloudflareBkndConfig<Env> = {},
config: CloudflareUserbaseConfig<Env> = {},
opts?: WithPlatformProxyOptions,
) {
const use_proxy =
@@ -91,5 +91,5 @@ export function withPlatformProxy<Env extends CloudflareEnv>(
connection,
};
},
} satisfies CloudflareBkndConfig<Env>;
} satisfies CloudflareUserbaseConfig<Env>;
}
@@ -1,7 +1,7 @@
import { registries as $registries, isDebug, guessMimeType } from "bknd";
import { registries as $registries, isDebug, guessMimeType } from "userbase";
import { getBindings } from "../bindings";
import { s } from "bknd/utils";
import { StorageAdapter, type FileBody } from "bknd";
import { s } from "userbase/utils";
import { StorageAdapter, type FileBody } from "userbase";
export function makeSchema(bindings: string[] = []) {
return s.object(
+2 -2
View File
@@ -8,7 +8,7 @@ import { resolve } from "node:path";
*/
export function devFsVitePlugin({
verbose = false,
configFile = "bknd.config.ts",
configFile = "userbase.config.ts",
}: {
verbose?: boolean;
configFile?: string;
@@ -195,7 +195,7 @@ export function devFsVitePlugin({
return;
}
// Check if this is the bknd config file
// Check if this is the userbase config file
if (id.includes(configFile)) {
if (verbose) {
console.debug("[dev-fs-plugin] Transforming", configFile);
+16 -16
View File
@@ -7,27 +7,27 @@ import {
type MaybePromise,
registries as $registries,
type Merge,
} from "bknd";
import { $console } from "bknd/utils";
} from "userbase";
import { $console } from "userbase/utils";
import type { Context, MiddlewareHandler, Next } from "hono";
import type { AdminControllerOptions } from "modules/server/AdminController";
import type { Manifest } from "vite";
export type BkndConfig<Args = any, Additional = {}> = Merge<
export type UserbaseConfig<Args = any, Additional = {}> = Merge<
CreateAppConfig &
Omit<Additional, "app"> & {
app?:
| Omit<BkndConfig<Args, Additional>, "app">
| ((args: Args) => MaybePromise<Omit<BkndConfig<Args, Additional>, "app">>);
| Omit<UserbaseConfig<Args, Additional>, "app">
| ((args: Args) => MaybePromise<Omit<UserbaseConfig<Args, Additional>, "app">>);
onBuilt?: (app: App) => MaybePromise<void>;
beforeBuild?: (app?: App, registries?: typeof $registries) => MaybePromise<void>;
buildConfig?: Parameters<App["build"]>[0];
}
>;
export type FrameworkBkndConfig<Args = any> = BkndConfig<Args>;
export type FrameworkUserbaseConfig<Args = any> = UserbaseConfig<Args>;
export type RuntimeBkndConfig<Args = any> = BkndConfig<Args> & {
export type RuntimeUserbaseConfig<Args = any> = UserbaseConfig<Args> & {
distPath?: string;
serveStatic?: MiddlewareHandler | [string, MiddlewareHandler];
adminOptions?: AdminControllerOptions | false;
@@ -38,9 +38,9 @@ export type DefaultArgs = {
};
export async function makeConfig<Args = DefaultArgs>(
config: BkndConfig<Args>,
config: UserbaseConfig<Args>,
args?: Args,
): Promise<Omit<BkndConfig<Args>, "app">> {
): Promise<Omit<UserbaseConfig<Args>, "app">> {
let additionalConfig: CreateAppConfig = {};
const { app, ...rest } = config;
if (app) {
@@ -57,10 +57,10 @@ export async function makeConfig<Args = DefaultArgs>(
return { ...rest, ...additionalConfig };
}
export async function createAdapterApp<Config extends BkndConfig = BkndConfig, Args = DefaultArgs>(
export async function createAdapterApp<Config extends UserbaseConfig = UserbaseConfig, Args = DefaultArgs>(
config: Config = {} as Config,
args?: Args,
): Promise<{ app: App; config: BkndConfig<Args> }> {
): Promise<{ app: App; config: UserbaseConfig<Args> }> {
await config.beforeBuild?.(undefined, $registries);
const appConfig = await makeConfig(config, args);
@@ -69,7 +69,7 @@ export async function createAdapterApp<Config extends BkndConfig = BkndConfig, A
if (Connection.isConnection(config.connection)) {
connection = config.connection;
} else {
const sqlite = (await import("bknd/adapter/sqlite")).sqlite;
const sqlite = (await import("userbase/adapter/sqlite")).sqlite;
const conf = appConfig.connection ?? { url: "file:data.db" };
connection = sqlite(conf) as any;
$console.info(`Using ${connection!.name} connection`, conf.url);
@@ -84,7 +84,7 @@ export async function createAdapterApp<Config extends BkndConfig = BkndConfig, A
}
export async function createFrameworkApp<Args = DefaultArgs>(
config: FrameworkBkndConfig = {},
config: FrameworkUserbaseConfig = {},
args?: Args,
): Promise<App> {
const { app, config: appConfig } = await createAdapterApp(config, args);
@@ -108,7 +108,7 @@ export async function createFrameworkApp<Args = DefaultArgs>(
}
export async function createRuntimeApp<Args = DefaultArgs>(
{ serveStatic, adminOptions, ...config }: RuntimeBkndConfig<Args> = {},
{ serveStatic, adminOptions, ...config }: RuntimeUserbaseConfig<Args> = {},
args?: Args,
): Promise<App> {
const { app, config: appConfig } = await createAdapterApp(config, args);
@@ -148,7 +148,7 @@ export async function createRuntimeApp<Args = DefaultArgs>(
*
* @example
* ```typescript
* import { serveStaticViaImport } from "bknd/adapter";
* import { serveStaticViaImport } from "userbase/adapter";
*
* serve({
* serveStatic: serveStaticViaImport(),
@@ -161,7 +161,7 @@ export function serveStaticViaImport(opts?: {
package?: string;
}) {
let files: string[] | undefined;
const pkg = opts?.package ?? "bknd";
const pkg = opts?.package ?? "userbase";
// @ts-ignore
return async (c: Context, next: Next) => {
@@ -3,13 +3,13 @@ import * as nextjs from "./nextjs.adapter";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
import { adapterTestSuite } from "adapter/adapter-test-suite";
import { bunTestRunner } from "adapter/bun/test";
import type { NextjsBkndConfig } from "./nextjs.adapter";
import type { NextjsUserbaseConfig } from "./nextjs.adapter";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
describe("nextjs adapter", () => {
adapterTestSuite<NextjsBkndConfig>(bunTestRunner, {
adapterTestSuite<NextjsUserbaseConfig>(bunTestRunner, {
makeApp: nextjs.getApp,
makeHandler: nextjs.serve,
});
+6 -6
View File
@@ -1,21 +1,21 @@
import { createFrameworkApp, type FrameworkBkndConfig } from "bknd/adapter";
import { isNode } from "bknd/utils";
import { createFrameworkApp, type FrameworkUserbaseConfig } from "userbase/adapter";
import { isNode } from "userbase/utils";
// @ts-expect-error next is not installed
import type { NextApiRequest } from "next";
type NextjsEnv = NextApiRequest["env"];
export type NextjsBkndConfig<Env = NextjsEnv> = FrameworkBkndConfig<Env> & {
export type NextjsUserbaseConfig<Env = NextjsEnv> = FrameworkUserbaseConfig<Env> & {
cleanRequest?: { searchParams?: string[] };
};
export async function getApp<Env = NextjsEnv>(
config: NextjsBkndConfig<Env>,
config: NextjsUserbaseConfig<Env>,
args: Env = process.env as Env,
) {
return await createFrameworkApp(config, args);
}
function getCleanRequest(req: Request, cleanRequest: NextjsBkndConfig["cleanRequest"]) {
function getCleanRequest(req: Request, cleanRequest: NextjsUserbaseConfig["cleanRequest"]) {
if (!cleanRequest) return req;
const url = new URL(req.url);
@@ -41,7 +41,7 @@ function getCleanRequest(req: Request, cleanRequest: NextjsBkndConfig["cleanRequ
}
export function serve<Env = NextjsEnv>(
{ cleanRequest, ...config }: NextjsBkndConfig<Env> = {},
{ cleanRequest, ...config }: NextjsUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
return async (req: Request) => {
@@ -2,9 +2,9 @@ import {
genericSqlite,
type GenericSqliteConnection,
type GenericSqliteConnectionConfig,
} from "bknd";
} from "userbase";
import { DatabaseSync } from "node:sqlite";
import { omitKeys } from "bknd/utils";
import { omitKeys } from "userbase/utils";
export type NodeSqliteConnection = GenericSqliteConnection<DatabaseSync>;
export type NodeSqliteConnectionConfig = Omit<
+8 -8
View File
@@ -2,12 +2,12 @@ import path from "node:path";
import { serve as honoServe } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
import { registerLocalMediaAdapter } from "adapter/node/storage";
import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter";
import { config as $config, type App } from "bknd";
import { $console } from "bknd/utils";
import { type RuntimeUserbaseConfig, createRuntimeApp } from "userbase/adapter";
import { config as $config, type App } from "userbase";
import { $console } from "userbase/utils";
type NodeEnv = NodeJS.ProcessEnv;
export type NodeBkndConfig<Env = NodeEnv> = RuntimeBkndConfig<Env> & {
export type NodeUserbaseConfig<Env = NodeEnv> = RuntimeUserbaseConfig<Env> & {
port?: number;
hostname?: string;
listener?: Parameters<typeof honoServe>[1];
@@ -16,12 +16,12 @@ export type NodeBkndConfig<Env = NodeEnv> = RuntimeBkndConfig<Env> & {
};
export async function createApp<Env = NodeEnv>(
{ distPath, relativeDistPath, ...config }: NodeBkndConfig<Env> = {},
{ distPath, relativeDistPath, ...config }: NodeUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
const root = path.relative(
process.cwd(),
path.resolve(distPath ?? relativeDistPath ?? "./node_modules/bknd/dist", "static"),
path.resolve(distPath ?? relativeDistPath ?? "./node_modules/userbase/dist", "static"),
);
if (relativeDistPath) {
$console.warn("relativeDistPath is deprecated, please use distPath instead");
@@ -38,7 +38,7 @@ export async function createApp<Env = NodeEnv>(
}
export function createHandler<Env = NodeEnv>(
config: NodeBkndConfig<Env> = {},
config: NodeUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
let app: App | undefined;
@@ -51,7 +51,7 @@ export function createHandler<Env = NodeEnv>(
}
export function serve<Env = NodeEnv>(
{ port = $config.server.default_port, hostname, listener, ...config }: NodeBkndConfig<Env> = {},
{ port = $config.server.default_port, hostname, listener, ...config }: NodeUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
honoServe(
@@ -1,7 +1,7 @@
import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "bknd";
import { StorageAdapter, guessMimeType } from "bknd";
import { parse, s, isFile } from "bknd/utils";
import type { FileBody, FileListObject, FileMeta, FileUploadPayload } from "userbase";
import { StorageAdapter, guessMimeType } from "userbase";
import { parse, s, isFile } from "userbase/utils";
export const localAdapterConfig = s.object(
{
+1 -1
View File
@@ -1,4 +1,4 @@
import { registries } from "bknd";
import { registries } from "userbase";
import { type LocalAdapterConfig, StorageLocalAdapter } from "./StorageLocalAdapter";
export * from "./StorageLocalAdapter";
+7 -7
View File
@@ -1,15 +1,15 @@
import { createRuntimeApp, type RuntimeBkndConfig } from "bknd/adapter";
import { createRuntimeApp, type RuntimeUserbaseConfig } from "userbase/adapter";
export type NuxtEnv = NodeJS.ProcessEnv;
export type NuxtBkndConfig<Env = NuxtEnv> = RuntimeBkndConfig<Env>;
export type NuxtUserbaseConfig<Env = NuxtEnv> = RuntimeUserbaseConfig<Env>;
/**
* Get bknd app instance
* @param config - bknd configuration
* Get userbase app instance
* @param config - userbase configuration
* @param args - environment variables
*/
export async function getApp<Env>(
config: NuxtBkndConfig<Env> = {} as NuxtBkndConfig<Env>,
config: NuxtUserbaseConfig<Env> = {} as NuxtUserbaseConfig<Env>,
args: Env,
) {
return await createRuntimeApp(config, args);
@@ -17,10 +17,10 @@ export async function getApp<Env>(
/**
* Create middleware handler for Nuxt
* @param config - bknd configuration
* @param config - userbase configuration
* @param args - environment variables
*/
export function serve<Env>(config: NuxtBkndConfig<Env> = {} as NuxtBkndConfig<Env>, args: Env) {
export function serve<Env>(config: NuxtUserbaseConfig<Env> = {} as NuxtUserbaseConfig<Env>, args: Env) {
return async (request: Request) => {
return (await getApp(config, args)).fetch(request);
};
@@ -1,20 +1,20 @@
import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter";
import { type FrameworkUserbaseConfig, createFrameworkApp } from "userbase/adapter";
type ReactRouterEnv = NodeJS.ProcessEnv;
type ReactRouterFunctionArgs = {
request: Request;
};
export type ReactRouterBkndConfig<Env = ReactRouterEnv> = FrameworkBkndConfig<Env>;
export type ReactRouterUserbaseConfig<Env = ReactRouterEnv> = FrameworkUserbaseConfig<Env>;
export async function getApp<Env = ReactRouterEnv>(
config: ReactRouterBkndConfig<Env>,
config: ReactRouterUserbaseConfig<Env>,
args: Env = process.env as Env,
) {
return await createFrameworkApp(config, args);
}
export function serve<Env = ReactRouterEnv>(
config: ReactRouterBkndConfig<Env> = {},
config: ReactRouterUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
return async (fnArgs: ReactRouterFunctionArgs) => {
@@ -3,13 +3,13 @@ import * as solidStart from "./solid-start.adapter";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
import { adapterTestSuite } from "adapter/adapter-test-suite";
import { bunTestRunner } from "adapter/bun/test";
import type { SolidStartBkndConfig } from "./solid-start.adapter";
import type { SolidStartUserbaseConfig } from "./solid-start.adapter";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
describe("solid-start adapter", () => {
adapterTestSuite<SolidStartBkndConfig>(bunTestRunner, {
adapterTestSuite<SolidStartUserbaseConfig>(bunTestRunner, {
makeApp: solidStart.getApp,
makeHandler: solidStart.serve,
});
@@ -1,15 +1,15 @@
import { createRuntimeApp, type RuntimeBkndConfig } from "bknd/adapter";
import { createRuntimeApp, type RuntimeUserbaseConfig } from "userbase/adapter";
export type SolidStartEnv = NodeJS.ProcessEnv;
export type SolidStartBkndConfig<Env = SolidStartEnv> = RuntimeBkndConfig<Env>;
export type SolidStartUserbaseConfig<Env = SolidStartEnv> = RuntimeUserbaseConfig<Env>;
/**
* Get bknd app instance
* @param config - bknd configuration
* Get userbase app instance
* @param config - userbase configuration
* @param args - environment variables
*/
export async function getApp<Env = SolidStartEnv>(
config: SolidStartBkndConfig<Env>,
config: SolidStartUserbaseConfig<Env>,
args: Env = process.env as Env,
) {
return await createRuntimeApp(config, args);
@@ -17,11 +17,11 @@ export async function getApp<Env = SolidStartEnv>(
/**
* Create middleware handler for Solid Start
* @param config - bknd configuration
* @param config - userbase configuration
* @param args - environment variables
*/
export function serve<Env = SolidStartEnv>(
config: SolidStartBkndConfig<Env> = {},
config: SolidStartUserbaseConfig<Env> = {},
args: Env = process.env as Env,
) {
return async (req: Request) => {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Connection } from "bknd";
import type { Connection } from "userbase";
import { bunSqlite } from "../bun/connection/BunSqliteConnection";
export function sqlite(config?: { url: string }): Connection {
+1 -1
View File
@@ -1,4 +1,4 @@
import { type Connection, libsql } from "bknd";
import { type Connection, libsql } from "userbase";
export function sqlite(config: { url: string }): Connection {
return libsql(config);
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Connection } from "bknd";
import type { Connection } from "userbase";
import { nodeSqlite } from "../node/connection/NodeSqliteConnection";
export function sqlite(config?: { url: string }): Connection {
@@ -1,18 +1,18 @@
import { createRuntimeApp, type RuntimeBkndConfig } from "bknd/adapter";
import { createRuntimeApp, type RuntimeUserbaseConfig } from "userbase/adapter";
type TSvelteKit = {
request: Request;
};
export type SvelteKitBkndConfig<Env> = Pick<RuntimeBkndConfig<Env>, "adminOptions">;
export type SvelteKitUserbaseConfig<Env> = Pick<RuntimeUserbaseConfig<Env>, "adminOptions">;
/**
* Get bknd app instance
* @param config - bknd configuration
* Get userbase app instance
* @param config - userbase configuration
* @param args - environment variables (use $env/dynamic/private for universal runtime support)
*/
export async function getApp<Env>(
config: SvelteKitBkndConfig<Env> = {} as SvelteKitBkndConfig<Env>,
config: SvelteKitUserbaseConfig<Env> = {} as SvelteKitUserbaseConfig<Env>,
args: Env,
) {
return await createRuntimeApp(config, args);
@@ -20,11 +20,11 @@ export async function getApp<Env>(
/**
* Create request handler for hooks.server.ts
* @param config - bknd configuration
* @param config - userbase configuration
* @param args - environment variables (use $env/dynamic/private for universal runtime support)
*/
export function serve<Env>(
config: SvelteKitBkndConfig<Env> = {} as SvelteKitBkndConfig<Env>,
config: SvelteKitUserbaseConfig<Env> = {} as SvelteKitUserbaseConfig<Env>,
args: Env,
) {
return async (fnArgs: TSvelteKit) => {
@@ -1,12 +1,12 @@
import { createFrameworkApp, type FrameworkBkndConfig } from "bknd/adapter";
import { createFrameworkApp, type FrameworkUserbaseConfig } from "userbase/adapter";
export type TanstackStartEnv = NodeJS.ProcessEnv;
export type TanstackStartConfig<Env = TanstackStartEnv> = FrameworkBkndConfig<Env>;
export type TanstackStartConfig<Env = TanstackStartEnv> = FrameworkUserbaseConfig<Env>;
/**
* Get bknd app instance
* @param config - bknd configuration
* Get userbase app instance
* @param config - userbase configuration
* @param args - environment variables
*/
export async function getApp<Env = TanstackStartEnv>(
@@ -18,7 +18,7 @@ export async function getApp<Env = TanstackStartEnv>(
/**
* Create request handler for src/routes/api.$.ts
* @param config - bknd configuration
* @param config - userbase configuration
* @param args - environment variables
*/
export function serve<Env = TanstackStartEnv>(
+8 -8
View File
@@ -1,17 +1,17 @@
import { serveStatic } from "@hono/node-server/serve-static";
import { type DevServerOptions, default as honoViteDevServer } from "@hono/vite-dev-server";
import type { App } from "bknd";
import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter";
import { registerLocalMediaAdapter } from "bknd/adapter/node";
import type { App } from "userbase";
import { type RuntimeUserbaseConfig, createRuntimeApp } from "userbase/adapter";
import { registerLocalMediaAdapter } from "userbase/adapter/node";
import { devServerConfig } from "./dev-server-config";
import type { MiddlewareHandler } from "hono";
export type ViteEnv = NodeJS.ProcessEnv;
export type ViteBkndConfig<Env = ViteEnv> = RuntimeBkndConfig<Env> & {
export type ViteUserbaseConfig<Env = ViteEnv> = RuntimeUserbaseConfig<Env> & {
serveStatic?: false | MiddlewareHandler;
};
export function addViteScript(html: string, addBkndContext: boolean = true) {
export function addViteScript(html: string, addUserbaseContext: boolean = true) {
return html.replace(
"</head>",
`<script type="module">
@@ -22,13 +22,13 @@ window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>
<script type="module" src="/@vite/client"></script>
${addBkndContext ? "<!-- BKND_CONTEXT -->" : ""}
${addUserbaseContext ? "<!-- BKND_CONTEXT -->" : ""}
</head>`,
);
}
async function createApp<ViteEnv>(
config: ViteBkndConfig<ViteEnv> = {},
config: ViteUserbaseConfig<ViteEnv> = {},
env: ViteEnv = {} as ViteEnv,
): Promise<App> {
registerLocalMediaAdapter();
@@ -49,7 +49,7 @@ async function createApp<ViteEnv>(
);
}
export function serve<ViteEnv>(config: ViteBkndConfig<ViteEnv> = {}, args?: ViteEnv) {
export function serve<ViteEnv>(config: ViteUserbaseConfig<ViteEnv> = {}, args?: ViteEnv) {
return {
async fetch(request: Request, env: any, ctx: ExecutionContext) {
const app = await createApp(config, env);
+3 -3
View File
@@ -1,8 +1,8 @@
import type { DB, PrimaryFieldType } from "bknd";
import type { DB, PrimaryFieldType } from "userbase";
import * as AuthPermissions from "auth/auth-permissions";
import type { AuthStrategy } from "auth/authenticate/strategies/Strategy";
import type { PasswordStrategy } from "auth/authenticate/strategies/PasswordStrategy";
import { $console, secureRandomString, transformObject, pickKeys } from "bknd/utils";
import { $console, secureRandomString, transformObject, pickKeys } from "userbase/utils";
import type { Entity, EntityManager } from "data/entities";
import { em, entity, enumm, type FieldSchema } from "data/prototype";
import { Module } from "modules/Module";
@@ -16,7 +16,7 @@ import { Role } from "./authorize/Role";
export type UsersFields = typeof AppAuth.usersFields;
export type UserFieldSchema = FieldSchema<typeof AppAuth.usersFields>;
declare module "bknd" {
declare module "userbase" {
interface Users extends AppEntity, UserFieldSchema {}
interface DB {
users: Users;
+1 -1
View File
@@ -1,6 +1,6 @@
import { AppAuth } from "auth/AppAuth";
import type { CreateUser, SafeUser, User, UserPool } from "auth/authenticate/Authenticator";
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
import { pick } from "lodash-es";
import {
InvalidConditionsException,
+2 -2
View File
@@ -1,6 +1,6 @@
import type { AuthActionResponse } from "auth/api/AuthController";
import type { AppAuthSchema } from "auth/auth-schema";
import type { AuthResponse, SafeUser, AuthStrategy } from "bknd";
import type { AuthResponse, SafeUser, AuthStrategy } from "userbase";
import { type BaseModuleApiOptions, ModuleApi } from "modules/ModuleApi";
export type AuthApiOptions = BaseModuleApiOptions & {
@@ -69,7 +69,7 @@ export class AuthApi extends ModuleApi<AuthApiOptions> {
async logout() {
return this.get(["logout"], undefined, {
headers: {
// this way bknd detects a json request and doesn't redirect back
// this way userbase detects a json request and doesn't redirect back
Accept: "application/json",
},
}).then(() => this.options.onTokenUpdate?.(undefined, true));
+2 -2
View File
@@ -1,4 +1,4 @@
import type { DB, SafeUser } from "bknd";
import type { DB, SafeUser } from "userbase";
import type { AuthStrategy } from "auth/authenticate/strategies/Strategy";
import type { AppAuth } from "auth/AppAuth";
import * as AuthPermissions from "auth/auth-permissions";
@@ -14,7 +14,7 @@ import {
transformObject,
mcpTool,
$console,
} from "bknd/utils";
} from "userbase/utils";
import type { PasswordStrategy } from "auth/authenticate/strategies";
export type AuthActionResponse = {
+1 -1
View File
@@ -1,7 +1,7 @@
import { cookieConfig, jwtConfig } from "auth/authenticate/Authenticator";
import { CustomOAuthStrategy, OAuthStrategy, PasswordStrategy } from "auth/authenticate/strategies";
import { roleSchema } from "auth/authorize/Role";
import { objectTransform, omitKeys, pick, s } from "bknd/utils";
import { objectTransform, omitKeys, pick, s } from "userbase/utils";
import { $object, $record } from "modules/mcp";
export const Strategies = {
+2 -2
View File
@@ -1,4 +1,4 @@
import type { DB } from "bknd";
import type { DB } from "userbase";
import { Exception } from "core/errors";
import { addFlashMessage } from "core/server/flash";
import type { Context } from "hono";
@@ -7,7 +7,7 @@ import { sign, verify } from "hono/jwt";
import { type CookieOptions, serializeSigned } from "hono/utils/cookie";
import type { ServerEnv } from "modules/Controller";
import { InvalidConditionsException } from "auth/errors";
import { s, parse, secret, runtimeSupports, truncate, $console, pickKeys } from "bknd/utils";
import { s, parse, secret, runtimeSupports, truncate, $console, pickKeys } from "userbase/utils";
import type { AuthStrategy } from "./strategies/Strategy";
type Input = any; // workaround
@@ -1,7 +1,7 @@
import type { User } from "bknd";
import type { User } from "userbase";
import type { Authenticator } from "auth/authenticate/Authenticator";
import { InvalidCredentialsException } from "auth/errors";
import { hash, $console, s, parse, jsc, describeRoute } from "bknd/utils";
import { hash, $console, s, parse, jsc, describeRoute } from "userbase/utils";
import { Hono } from "hono";
import { compare as bcryptCompare, genSalt as bcryptGenSalt, hash as bcryptHash } from "bcryptjs";
import { AuthStrategy } from "./Strategy";
@@ -5,7 +5,7 @@ import type {
StrategyActions,
} from "../Authenticator";
import type { Hono } from "hono";
import { type s, parse } from "bknd/utils";
import { type s, parse } from "userbase/utils";
export type StrategyMode = "form" | "external";
@@ -1,6 +1,6 @@
import type * as oauth from "oauth4webapi";
import { OAuthStrategy } from "./OAuthStrategy";
import { s } from "bknd/utils";
import { s } from "userbase/utils";
type SupportedTypes = "oauth2" | "oidc";
@@ -3,7 +3,7 @@ import { type Context, Hono } from "hono";
import { getSignedCookie, setSignedCookie } from "hono/cookie";
import * as oauth from "oauth4webapi";
import * as issuers from "./issuers";
import { s, filterKeys } from "bknd/utils";
import { s, filterKeys } from "userbase/utils";
import { Exception } from "core/errors";
import { isDebug } from "core/env";
import { AuthStrategy } from "../Strategy";
@@ -37,7 +37,7 @@ export const github: IssuerConfig<GithubUserInfo> = {
try {
const res = await fetch("https://api.github.com/user/emails", {
headers: {
"User-Agent": "bknd", // this is mandatory... *smh*
"User-Agent": "userbase", // this is mandatory... *smh*
Accept: "application/json",
Authorization: `Bearer ${tokenResponse.access_token}`,
},
+2 -2
View File
@@ -1,10 +1,10 @@
import { Exception } from "core/errors";
import { $console, mergeObject, type s } from "bknd/utils";
import { $console, mergeObject, type s } from "userbase/utils";
import type { Permission, PermissionContext } from "auth/authorize/Permission";
import type { Context } from "hono";
import type { ServerEnv } from "modules/Controller";
import type { Role } from "./Role";
import { HttpStatus } from "bknd/utils";
import { HttpStatus } from "userbase/utils";
import type { Policy, PolicySchema } from "./Policy";
import { convert, type ObjectQuery } from "core/object/query/object-query";
+1 -1
View File
@@ -1,4 +1,4 @@
import { s, type ParseOptions, parse, InvalidSchemaError, HttpStatus } from "bknd/utils";
import { s, type ParseOptions, parse, InvalidSchemaError, HttpStatus } from "userbase/utils";
export const permissionOptionsSchema = s
.strictObject({
+1 -1
View File
@@ -1,4 +1,4 @@
import { s, parse, recursivelyReplacePlaceholders } from "bknd/utils";
import { s, parse, recursivelyReplacePlaceholders } from "userbase/utils";
import * as query from "core/object/query/object-query";
export const policySchema = s
+1 -1
View File
@@ -1,4 +1,4 @@
import { s } from "bknd/utils";
import { s } from "userbase/utils";
import { Permission } from "./Permission";
import { Policy, policySchema } from "./Policy";
+1 -1
View File
@@ -1,6 +1,6 @@
import { Exception } from "core/errors";
import { isDebug } from "core/env";
import { HttpStatus } from "bknd/utils";
import { HttpStatus } from "userbase/utils";
export class AuthException extends Exception {
getSafeErrorAndCode() {
+1 -1
View File
@@ -1,4 +1,4 @@
import { $console, patternMatch } from "bknd/utils";
import { $console, patternMatch } from "userbase/utils";
import type { Context } from "hono";
import { createMiddleware } from "hono/factory";
import type { ServerEnv } from "modules/Controller";
@@ -1,5 +1,5 @@
import type { Permission, PermissionContext } from "auth/authorize/Permission";
import { $console, threw } from "bknd/utils";
import { $console, threw } from "userbase/utils";
import type { Context, Hono } from "hono";
import type { RouterRoute } from "hono/types";
import { createMiddleware } from "hono/factory";
+1 -1
View File
@@ -4,7 +4,7 @@ import { makeAppFromEnv } from "cli/commands/run";
import { writeFile } from "node:fs/promises";
import c from "picocolors";
import { withConfigOptions } from "cli/utils/options";
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
export const config: CliCommand = (program) => {
withConfigOptions(program.command("config"))
+8 -8
View File
@@ -5,9 +5,9 @@ import type { CliCommand } from "cli/types";
import { typewriter, wait } from "cli/utils/cli";
import { execAsync, getVersion } from "cli/utils/sys";
import { Option } from "commander";
import { env } from "bknd";
import { env } from "userbase";
import color from "picocolors";
import { overridePackageJson, updateBkndPackages } from "./npm";
import { overridePackageJson, updateUserbasePackages } from "./npm";
import { type Template, templates, type TemplateSetupCtx } from "./templates";
import { createScoped, flush } from "cli/utils/telemetry";
import path from "node:path";
@@ -48,7 +48,7 @@ function errorOutro() {
// biome-ignore lint/suspicious/noConsoleLog:
console.log(
color.yellow("Sorry that this happened. If you think this is a bug, please report it at: ") +
color.cyan("https://github.com/bknd-io/bknd/issues"),
color.cyan("https://github.com/userbase-io/userbase/issues"),
);
// biome-ignore lint/suspicious/noConsoleLog:
console.log("");
@@ -80,12 +80,12 @@ async function action(options: {
const version = await getVersion();
$p.intro(
`👋 Welcome to the ${color.bold(color.cyan("bknd"))} create cli ${color.bold(`v${version}`)}`,
`👋 Welcome to the ${color.bold(color.cyan("userbase"))} create cli ${color.bold(`v${version}`)}`,
);
await $p.stream.message(
(async function* () {
yield* typewriter("Thanks for choosing to create a new project with bknd!", color.dim);
yield* typewriter("Thanks for choosing to create a new project with userbase!", color.dim);
await wait();
})(),
);
@@ -127,7 +127,7 @@ async function action(options: {
? downloadOpts.dir.split("/").pop()
: downloadOpts.dir.replace(/[./]/g, "");
if (!name || name.length === 0) name = "bknd";
if (!name || name.length === 0) name = "userbase";
let template: Template | undefined;
@@ -254,7 +254,7 @@ async function action(options: {
}
s.stop("Template downloaded.");
await updateBkndPackages(ctx.dir);
await updateUserbasePackages(ctx.dir);
if (template.preinstall) {
await template.preinstall(ctx);
@@ -335,7 +335,7 @@ async function action(options: {
yield "\n\n";
yield* typewriter(
`Enter your project's directory using ${color.cyan("cd " + ctx.dir)}
If you need help, check ${color.cyan("https://docs.bknd.io")} or join our Discord!`,
If you need help, check ${color.cyan("https://docs.userbase.io")} or join our Discord!`,
);
await wait(2);
})(),
+2 -2
View File
@@ -92,10 +92,10 @@ export async function replacePackageJsonVersions(
);
}
export async function updateBkndPackages(dir?: string, map?: Record<string, string>) {
export async function updateUserbasePackages(dir?: string, map?: Record<string, string>) {
try {
const versions = {
bknd: await sysGetVersion(),
userbase: await sysGetVersion(),
...(map ?? {}),
};
await replacePackageJsonVersions(
+2 -2
View File
@@ -9,8 +9,8 @@ export const aws = {
key: "aws",
title: "AWS Lambda Basic",
integration: "aws",
description: "A basic bknd AWS Lambda starter",
path: "gh:bknd-io/bknd/examples/aws-lambda",
description: "A basic userbase AWS Lambda starter",
path: "gh:userbase-io/userbase/examples/aws-lambda",
ref: true,
setup: async (ctx) => {
await $p.stream.info(
@@ -11,8 +11,8 @@ export const cloudflare = {
key: "cloudflare",
title: "Cloudflare Basic",
integration: "cloudflare",
description: "A basic bknd Cloudflare worker",
path: "gh:bknd-io/bknd/examples/cloudflare-worker",
description: "A basic userbase Cloudflare worker",
path: "gh:userbase-io/userbase/examples/cloudflare-worker",
ref: true,
setup: async (ctx) => {
// overwrite assets directory & name
@@ -22,7 +22,7 @@ export const cloudflare = {
...json,
name: ctx.name,
assets: {
directory: "node_modules/bknd/dist/static",
directory: "node_modules/userbase/dist/static",
},
}),
{ dir: ctx.dir },
@@ -6,15 +6,15 @@ export const deno = {
key: "deno",
title: "Deno Basic",
integration: "deno",
description: "A basic bknd Deno server with static assets",
path: "gh:bknd-io/bknd/examples/deno",
description: "A basic userbase Deno server with static assets",
path: "gh:userbase-io/userbase/examples/deno",
installDeps: false,
ref: true,
setup: async (ctx) => {
const version = await getVersion();
await overrideJson(
"deno.json",
(json) => ({ ...json, links: undefined, imports: { bknd: `npm:bknd@${version}` } }),
(json) => ({ ...json, links: undefined, imports: { userbase: `npm:userbase@${version}` } }),
{ dir: ctx.dir },
);
},
+13 -13
View File
@@ -33,7 +33,7 @@ export type Template = {
description?: string;
path: string;
/**
* adds a ref "#{ref}" to the path. If "true", adds the current version of bknd
* adds a ref "#{ref}" to the path. If "true", adds the current version of userbase
*/
ref?: true | string;
/**
@@ -53,48 +53,48 @@ export const templates: Template[] = [
key: "node",
title: "Node.js Basic",
integration: "node",
description: "A basic bknd Node.js server",
path: "gh:bknd-io/bknd/examples/node",
description: "A basic userbase Node.js server",
path: "gh:userbase-io/userbase/examples/node",
ref: true,
},
{
key: "bun",
title: "Bun Basic",
integration: "bun",
description: "A basic bknd Bun server",
path: "gh:bknd-io/bknd/examples/bun",
description: "A basic userbase Bun server",
path: "gh:userbase-io/userbase/examples/bun",
ref: true,
},
{
key: "nextjs",
title: "Next.js Basic",
integration: "nextjs",
description: "A basic bknd Next.js starter",
path: "gh:bknd-io/bknd/examples/nextjs",
description: "A basic userbase Next.js starter",
path: "gh:userbase-io/userbase/examples/nextjs",
ref: true,
},
{
key: "astro",
title: "Astro Basic",
integration: "astro",
description: "A basic bknd Astro starter",
path: "gh:bknd-io/bknd/examples/astro",
description: "A basic userbase Astro starter",
path: "gh:userbase-io/userbase/examples/astro",
ref: true,
},
{
key: "react-router",
title: "React Router Basic",
integration: "react-router",
description: "A basic bknd React Router starter",
path: "gh:bknd-io/bknd/examples/react-router",
description: "A basic userbase React Router starter",
path: "gh:userbase-io/userbase/examples/react-router",
ref: true,
},
{
key: "aws",
title: "AWS Lambda Basic",
integration: "aws",
description: "A basic bknd AWS Lambda starter",
path: "gh:bknd-io/bknd/examples/aws-lambda",
description: "A basic userbase AWS Lambda starter",
path: "gh:userbase-io/userbase/examples/aws-lambda",
ref: true,
},
deno,
+1 -1
View File
@@ -10,7 +10,7 @@ import type { CliCommand } from "../types";
export const debug: CliCommand = (program) => {
program
.command("debug")
.description("debug bknd")
.description("debug userbase")
.addArgument(new Argument("<subject>", "subject to debug").choices(Object.keys(subjects)))
.action(action);
};
+1 -1
View File
@@ -1,7 +1,7 @@
import type { CliCommand } from "cli/types";
import { makeAppFromEnv } from "../run";
import { getSystemMcp } from "modules/mcp/system-mcp";
import { $console, stdioTransport } from "bknd/utils";
import { $console, stdioTransport } from "userbase/utils";
import { withConfigOptions, type WithConfigOptions } from "cli/utils/options";
export const mcp: CliCommand = (program) =>
+2 -2
View File
@@ -1,5 +1,5 @@
import path from "node:path";
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
import type { MiddlewareHandler } from "hono";
import open from "open";
import { fileExists, getRelativeDistPath } from "../../utils/sys";
@@ -86,7 +86,7 @@ export async function getConfigPath(filePath?: string) {
}
const exts = ["", ".js", ".ts", ".mjs", ".cjs", ".json"];
const paths = exts.map((e) => `bknd.config${e}`);
const paths = exts.map((e) => `userbase.config${e}`);
for (const p of paths) {
const _p = path.resolve(process.cwd(), p);
if (await fileExists(_p)) {
+6 -6
View File
@@ -1,8 +1,8 @@
import type { Config } from "@libsql/client/node";
import { StorageLocalAdapter } from "adapter/node/storage";
import type { CliBkndConfig, CliCommand } from "cli/types";
import type { CliUserbaseConfig, CliCommand } from "cli/types";
import { Option } from "commander";
import { config, type App, type CreateAppConfig, type MaybePromise, registries } from "bknd";
import { config, type App, type CreateAppConfig, type MaybePromise, registries } from "userbase";
import dotenv from "dotenv";
import c from "picocolors";
import path from "node:path";
@@ -14,8 +14,8 @@ import {
serveStatic,
startServer,
} from "./platform";
import { createRuntimeApp, makeConfig } from "bknd/adapter";
import { colorizeConsole, isBun } from "bknd/utils";
import { createRuntimeApp, makeConfig } from "userbase/adapter";
import { colorizeConsole, isBun } from "userbase/utils";
import { withConfigOptions, type WithConfigOptions } from "cli/utils/options";
const env_files = [".env", ".dev.vars"];
@@ -69,7 +69,7 @@ async function makeApp(config: MakeAppConfig) {
});
}
export async function makeConfigApp(_config: CliBkndConfig, platform?: Platform) {
export async function makeConfigApp(_config: CliUserbaseConfig, platform?: Platform) {
const config = await makeConfig(_config, process.env);
return makeApp({
...config,
@@ -100,7 +100,7 @@ export async function makeAppFromEnv(options: Partial<RunOptions> = {}) {
} else if (configFilePath) {
console.info("Using config from", c.cyan(configFilePath));
try {
const config = (await import(configFilePath).then((m) => m.default)) as CliBkndConfig;
const config = (await import(configFilePath).then((m) => m.default)) as CliUserbaseConfig;
app = await makeConfigApp(config, options.server);
} catch (e) {
console.error("Failed to load config:", e);
+1 -1
View File
@@ -3,7 +3,7 @@ import { makeAppFromEnv } from "cli/commands/run";
import { writeFile } from "node:fs/promises";
import c from "picocolors";
import { withConfigOptions, type WithConfigOptions } from "cli/utils/options";
import { transformObject } from "bknd/utils";
import { transformObject } from "userbase/utils";
import { Option } from "commander";
export const secrets: CliCommand = (program) => {
+1 -1
View File
@@ -9,7 +9,7 @@ import { withConfigOptions, type WithConfigOptions } from "cli/utils/options";
export const types: CliCommand = (program) => {
withConfigOptions(program.command("types"))
.description("generate types")
.addOption(new Option("-o, --outfile <outfile>", "output file").default("bknd-types.d.ts"))
.addOption(new Option("-o, --outfile <outfile>", "output file").default("userbase-types.d.ts"))
.addOption(new Option("--dump", "dump types to console instead of writing to file"))
.action(action);
};
+1 -1
View File
@@ -10,7 +10,7 @@ import type { PasswordStrategy } from "auth/authenticate/strategies";
import { makeAppFromEnv } from "cli/commands/run";
import type { CliCommand } from "cli/types";
import { Argument } from "commander";
import { $console, isBun } from "bknd/utils";
import { $console, isBun } from "userbase/utils";
import c from "picocolors";
import { withConfigOptions, type WithConfigOptions } from "cli/utils/options";
+2 -2
View File
@@ -13,8 +13,8 @@ async function main() {
const version = await getVersion();
program
.name("bknd")
.description(color.yellowBright("⚡") + " bknd cli " + color.bold(color.cyan(`v${version}`)))
.name("userbase")
.description(color.yellowBright("⚡") + " userbase cli " + color.bold(color.cyan(`v${version}`)))
.version(version)
.hook("preAction", (thisCommand, actionCommand) => {
capture(`cmd_${actionCommand.name()}`);
+2 -2
View File
@@ -1,9 +1,9 @@
import type { BkndConfig } from "adapter";
import type { UserbaseConfig } from "adapter";
import type { Command } from "commander";
export type CliCommand = (program: Command) => void;
export type CliBkndConfig<Env = any> = BkndConfig & {
export type CliUserbaseConfig<Env = any> = UserbaseConfig & {
server?: {
port?: number;
platform?: "node" | "bun";
+1 -1
View File
@@ -1,4 +1,4 @@
import { $console } from "bknd/utils";
import { $console } from "userbase/utils";
import { execSync, exec as nodeExec } from "node:child_process";
import { readFile, writeFile as nodeWriteFile } from "node:fs/promises";
import path from "node:path";
+2 -2
View File
@@ -1,7 +1,7 @@
import { PostHog } from "posthog-js-lite";
import { getVersion } from "cli/utils/sys";
import { env, isDebug } from "bknd";
import { $console } from "bknd/utils";
import { env, isDebug } from "userbase";
import { $console } from "userbase/utils";
type Properties = { [p: string]: any };
@@ -12,9 +12,9 @@ describe.skipIf(ALL_TESTS)("mailchannels", () => {
it("should send an email", async () => {
const driver = mailchannelsEmail({
apiKey: process.env.MAILCHANNELS_API_KEY!,
from: { email: "accounts@bknd.io", name: "Dennis Senn" },
from: { email: "accounts@userbase.io", name: "Dennis Senn" },
});
const response = await driver.send("ds@bknd.io", "Test", "Test");
const response = await driver.send("ds@userbase.io", "Test", "Test");
expect(response).toBeDefined();
});
});
+1 -1
View File
@@ -1,4 +1,4 @@
import { mergeObject, type RecursivePartial } from "bknd/utils";
import { mergeObject, type RecursivePartial } from "userbase/utils";
import type { IEmailDriver } from "./index";
export type MailchannelsEmailOptions = {
+3 -3
View File
@@ -15,7 +15,7 @@ describe.skipIf(ALL_TESTS)("plunk", () => {
from: undefined, // Default to what Plunk sets
});
const response = await driver.send(
"help@bknd.io",
"help@userbase.io",
"Test Email from Plunk",
"This is a test email",
);
@@ -31,7 +31,7 @@ describe.skipIf(ALL_TESTS)("plunk", () => {
from: undefined,
});
const htmlBody = "<h1>Test Email</h1><p>This is a test email</p>";
const response = await driver.send("help@bknd.io", "HTML Test", htmlBody);
const response = await driver.send("help@userbase.io", "HTML Test", htmlBody);
expect(response).toBeDefined();
expect(response.success).toBe(true);
});
@@ -42,7 +42,7 @@ describe.skipIf(ALL_TESTS)("plunk", () => {
from: undefined,
});
const response = await driver.send("test@example.com", "Test Email", {
text: "help@bknd.io",
text: "help@userbase.io",
html: "<p>This is HTML</p>",
});
expect(response).toBeDefined();
+3 -2
View File
@@ -1,3 +1,4 @@
import { describe, it, expect } from "bun:test";
import { resendEmail } from "./resend";
@@ -12,9 +13,9 @@ describe.skipIf(ALL_TESTS)("resend", () => {
it("should send an email", async () => {
const driver = resendEmail({
apiKey: process.env.RESEND_API_KEY!,
from: "BKND <help@bknd.io>",
from: "BKND <help@userbase.io>",
});
const response = await driver.send("help@bknd.io", "Test", "Test");
const response = await driver.send("help@userbase.io", "Test", "Test");
expect(response).toBeDefined();
expect(response.id).toBeDefined();
});
+2 -2
View File
@@ -27,7 +27,7 @@ export class Exception extends Error {
}
}
export class BkndError extends Error {
export class UserbaseError extends Error {
constructor(
message: string,
public details?: Record<string, any>,
@@ -37,7 +37,7 @@ export class BkndError extends Error {
}
static with(message: string, details?: Record<string, any>, type?: string) {
throw new BkndError(message, details, type);
throw new UserbaseError(message, details, type);
}
toJSON() {

Some files were not shown because too many files have changed in this diff Show More