mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
Adds isolated Convex-backed Vercel PR previews with shared local/preview seeding, preview-safe routing, and production guards.
228 lines
7.8 KiB
TypeScript
228 lines
7.8 KiB
TypeScript
import { createRequire } from "node:module";
|
|
import { dirname, join } from "node:path";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
import { devtools } from "@tanstack/devtools-vite";
|
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
import viteReact from "@vitejs/plugin-react";
|
|
import { nitro } from "nitro/vite";
|
|
import { defineConfig, type Plugin } from "vite";
|
|
import { copyOgAssets } from "./scripts/copy-og-assets";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
const convexEntry = require.resolve("convex");
|
|
const convexRoot = dirname(dirname(dirname(convexEntry)));
|
|
const convexReactPath = join(convexRoot, "dist/esm/react/index.js");
|
|
const convexBrowserPath = join(convexRoot, "dist/esm/browser/index.js");
|
|
const convexValuesPath = join(convexRoot, "dist/esm/values/index.js");
|
|
const convexAuthReactPath = require.resolve("@convex-dev/auth/react");
|
|
|
|
function handleRollupWarning(
|
|
warning: { code?: string; message: string; id?: string },
|
|
warn: (warning: { code?: string; message: string; id?: string }) => void,
|
|
) {
|
|
if (
|
|
warning.code === "MODULE_LEVEL_DIRECTIVE" &&
|
|
warning.id?.includes("node_modules") &&
|
|
/use client/i.test(warning.message)
|
|
) {
|
|
return;
|
|
}
|
|
if (
|
|
warning.code === "UNUSED_EXTERNAL_IMPORT" &&
|
|
/@tanstack\/start-|@tanstack\/router-core\/ssr\/(client|server)/.test(warning.message)
|
|
) {
|
|
return;
|
|
}
|
|
if (warning.code === "EMPTY_BUNDLE" || /Generated an empty chunk/i.test(warning.message)) {
|
|
return;
|
|
}
|
|
warn(warning);
|
|
}
|
|
|
|
type SourceReplacement = readonly [from: string, to: string];
|
|
|
|
const reflectHas = (target: string, key: string) =>
|
|
`Reflect.has(${target}, ${JSON.stringify(key)})`;
|
|
|
|
const arkSafariInOperatorFixes = [
|
|
{
|
|
suffix: "/node_modules/.vite/deps/arktype.js",
|
|
replacements: [
|
|
['"expression" in value', reflectHas("value", "expression")],
|
|
['"toJSON" in o', reflectHas("o", "toJSON")],
|
|
['"morphs" in schema', reflectHas("schema", "morphs")],
|
|
['"branches" in schema', reflectHas("schema", "branches")],
|
|
['"unit" in schema', reflectHas("schema", "unit")],
|
|
['"reference" in schema', reflectHas("schema", "reference")],
|
|
['"proto" in schema', reflectHas("schema", "proto")],
|
|
['"domain" in schema', reflectHas("schema", "domain")],
|
|
['"value" in transformedInner', reflectHas("transformedInner", "value")],
|
|
['"default" in this.inner', reflectHas("this.inner", "default")],
|
|
['"variadic" in schema', reflectHas("schema", "variadic")],
|
|
['"prefix" in schema', reflectHas("schema", "prefix")],
|
|
['"defaultables" in schema', reflectHas("schema", "defaultables")],
|
|
['"optionals" in schema', reflectHas("schema", "optionals")],
|
|
['"postfix" in schema', reflectHas("schema", "postfix")],
|
|
['"minVariadicLength" in schema', reflectHas("schema", "minVariadicLength")],
|
|
['"description" in ctx', reflectHas("ctx", "description")],
|
|
['"data" in input', reflectHas("input", "data")],
|
|
['"get" in desc', reflectHas("desc", "get")],
|
|
['"set" in desc', reflectHas("desc", "set")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/util/out/serialize.js",
|
|
replacements: [
|
|
['"expression" in value', reflectHas("value", "expression")],
|
|
['"toJSON" in o', reflectHas("o", "toJSON")],
|
|
],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/parse.js",
|
|
replacements: [
|
|
['"morphs" in schema', reflectHas("schema", "morphs")],
|
|
['"branches" in schema', reflectHas("schema", "branches")],
|
|
['"unit" in schema', reflectHas("schema", "unit")],
|
|
['"reference" in schema', reflectHas("schema", "reference")],
|
|
['"proto" in schema', reflectHas("schema", "proto")],
|
|
['"domain" in schema', reflectHas("schema", "domain")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/node.js",
|
|
replacements: [
|
|
['"value" in transformedInner', reflectHas("transformedInner", "value")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/scope.js",
|
|
replacements: [
|
|
['"branches" in schema', reflectHas("schema", "branches")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/structure/optional.js",
|
|
replacements: [
|
|
['"default" in this.inner', reflectHas("this.inner", "default")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/structure/sequence.js",
|
|
replacements: [
|
|
['"variadic" in schema', reflectHas("schema", "variadic")],
|
|
['"prefix" in schema', reflectHas("schema", "prefix")],
|
|
['"defaultables" in schema', reflectHas("schema", "defaultables")],
|
|
['"optionals" in schema', reflectHas("schema", "optionals")],
|
|
['"postfix" in schema', reflectHas("schema", "postfix")],
|
|
['"minVariadicLength" in schema', reflectHas("schema", "minVariadicLength")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/structure/prop.js",
|
|
replacements: [
|
|
['"default" in this.inner', reflectHas("this.inner", "default")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/shared/implement.js",
|
|
replacements: [
|
|
['"description" in ctx', reflectHas("ctx", "description")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/schema/out/shared/errors.js",
|
|
replacements: [['"data" in input', reflectHas("input", "data")]] satisfies SourceReplacement[],
|
|
},
|
|
{
|
|
suffix: "/node_modules/@ark/util/out/clone.js",
|
|
replacements: [
|
|
['"get" in desc', reflectHas("desc", "get")],
|
|
['"set" in desc', reflectHas("desc", "set")],
|
|
] satisfies SourceReplacement[],
|
|
},
|
|
] as const;
|
|
|
|
function patchArkSafariInOperator(): Plugin {
|
|
return {
|
|
name: "patch-ark-safari-in-operator",
|
|
enforce: "pre",
|
|
transform(code, id) {
|
|
const normalizedId = id.split("?")[0].replace(/\\/g, "/");
|
|
const fix = arkSafariInOperatorFixes.find((entry) => normalizedId.endsWith(entry.suffix));
|
|
if (!fix) return null;
|
|
|
|
let nextCode = code;
|
|
for (const [from, to] of fix.replacements) {
|
|
if (!nextCode.includes(from)) {
|
|
this.error(`Expected to patch ${from} in ${normalizedId}`);
|
|
}
|
|
nextCode = nextCode.replaceAll(from, to);
|
|
}
|
|
|
|
return {
|
|
code: nextCode,
|
|
map: null,
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
function copyOgAssetsPlugin(): Plugin {
|
|
return {
|
|
name: "copy-og-assets",
|
|
apply: "build",
|
|
async closeBundle() {
|
|
await copyOgAssets();
|
|
},
|
|
};
|
|
}
|
|
|
|
const config = defineConfig({
|
|
resolve: {
|
|
dedupe: ["convex", "@convex-dev/auth", "react", "react-dom"],
|
|
alias: {
|
|
"convex/react": convexReactPath,
|
|
"convex/browser": convexBrowserPath,
|
|
"convex/values": convexValuesPath,
|
|
"@convex-dev/auth/react": convexAuthReactPath,
|
|
// MarkdownPreview uses Shiki's JavaScript engine; keep rehype from
|
|
// selecting the WASM-only `shiki/core` export condition.
|
|
"shiki/core": "shiki/dist/core.mjs",
|
|
},
|
|
// Use native Vite tsconfig paths resolution instead of the plugin
|
|
tsconfigPaths: true,
|
|
},
|
|
optimizeDeps: {
|
|
include: ["convex/react", "convex/browser"],
|
|
},
|
|
plugins: [
|
|
patchArkSafariInOperator(),
|
|
devtools(),
|
|
nitro({
|
|
serverDir: "server",
|
|
handlers: [
|
|
{ route: "/api/**", handler: "./server/handlers/convexProxy.ts" },
|
|
{ route: "/v1/feeds/**", handler: "./server/handlers/convexProxy.ts" },
|
|
],
|
|
rollupConfig: {
|
|
onwarn: handleRollupWarning,
|
|
},
|
|
}),
|
|
tailwindcss(),
|
|
tanstackStart(),
|
|
viteReact(),
|
|
copyOgAssetsPlugin(),
|
|
],
|
|
build: {
|
|
// Keep the shipped client bundle parseable in Safari/WebKit.
|
|
target: "safari15",
|
|
chunkSizeWarningLimit: 900,
|
|
rollupOptions: {
|
|
onwarn: handleRollupWarning,
|
|
},
|
|
},
|
|
});
|
|
|
|
export default config;
|