diff --git a/bun.lock b/bun.lock index aa87c959df..2a79552b9e 100644 --- a/bun.lock +++ b/bun.lock @@ -745,7 +745,7 @@ "cross-spawn": "7.0.6", "diff": "8.0.2", "dompurify": "3.3.1", - "drizzle-kit": "1.0.0-beta.22", + "drizzle-kit": "1.0.0-beta.19-d95b7a4", "drizzle-orm": "1.0.0-beta.19-d95b7a4", "effect": "4.0.0-beta.65", "fuzzysort": "3.1.0", @@ -2972,7 +2972,7 @@ "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], - "drizzle-kit": ["drizzle-kit@1.0.0-beta.22", "", { "dependencies": { "@drizzle-team/brocli": "^0.11.0", "@js-temporal/polyfill": "^0.5.1", "esbuild": "^0.25.10", "get-tsconfig": "^4.13.6", "jiti": "^2.6.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-9HTZuQRljQKTgCx4UhiGn8KYYfHGk4+B/bRR1714W67kz0qgJvdrG527i8rQD8uUyET9UTGR1u8syySJD4znGw=="], + "drizzle-kit": ["drizzle-kit@1.0.0-beta.19-d95b7a4", "", { "dependencies": { "@drizzle-team/brocli": "^0.11.0", "@js-temporal/polyfill": "^0.5.1", "esbuild": "^0.25.10", "get-tsconfig": "^4.13.6", "jiti": "^2.6.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-M0sqc+42TYBod6kEZ3AsW6+JWe3+76gR1aDFbHH5DmuLKEwewmbzlhBG6qnvV6YA1cIIbkuam3dC7r6PREOCXw=="], "drizzle-orm": ["drizzle-orm@1.0.0-beta.19-d95b7a4", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql": "^0.48.5", "@effect/sql-pg": "^0.49.7", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@sinclair/typebox": ">=0.34.8", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.2.1", "@tursodatabase/database-common": ">=0.2.1", "@tursodatabase/database-wasm": ">=0.2.1", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "arktype": ">=2.0.0", "better-sqlite3": ">=9.3.0", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5", "typebox": ">=1.0.0", "valibot": ">=1.0.0-beta.7", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql", "@effect/sql-pg", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@sinclair/typebox", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "arktype", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "mysql2", "pg", "postgres", "sql.js", "sqlite3", "typebox", "valibot", "zod"] }, "sha512-bZZKKeoRKrMVU6zKTscjrSH0+WNb1WEi3N0Jl4wEyQ7aQpTgHzdYY6IJQ1P0M74HuSJVeX4UpkFB/S6dtqLEJg=="], diff --git a/package.json b/package.json index 6205d8773b..f1cc7da5c3 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@tailwindcss/vite": "4.1.11", "diff": "8.0.2", "dompurify": "3.3.1", - "drizzle-kit": "1.0.0-beta.22", + "drizzle-kit": "1.0.0-beta.19-d95b7a4", "drizzle-orm": "1.0.0-beta.19-d95b7a4", "effect": "4.0.0-beta.65", "ai": "6.0.168", diff --git a/packages/console/app/src/component/go-referral.tsx b/packages/console/app/src/component/go-referral.tsx index 6f0b305bb8..22aaa5976c 100644 --- a/packages/console/app/src/component/go-referral.tsx +++ b/packages/console/app/src/component/go-referral.tsx @@ -1,6 +1,5 @@ import { action, createAsync, json, query, useAction, useSubmission } from "@solidjs/router" -import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js" -import { getRequestEvent } from "solid-js/web" +import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js" import { Referral } from "@opencode-ai/console-core/referral.js" import { withActor } from "~/context/auth.withActor" import { Modal } from "~/component/modal" @@ -11,38 +10,10 @@ import { formatResetTime, liteResetTimeKeys } from "~/lib/format-reset-time" import { queryLiteSubscription } from "~/routes/workspace/[id]/go/lite-section" import "./go-referral.css" -type GoReferralReward = { - id: string - amount: number - email: string - source: "inviter" | "invitee" - status: "pending" | "available" | "applied" - timeCreated: string | Date - timeApplied: string | Date | null -} - -type GoReferralSummary = { - inviteCode: string - inviteUrl: string - validInviteCount: number - hasActiveGo: boolean - rewardAmount: number - totalEarned: number - totalApplied: number - rewards: GoReferralReward[] -} - -type GoReferralUsagePreview = { - rollingUsage: GoReferralUsagePreviewItem - weeklyUsage: GoReferralUsagePreviewItem - monthlyUsage: GoReferralUsagePreviewItem -} - -type GoReferralUsagePreviewItem = { - beforePercent: number - afterPercent: number - resetInSec: number -} +type GoReferralSummary = Awaited> +type GoReferralReward = GoReferralSummary["rewards"][number] +type GoReferralUsagePreview = NonNullable>> +type GoReferralUsagePreviewItem = GoReferralUsagePreview["rollingUsage"] const emptyUsagePreview = { rollingUsage: { beforePercent: 0, afterPercent: 0, resetInSec: 0 }, @@ -52,13 +23,7 @@ const emptyUsagePreview = { export const queryGoReferral = query(async (workspaceID: string) => { "use server" - return withActor(async () => { - const summary = await Referral.summary() - return { - ...summary, - inviteUrl: new URL(`/go?invite=${summary.inviteCode}`, getRequestEvent()!.request.url).toString(), - } satisfies GoReferralSummary - }, workspaceID) + return withActor(() => Referral.summary(), workspaceID) }, "go.referral.get") export const queryGoReferralUsagePreview = query(async (workspaceID: string, referralID?: string) => { @@ -70,13 +35,7 @@ export const queryGoReferralUsagePreview = query(async (workspaceID: string, ref export const applyGoReferralReward = action(async (workspaceID: string, referralID: string) => { "use server" return json( - await withActor( - () => - Referral.applyReward({ referralID }) - .then((data) => ({ error: undefined, data })) - .catch((e) => ({ error: e.message as string, data: undefined })), - workspaceID, - ), + await withActor(() => Referral.applyReward({ referralID }), workspaceID), { revalidate: [queryGoReferral.key, queryGoReferralUsagePreview.key, queryLiteSubscription.key] }, ) }, "go.referral.reward.apply") @@ -114,10 +73,18 @@ function rewardPendingStatusKey(source: GoReferralReward["source"]) { function CopyInviteLink(props: { summary: GoReferralSummary }) { const i18n = useI18n() const [copied, setCopied] = createSignal(false) + const [origin, setOrigin] = createSignal("") + const inviteUrl = createMemo(() => { + const path = `/go?invite=${props.summary.inviteCode}` + if (!origin()) return path + return new URL(path, origin()).toString() + }) + + onMount(() => setOrigin(window.location.origin)) async function copy() { if (typeof navigator !== "object") return - await navigator.clipboard.writeText(props.summary.inviteUrl) + await navigator.clipboard.writeText(inviteUrl()) setCopied(true) window.setTimeout(() => setCopied(false), 1600) } @@ -125,7 +92,7 @@ function CopyInviteLink(props: { summary: GoReferralSummary }) { return (
- {props.summary.inviteUrl} + {inviteUrl()}