mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
Refactored asset handling to support multiple CSS entries and fixed context handling in authenticator when executed through mcp. Adjusted UI readonly conditions.
323 lines
7.7 KiB
TypeScript
323 lines
7.7 KiB
TypeScript
import { $ } from "bun";
|
|
import * as tsup from "tsup";
|
|
import pkg from "./package.json" with { type: "json" };
|
|
import c from "picocolors";
|
|
|
|
const args = process.argv.slice(2);
|
|
const watch = args.includes("--watch");
|
|
const minify = args.includes("--minify");
|
|
const types = args.includes("--types");
|
|
const sourcemap = args.includes("--sourcemap");
|
|
const clean = args.includes("--clean");
|
|
|
|
// silence tsup
|
|
const oldConsole = {
|
|
log: console.log,
|
|
warn: console.warn,
|
|
};
|
|
console.log = () => {};
|
|
console.warn = () => {};
|
|
|
|
const define = {
|
|
__isDev: "0",
|
|
__version: JSON.stringify(pkg.version),
|
|
};
|
|
|
|
if (clean) {
|
|
console.info("Cleaning dist (w/o static)");
|
|
await $`find dist -mindepth 1 ! -path "dist/static/*" ! -path "dist/static" -exec rm -rf {} +`;
|
|
}
|
|
|
|
let types_running = false;
|
|
function buildTypes() {
|
|
if (types_running || !types) return;
|
|
types_running = true;
|
|
|
|
Bun.spawn(["bun", "build:types"], {
|
|
stdout: "inherit",
|
|
onExit: () => {
|
|
oldConsole.log(c.cyan("[Types]"), c.green("built"));
|
|
Bun.spawn(["bun", "tsc-alias"], {
|
|
stdout: "inherit",
|
|
onExit: () => {
|
|
oldConsole.log(c.cyan("[Types]"), c.green("aliased"));
|
|
types_running = false;
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
if (types && !watch) {
|
|
buildTypes();
|
|
}
|
|
|
|
let watcher_timeout: any;
|
|
function delayTypes() {
|
|
if (!watch || !types) return;
|
|
if (watcher_timeout) {
|
|
clearTimeout(watcher_timeout);
|
|
}
|
|
watcher_timeout = setTimeout(buildTypes, 1000);
|
|
}
|
|
|
|
const dependencies = Object.keys(pkg.dependencies);
|
|
|
|
// collection of always-external packages
|
|
const external = [
|
|
...dependencies,
|
|
"bun:test",
|
|
"node:test",
|
|
"node:assert/strict",
|
|
"@libsql/client",
|
|
"bknd",
|
|
/^bknd\/.*/,
|
|
"jsonv-ts",
|
|
/^jsonv-ts\/.*/,
|
|
] as const;
|
|
|
|
/**
|
|
* Building backend and general API
|
|
*/
|
|
async function buildApi() {
|
|
await tsup.build({
|
|
minify,
|
|
sourcemap,
|
|
watch,
|
|
define,
|
|
entry: ["src/index.ts", "src/core/utils/index.ts", "src/plugins/index.ts"],
|
|
outDir: "dist",
|
|
external: [...external],
|
|
metafile: true,
|
|
target: "esnext",
|
|
platform: "browser",
|
|
format: ["esm"],
|
|
splitting: false,
|
|
loader: {
|
|
".svg": "dataurl",
|
|
},
|
|
onSuccess: async () => {
|
|
delayTypes();
|
|
oldConsole.log(c.cyan("[API]"), c.green("built"));
|
|
},
|
|
});
|
|
}
|
|
|
|
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() {
|
|
const base = {
|
|
minify,
|
|
sourcemap,
|
|
watch,
|
|
define,
|
|
external: [
|
|
...external,
|
|
"react",
|
|
"react-dom",
|
|
"react/jsx-runtime",
|
|
"react/jsx-dev-runtime",
|
|
"use-sync-external-store",
|
|
/codemirror/,
|
|
"@xyflow/react",
|
|
"@mantine/core",
|
|
],
|
|
metafile: true,
|
|
platform: "browser",
|
|
format: ["esm"],
|
|
splitting: false,
|
|
bundle: true,
|
|
treeshake: true,
|
|
loader: {
|
|
".svg": "dataurl",
|
|
},
|
|
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();
|
|
oldConsole.log(c.cyan("[UI]"), c.green("built"));
|
|
},
|
|
});
|
|
|
|
await tsup.build({
|
|
...base,
|
|
entry: ["src/ui/client/index.ts"],
|
|
outDir: "dist/ui/client",
|
|
onSuccess: async () => {
|
|
await rewriteClient("./dist/ui/client/index.js");
|
|
delayTypes();
|
|
oldConsole.log(c.cyan("[UI]"), "Client", c.green("built"));
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Building UI Elements
|
|
* - tailwind-merge is mocked, no exclude
|
|
* - ui/client is external, and after built replaced with "bknd/client"
|
|
*/
|
|
async function buildUiElements() {
|
|
await tsup.build({
|
|
minify,
|
|
sourcemap,
|
|
watch,
|
|
define,
|
|
entry: ["src/ui/elements/index.ts"],
|
|
outDir: "dist/ui/elements",
|
|
external: [
|
|
"ui/client",
|
|
"react",
|
|
"react-dom",
|
|
"react/jsx-runtime",
|
|
"react/jsx-dev-runtime",
|
|
"use-sync-external-store",
|
|
],
|
|
metafile: true,
|
|
platform: "browser",
|
|
format: ["esm"],
|
|
splitting: false,
|
|
bundle: true,
|
|
treeshake: true,
|
|
loader: {
|
|
".svg": "dataurl",
|
|
},
|
|
esbuildOptions: (options) => {
|
|
options.alias = {
|
|
// not important for elements, mock to reduce bundle
|
|
"tailwind-merge": "./src/ui/elements/mocks/tailwind-merge.ts",
|
|
};
|
|
},
|
|
onSuccess: async () => {
|
|
await rewriteClient("./dist/ui/elements/index.js");
|
|
delayTypes();
|
|
oldConsole.log(c.cyan("[UI]"), "Elements", c.green("built"));
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Building adapters
|
|
*/
|
|
function baseConfig(adapter: string, overrides: Partial<tsup.Options> = {}): tsup.Options {
|
|
return {
|
|
minify,
|
|
sourcemap,
|
|
watch,
|
|
entry: [`src/adapter/${adapter}/index.ts`],
|
|
format: ["esm"],
|
|
platform: "neutral",
|
|
outDir: `dist/adapter/${adapter}`,
|
|
metafile: true,
|
|
splitting: false,
|
|
onSuccess: async () => {
|
|
delayTypes();
|
|
oldConsole.log(c.cyan("[Adapter]"), adapter || "base", c.green("built"));
|
|
},
|
|
...overrides,
|
|
define: {
|
|
...define,
|
|
...overrides.define,
|
|
},
|
|
external: [
|
|
/^cloudflare*/,
|
|
/^@?hono.*?/,
|
|
/^(bknd|react|next|node).*?/,
|
|
/.*\.(html)$/,
|
|
...external,
|
|
...(Array.isArray(overrides.external) ? overrides.external : []),
|
|
],
|
|
};
|
|
}
|
|
|
|
async function buildAdapters() {
|
|
await Promise.all([
|
|
// base adapter handles
|
|
tsup.build({
|
|
...baseConfig(""),
|
|
target: "esnext",
|
|
platform: "neutral",
|
|
entry: ["src/adapter/index.ts"],
|
|
outDir: "dist/adapter",
|
|
// only way to keep @vite-ignore comments
|
|
minify: false,
|
|
}),
|
|
|
|
// specific adatpers
|
|
tsup.build(baseConfig("react-router")),
|
|
tsup.build(
|
|
baseConfig("bun", {
|
|
external: [/^bun\:.*/],
|
|
}),
|
|
),
|
|
tsup.build(baseConfig("astro")),
|
|
tsup.build(baseConfig("aws")),
|
|
tsup.build(
|
|
baseConfig("cloudflare", {
|
|
external: ["wrangler", "node:process"],
|
|
}),
|
|
),
|
|
tsup.build(
|
|
baseConfig("cloudflare/proxy", {
|
|
entry: ["src/adapter/cloudflare/proxy.ts"],
|
|
outDir: "dist/adapter/cloudflare",
|
|
metafile: false,
|
|
external: [/bknd/, "wrangler", "node:process"],
|
|
}),
|
|
),
|
|
|
|
tsup.build({
|
|
...baseConfig("vite"),
|
|
platform: "node",
|
|
}),
|
|
|
|
tsup.build({
|
|
...baseConfig("nextjs"),
|
|
platform: "node",
|
|
}),
|
|
|
|
tsup.build({
|
|
...baseConfig("node"),
|
|
platform: "node",
|
|
}),
|
|
|
|
tsup.build({
|
|
...baseConfig("sqlite/edge"),
|
|
entry: ["src/adapter/sqlite/edge.ts"],
|
|
outDir: "dist/adapter/sqlite",
|
|
metafile: false,
|
|
}),
|
|
|
|
tsup.build({
|
|
...baseConfig("sqlite/node"),
|
|
entry: ["src/adapter/sqlite/node.ts"],
|
|
outDir: "dist/adapter/sqlite",
|
|
platform: "node",
|
|
metafile: false,
|
|
}),
|
|
|
|
tsup.build({
|
|
...baseConfig("sqlite/bun"),
|
|
entry: ["src/adapter/sqlite/bun.ts"],
|
|
outDir: "dist/adapter/sqlite",
|
|
metafile: false,
|
|
external: [/^bun\:.*/],
|
|
}),
|
|
]);
|
|
}
|
|
|
|
await Promise.all([buildApi(), buildUi(), buildUiElements(), buildAdapters()]);
|