mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-17 12:56:05 +00:00
updated nextjs example with app router
This commit is contained in:
@@ -48,7 +48,7 @@ describe("App", () => {
|
||||
|
||||
const todos = await app.getApi().data.readMany("todos");
|
||||
expect(todos.length).toBe(2);
|
||||
expect(todos[0].title).toBe("ctx");
|
||||
expect(todos[1].title).toBe("api");
|
||||
expect(todos[0]?.title).toBe("ctx");
|
||||
expect(todos[1]?.title).toBe("api");
|
||||
});
|
||||
});
|
||||
|
||||
32
app/build.ts
32
app/build.ts
@@ -71,16 +71,19 @@ 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"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Building UI for direct imports
|
||||
*/
|
||||
async function buildUi() {
|
||||
await tsup.build({
|
||||
const base = {
|
||||
minify,
|
||||
sourcemap,
|
||||
watch,
|
||||
entry: ["src/ui/index.ts", "src/ui/client/index.ts", "src/ui/main.css", "src/ui/styles.css"],
|
||||
outDir: "dist/ui",
|
||||
external: [
|
||||
"bun:test",
|
||||
"react",
|
||||
@@ -104,7 +107,24 @@ async function buildUi() {
|
||||
esbuildOptions: (options) => {
|
||||
options.logLevel = "silent";
|
||||
},
|
||||
} satisfies tsup.Options;
|
||||
|
||||
await tsup.build({
|
||||
...base,
|
||||
entry: ["src/ui/index.ts", "src/ui/main.css", "src/ui/styles.css"],
|
||||
outDir: "dist/ui",
|
||||
onSuccess: async () => {
|
||||
await rewriteClient("./dist/ui/index.js");
|
||||
delayTypes();
|
||||
},
|
||||
});
|
||||
|
||||
await tsup.build({
|
||||
...base,
|
||||
entry: ["src/ui/client/index.ts"],
|
||||
outDir: "dist/ui/client",
|
||||
onSuccess: async () => {
|
||||
await rewriteClient("./dist/ui/client/index.js");
|
||||
delayTypes();
|
||||
},
|
||||
});
|
||||
@@ -146,11 +166,7 @@ async function buildUiElements() {
|
||||
};
|
||||
},
|
||||
onSuccess: async () => {
|
||||
// manually replace ui/client with bknd/client
|
||||
const path = "./dist/ui/elements/index.js";
|
||||
const bundle = await Bun.file(path).text();
|
||||
await Bun.write(path, bundle.replaceAll("ui/client", "bknd/client"));
|
||||
|
||||
await rewriteClient("./dist/ui/elements/index.js");
|
||||
delayTypes();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
"bin": "./dist/cli/index.js",
|
||||
"version": "0.9.0-rc.1",
|
||||
"version": "0.9.0-rc.1-7",
|
||||
"description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, Remix, Astro, Cloudflare, Bun, Node, AWS Lambda & more.",
|
||||
"homepage": "https://bknd.io",
|
||||
"repository": {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Api, type ApiOptions } from "Api";
|
||||
import type { CreateUserPayload } from "auth/AppAuth";
|
||||
import { $console } from "core";
|
||||
import { Event } from "core/events";
|
||||
@@ -188,12 +187,10 @@ export class App {
|
||||
return this.module.auth.createUser(p);
|
||||
}
|
||||
|
||||
async getApi(options?: LocalApiOptions) {
|
||||
getApi(options?: LocalApiOptions) {
|
||||
const fetcher = this.server.request as typeof fetch;
|
||||
if (options && options instanceof Request) {
|
||||
const api = new Api({ request: options, headers: options.headers, fetcher });
|
||||
await api.verifyAuth();
|
||||
return api;
|
||||
return new Api({ request: options, headers: options.headers, fetcher });
|
||||
}
|
||||
|
||||
return new Api({ host: "http://localhost", ...(options ?? {}), fetcher });
|
||||
|
||||
@@ -54,9 +54,9 @@ function AdminInternal() {
|
||||
);
|
||||
}
|
||||
|
||||
const Skeleton = ({ theme }: { theme?: string }) => {
|
||||
const actualTheme =
|
||||
(theme ?? document.querySelector("html")?.classList.contains("light")) ? "light" : "dark";
|
||||
const Skeleton = ({ theme }: { theme?: any }) => {
|
||||
const t = useTheme();
|
||||
const actualTheme = theme ?? t.theme;
|
||||
|
||||
return (
|
||||
<div id="bknd-admin" className={actualTheme + " antialiased"}>
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { AppTheme } from "modules/server/AppServer";
|
||||
import { useBkndWindowContext } from "ui/client/ClientProvider";
|
||||
import { useBknd } from "ui/client/bknd";
|
||||
|
||||
export function useTheme(fallback: AppTheme = "system"): { theme: AppTheme } {
|
||||
export function useTheme(fallback: AppTheme = "system") {
|
||||
const b = useBknd();
|
||||
const winCtx = useBkndWindowContext();
|
||||
|
||||
@@ -14,13 +14,16 @@ export function useTheme(fallback: AppTheme = "system"): { theme: AppTheme } {
|
||||
const override = b?.adminOverride?.color_scheme;
|
||||
const config = b?.config.server.admin.color_scheme;
|
||||
const win = winCtx.color_scheme;
|
||||
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
const prefersDark =
|
||||
typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
|
||||
const theme = override ?? config ?? win ?? fallback;
|
||||
|
||||
if (theme === "system") {
|
||||
return { theme: prefersDark ? "dark" : "light" };
|
||||
}
|
||||
|
||||
return { theme };
|
||||
return {
|
||||
theme: (theme === "system" ? (prefersDark ? "dark" : "light") : theme) as AppTheme,
|
||||
prefersDark,
|
||||
override,
|
||||
config,
|
||||
win,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
// there is no lifecycle or Hook in React that we can use to switch
|
||||
// .current at the right timing."
|
||||
// So we will have to make do with this "close enough" approach for now.
|
||||
import { useInsertionEffect, useRef } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export const useEvent = <Fn>(fn: Fn | ((...args: any[]) => any) | undefined): Fn => {
|
||||
const ref = useRef([fn, (...args) => ref[0](...args)]).current;
|
||||
// Per Dan Abramov: useInsertionEffect executes marginally closer to the
|
||||
// correct timing for ref synchronization than useLayoutEffect on React 18.
|
||||
// See: https://github.com/facebook/react/pull/25881#issuecomment-1356244360
|
||||
useInsertionEffect(() => {
|
||||
useEffect(() => {
|
||||
ref[0] = fn;
|
||||
});
|
||||
}, []);
|
||||
return ref[1];
|
||||
};
|
||||
|
||||
@@ -45,7 +45,6 @@ export function StepEntityFields() {
|
||||
const values = watch();
|
||||
|
||||
const updateListener = useEvent((data: TAppDataEntityFields) => {
|
||||
console.log("updateListener", data);
|
||||
setValue("fields", data as any);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Type } from "core/utils";
|
||||
import { type Entity, querySchema } from "data";
|
||||
import { Fragment } from "react";
|
||||
import { TbDots } from "react-icons/tb";
|
||||
import { useApi, useApiQuery } from "ui/client";
|
||||
import { useApiQuery } from "ui/client";
|
||||
import { useBknd } from "ui/client/bknd";
|
||||
import { useBkndData } from "ui/client/schema/data/use-bknd-data";
|
||||
import { Button } from "ui/components/buttons/Button";
|
||||
@@ -83,7 +83,7 @@ export function DataEntityList({ params }) {
|
||||
search.set("perPage", perPage);
|
||||
}
|
||||
|
||||
const isUpdating = $q.isLoading && $q.isValidating;
|
||||
const isUpdating = $q.isLoading || $q.isValidating;
|
||||
|
||||
return (
|
||||
<Fragment key={entity.name}>
|
||||
|
||||
@@ -108,9 +108,7 @@ export const EntityFieldsForm = forwardRef<EntityFieldsFormRef, EntityFieldsForm
|
||||
|
||||
useEffect(() => {
|
||||
if (props?.onChange) {
|
||||
console.log("----set");
|
||||
watch((data: any) => {
|
||||
console.log("---calling");
|
||||
props?.onChange?.(toCleanValues(data));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user