From 2b9df3106f437687aab6cfe1278fd47ef4191a6c Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Wed, 26 Mar 2025 03:52:31 -0400 Subject: [PATCH] fixed some supabase errors --- apps/desktop/dev.ts | 8 +++ apps/desktop/src/lib/utils/updater.ts | 27 +++++--- .../routes/app/extension/store/+page.svelte | 69 ++++++++++--------- .../src/routes/app/extension/store/+page.ts | 33 ++++----- .../extension/store/[identifier]/+page.svelte | 43 +++++------- .../app/extension/store/[identifier]/+page.ts | 62 +++++++++-------- .../extension/store/[identifier]/helper.ts | 16 +++-- packages/api/src/models/server.ts | 35 +++++++++- packages/extension/src/install.ts | 6 +- .../scripts/upload-schema-to-supabase.ts | 3 +- packages/tauri-plugins/jarvis/setup.ts | 4 +- .../components/extension/ExtListItem.svelte | 5 +- .../extension/StoreExtDetail.svelte | 20 ++++-- 13 files changed, 197 insertions(+), 134 deletions(-) create mode 100644 apps/desktop/dev.ts diff --git a/apps/desktop/dev.ts b/apps/desktop/dev.ts new file mode 100644 index 0000000..a45386b --- /dev/null +++ b/apps/desktop/dev.ts @@ -0,0 +1,8 @@ +import { getExtensionsLatestPublishByIdentifier } from "@kksh/sdk" + +const latestPublish = await getExtensionsLatestPublishByIdentifier({ + path: { + identifier: "RAG1" + } +}) +console.log(latestPublish) diff --git a/apps/desktop/src/lib/utils/updater.ts b/apps/desktop/src/lib/utils/updater.ts index 17705b0..d6b503d 100644 --- a/apps/desktop/src/lib/utils/updater.ts +++ b/apps/desktop/src/lib/utils/updater.ts @@ -1,8 +1,7 @@ import { extensions } from "@/stores" -import { supabaseAPI } from "@/supabase" import { isCompatible } from "@kksh/api" import type { ExtPackageJsonExtra } from "@kksh/api/models" -import { greaterThan } from "@std/semver" +import { getExtensionsLatestPublishByIdentifier } from "@kksh/sdk" import { relaunch } from "@tauri-apps/plugin-process" import { check } from "@tauri-apps/plugin-updater" import { gt } from "semver" @@ -32,11 +31,22 @@ export async function checkSingleExtensionUpdate( installedExt: ExtPackageJsonExtra, autoupgrade: boolean ) { - const { data: sbExt, error } = await supabaseAPI.getLatestExtPublish( - installedExt.kunkun.identifier - ) + const { + data: sbExt, + error, + response + } = await getExtensionsLatestPublishByIdentifier({ + path: { + identifier: "RAG" + } + }) + // const { data: sbExt, error } = await supabaseAPI.getLatestExtPublish( + // installedExt.kunkun.identifier + // ) if (error) { - return toast.error(`Failed to check update for ${installedExt.kunkun.identifier}: ${error}`) + return toast.error( + `Failed to check update for ${installedExt.kunkun.identifier}: ${error} (${response.status})` + ) } if (!sbExt) { @@ -49,10 +59,7 @@ export async function checkSingleExtensionUpdate( ) { if (autoupgrade) { await extensions - .upgradeStoreExtension( - sbExt.identifier, - supabaseAPI.translateExtensionFilePathToUrl(sbExt.tarball_path) - ) + .upgradeStoreExtension(sbExt.identifier, sbExt.tarball_path) .then(() => { toast.success(`${sbExt.name} upgraded`, { description: `From ${installedExt.version} to ${sbExt.version}` diff --git a/apps/desktop/src/routes/app/extension/store/+page.svelte b/apps/desktop/src/routes/app/extension/store/+page.svelte index 115d426..4cd0124 100644 --- a/apps/desktop/src/routes/app/extension/store/+page.svelte +++ b/apps/desktop/src/routes/app/extension/store/+page.svelte @@ -2,14 +2,13 @@ import { getExtensionsFolder } from "@/constants" import { appState, extensions } from "@/stores" import { keys } from "@/stores/keys" - import { supabaseAPI } from "@/supabase" - import { goBackOnEscapeClearSearchTerm, goHomeOnEscapeClearSearchTerm } from "@/utils/key" import { goBack, goHome } from "@/utils/route" - import { Action as ActionSchema } from "@kksh/api/models" + import { Action as ActionSchema, ExtensionStoreListItem, ExtPublish } from "@kksh/api/models" import { Action } from "@kksh/api/ui" - import { SBExt } from "@kksh/supabase/models" - import type { ExtPublishMetadata } from "@kksh/supabase/models" - import { type Tables } from "@kksh/supabase/types" + import { + getExtensionsLatestPublishByIdentifier, + postExtensionsIncrementDownloads + } from "@kksh/sdk" import { Button, Command } from "@kksh/svelte5" import { Constants } from "@kksh/ui" import { ExtListItem } from "@kksh/ui/extension" @@ -71,51 +70,57 @@ } }) - function onExtItemSelected(ext: SBExt) { + function onExtItemSelected(ext: ExtensionStoreListItem) { goto(`./store/${ext.identifier}`) } - async function onExtItemUpgrade(ext: SBExt) { - const res = await supabaseAPI.getLatestExtPublish(ext.identifier) - if (res.error) + async function onExtItemUpgrade(ext: ExtensionStoreListItem) { + const { data, error, response } = await getExtensionsLatestPublishByIdentifier({ + path: { + identifier: ext.identifier + } + }) + if (error) return toast.error("Fail to get latest extension", { - description: res.error.message + description: error as string }) - const tarballUrl = res.data.tarball_path.startsWith("http") - ? res.data.tarball_path - : supabaseAPI.translateExtensionFilePathToUrl(res.data.tarball_path) - const installExtras = await getInstallExtras( - res.data as Tables<"ext_publish"> & { metadata: ExtPublishMetadata } - ) + const installExtras = await getInstallExtras(data?.metadata) return extensions - .upgradeStoreExtension(ext.identifier, tarballUrl, installExtras) + .upgradeStoreExtension(ext.identifier, data.tarball_path, installExtras) .then((newExt) => { toast.success(`${ext.name} Upgraded to ${newExt.version}`) }) } - async function onExtItemInstall(ext: SBExt) { - const res = await supabaseAPI.getLatestExtPublish(ext.identifier) - if (res.error) + async function onExtItemInstall(ext: ExtensionStoreListItem) { + const { data, error, response } = await getExtensionsLatestPublishByIdentifier({ + path: { + identifier: ext.identifier + } + }) + if (error) return toast.error("Fail to get latest extension", { - description: res.error.message + description: error }) - const tarballUrl = res.data.tarball_path.startsWith("http") - ? res.data.tarball_path - : supabaseAPI.translateExtensionFilePathToUrl(res.data.tarball_path) - const installExtras = await getInstallExtras( - res.data as Tables<"ext_publish"> & { metadata: ExtPublishMetadata } - ) + const installExtras = await getInstallExtras(data?.metadata) const installDir = await getExtensionsFolder() return extensions - .installFromTarballUrl(tarballUrl, installDir, installExtras) + .installFromTarballUrl(data.tarball_path, installDir, installExtras) .then(() => toast.success(`Plugin ${ext.name} Installed`)) .then(() => - supabaseAPI.incrementDownloads({ - identifier: ext.identifier, - version: ext.version + postExtensionsIncrementDownloads({ + body: { + identifier: ext.identifier, + version: ext.version + } }) + .then(({ error }) => { + if (error) { + console.error(error) + } + }) + .catch(console.error) ) } diff --git a/apps/desktop/src/routes/app/extension/store/+page.ts b/apps/desktop/src/routes/app/extension/store/+page.ts index 7a8e681..86eb7ce 100644 --- a/apps/desktop/src/routes/app/extension/store/+page.ts +++ b/apps/desktop/src/routes/app/extension/store/+page.ts @@ -1,43 +1,40 @@ import { appConfig, appState, extensions, installedStoreExts } from "@/stores" -import { supabaseAPI } from "@/supabase" -import type { ExtPackageJsonExtra } from "@kksh/api/models" +import { goHome } from "@/utils/route" +// import { supabaseAPI } from "@/supabase" +import type { ExtensionStoreListItem, ExtPackageJsonExtra } from "@kksh/api/models" import { isExtPathInDev, isUpgradable } from "@kksh/extension" -import { SBExt } from "@kksh/supabase/models" -import { sleep } from "@kksh/utils" -import { error } from "@sveltejs/kit" +import { getExtensionsStoreList } from "@kksh/sdk" +import { toast } from "svelte-sonner" import { derived, get, type Readable } from "svelte/store" import type { PageLoad } from "./$types" export const load: PageLoad = (): Promise<{ - storeExtList: SBExt[] + storeExtList: ExtensionStoreListItem[] installedStoreExts: Readable installedExtsMap: Readable> upgradableExpsMap: Readable> }> => { appState.setFullScreenLoading(true) - return supabaseAPI - .getExtList() - .then(async (storeExtList) => { - // map identifier to extItem + return getExtensionsStoreList() + .then(({ data: storeExtList, error, response }) => { + storeExtList = storeExtList ?? [] + if (error) { + toast.error(`Failed to load extension store: ${error} (${response.status})`) + goHome() + return + } const storeExtsMap = Object.fromEntries(storeExtList.map((ext) => [ext.identifier, ext])) - // const _appConfig = get(appConfig) - // const installedStoreExts = derived(extensions, ($extensions) => { - // if (!_appConfig.extensionPath) return [] - // return $extensions.filter((ext) => !isExtPathInDev(_appConfig.extensionPath!, ext.extPath)) - // }) - // map installed extension identifier to version const installedExtsMap = derived(installedStoreExts, ($exts) => Object.fromEntries($exts.map((ext) => [ext.kunkun.identifier, ext.version])) ) const upgradableExpsMap = derived(installedStoreExts, ($exts) => Object.fromEntries( $exts.map((ext) => { - const dbExt: SBExt | undefined = storeExtsMap[ext.kunkun.identifier] + const dbExt: ExtensionStoreListItem | undefined = storeExtsMap[ext.kunkun.identifier] return [ext.kunkun.identifier, dbExt ? isUpgradable(dbExt, ext.version) : false] }) ) ) - return { storeExtList, installedStoreExts, diff --git a/apps/desktop/src/routes/app/extension/store/[identifier]/+page.svelte b/apps/desktop/src/routes/app/extension/store/[identifier]/+page.svelte index 9a6309d..12d8462 100644 --- a/apps/desktop/src/routes/app/extension/store/[identifier]/+page.svelte +++ b/apps/desktop/src/routes/app/extension/store/[identifier]/+page.svelte @@ -2,11 +2,8 @@ import { getExtensionsFolder } from "@/constants.js" import { i18n } from "@/i18n.js" import { extensions, installedStoreExts } from "@/stores/extensions.js" - import { supabaseAPI } from "@/supabase" - import { goBack } from "@/utils/route.js" - import { ExtPackageJson } from "@kksh/api/models" - import { ExtPublishMetadata } from "@kksh/supabase/models" - import type { Tables } from "@kksh/supabase/types" + import { ExtensionStoreListItem, ExtPackageJson, ExtPublish } from "@kksh/api/models" + import { postExtensionsIncrementDownloads } from "@kksh/sdk" import { Button } from "@kksh/svelte5" import { cn } from "@kksh/svelte5/utils" import { Constants } from "@kksh/ui" @@ -22,10 +19,8 @@ import { getInstallExtras } from "./helper" const { data } = $props() - const extPublish: Tables<"ext_publish"> & { metadata: ExtPublishMetadata } = $derived( - data.extPublish - ) - const ext: Tables<"extensions"> = $derived(data.ext) + const extPublish: ExtPublish = $derived(data.extPublish) + const ext: ExtensionStoreListItem = $derived(data.ext) const manifest = $derived(data.manifest) const installedExt = storeDerived(installedStoreExts, ($e) => { return $e.find((e) => e.kunkun.identifier === extPublish.identifier) @@ -77,28 +72,29 @@ }, 500) }) - const demoImages = $derived( - extPublish.demo_images.map((src) => - src.startsWith("http") ? src : supabaseAPI.translateExtensionFilePathToUrl(src) - ) - ) + const demoImages = $derived(extPublish.demo_images) async function onInstallSelected() { loading.install = true - const tarballUrl = extPublish.tarball_path.startsWith("http") - ? extPublish.tarball_path - : supabaseAPI.translateExtensionFilePathToUrl(extPublish.tarball_path) - const installExtras = await getInstallExtras(extPublish) + const installExtras = await getInstallExtras(extPublish.metadata) const installDir = await getExtensionsFolder() return extensions - .installFromTarballUrl(tarballUrl, installDir, installExtras) + .installFromTarballUrl(extPublish.tarball_path, installDir, installExtras) .then(() => toast.success(`Plugin ${extPublish.name} Installed`)) .then((loadedExt) => { info(`Successfully installed ${extPublish.name}`) - supabaseAPI.incrementDownloads({ - identifier: extPublish.identifier, - version: extPublish.version + postExtensionsIncrementDownloads({ + body: { + identifier: extPublish.identifier, + version: extPublish.version + } }) + .then(({ error }) => { + if (error) { + console.error(error) + } + }) + .catch(console.error) showBtn.install = false showBtn.uninstall = true }) @@ -113,9 +109,8 @@ function onUpgradeSelected() { loading.upgrade = true - const tarballUrl = supabaseAPI.translateExtensionFilePathToUrl(extPublish.tarball_path) return extensions - .upgradeStoreExtension(extPublish.identifier, tarballUrl) + .upgradeStoreExtension(extPublish.identifier, extPublish.tarball_path) .then((newExt) => { toast.success( `${extPublish.name} Upgraded from ${$installedExt?.version} to ${newExt.version}` diff --git a/apps/desktop/src/routes/app/extension/store/[identifier]/+page.ts b/apps/desktop/src/routes/app/extension/store/[identifier]/+page.ts index 9994a21..7642331 100644 --- a/apps/desktop/src/routes/app/extension/store/[identifier]/+page.ts +++ b/apps/desktop/src/routes/app/extension/store/[identifier]/+page.ts @@ -1,9 +1,17 @@ import { appState, extensions } from "@/stores" -import { supabaseAPI } from "@/supabase" -import { KunkunExtManifest, type ExtPackageJsonExtra } from "@kksh/api/models" -import { ExtPublishMetadata } from "@kksh/supabase/models" -import type { Tables } from "@kksh/supabase/types" -import { sleep } from "@kksh/utils" +import { + ExtensionStoreListItem, + ExtPublish, + KunkunExtManifest, + type ExtPackageJsonExtra +} from "@kksh/api/models" +import { + getExtensionsByIdentifier, + getExtensionsLatestPublishByIdentifier, + type GetExtensionsByIdentifierResponse, + type GetExtensionsLatestPublishByIdentifierResponse, + type GetExtensionsLatestPublishByIdentifierResponses +} from "@kksh/sdk" import { error } from "@sveltejs/kit" import { toast } from "svelte-sonner" import * as v from "valibot" @@ -12,43 +20,43 @@ import type { PageLoad } from "./$types" export const load: PageLoad = ({ params }): Promise<{ - extPublish: Tables<"ext_publish"> & { metadata: ExtPublishMetadata } - ext: Tables<"extensions"> - manifest: KunkunExtManifest + // extPublish: GetExtensionsLatestPublishByIdentifierResponses['200'] + ext: GetExtensionsByIdentifierResponse + manifest: GetExtensionsLatestPublishByIdentifierResponse["manifest"] params: { identifier: string } }> => { appState.setFullScreenLoading(true) - return supabaseAPI - .getLatestExtPublish(params.identifier) - .then(async ({ error: dbError, data: extPublish }) => { - const metadataParse = v.safeParse(ExtPublishMetadata, extPublish?.metadata ?? {}) - if (dbError) { + return getExtensionsLatestPublishByIdentifier({ + path: { + identifier: params.identifier + } + }) + .then(async ({ data: extPublish, error: err, response }) => { + if (err || !extPublish) { + console.error(err) return error(400, { - message: dbError.message + message: "Failed to get extension publish" }) } - const metadata = metadataParse.success ? metadataParse.output : {} - const parseManifest = v.safeParse(KunkunExtManifest, extPublish.manifest) - if (!parseManifest.success) { - const errMsg = "Invalid extension manifest, you may need to upgrade your app." - toast.error(errMsg) - throw error(400, errMsg) - } - - const { data: ext, error: extError } = await supabaseAPI.getExtension(params.identifier) + const { data: ext, error: extError } = await getExtensionsByIdentifier({ + path: { + identifier: params.identifier + } + }) if (extError) { + console.error(extError) return error(400, { - message: extError.message + message: "Failed to get extension" }) } return { - extPublish: { ...extPublish, metadata }, + // extPublish, ext, - params, - manifest: parseManifest.output + manifest: extPublish.manifest, + params } }) .finally(() => { diff --git a/apps/desktop/src/routes/app/extension/store/[identifier]/helper.ts b/apps/desktop/src/routes/app/extension/store/[identifier]/helper.ts index 7ac604a..03f6628 100644 --- a/apps/desktop/src/routes/app/extension/store/[identifier]/helper.ts +++ b/apps/desktop/src/routes/app/extension/store/[identifier]/helper.ts @@ -1,15 +1,17 @@ -import type { ExtPublishMetadata } from "@kksh/supabase/models" -import type { Tables } from "@kksh/supabase/types" +import type { ExtPublishMetadata } from "@kunkunapi/src/models" export async function getInstallExtras( - ext: Tables<"ext_publish"> & { metadata?: ExtPublishMetadata } + extMetadata?: { + sourceType?: string + source?: string + } ): Promise<{ overwritePackageJson?: string }> { const extras: { overwritePackageJson?: string } = {} - if (ext.metadata?.sourceType) { - if (ext.metadata?.sourceType === "jsr") { - if (ext.metadata?.source) { + if (extMetadata?.sourceType) { + if (extMetadata?.sourceType === "jsr") { + if (extMetadata?.source) { try { - const res = await fetch(`${ext.metadata.source}/package.json`) + const res = await fetch(`${extMetadata.source}/package.json`) const pkgJsonContent = await res.text() extras.overwritePackageJson = pkgJsonContent } catch (error) { diff --git a/packages/api/src/models/server.ts b/packages/api/src/models/server.ts index 13d5e91..d945bb6 100644 --- a/packages/api/src/models/server.ts +++ b/packages/api/src/models/server.ts @@ -1,5 +1,6 @@ import * as v from "valibot" import { BaseIcon } from "./icon" +import { ExtPackageJson, KunkunExtManifest } from "./manifest" export enum ExtPublishSourceTypeEnum { jsr = "jsr", @@ -26,13 +27,14 @@ export const ExtPublishMetadata = v.object({ export type ExtPublishMetadata = v.InferOutput /*** - * Correspond to `extensions` table in supabase + * Correspond to `extensions` table in supabase, missing a few fields */ export const ExtensionStoreListItem = v.object({ identifier: v.string(), name: v.string(), created_at: v.string(), downloads: v.number(), + author_id: v.string(), short_description: v.string(), long_description: v.string(), version: v.string(), @@ -41,3 +43,34 @@ export const ExtensionStoreListItem = v.object({ }) export type ExtensionStoreListItem = v.InferOutput + +export enum PublishStateEnum { + "public", + "pending", + "under_review", + "private" +} +export const ExtensionPublishState = v.enum(PublishStateEnum) + +export const ExtPublish = v.object({ + name: v.string(), + tarball_path: v.string(), + created_at: v.date(), + version: v.string(), + manifest: KunkunExtManifest, + shasum: v.string(), + tarball_size: v.number(), + unpacked_size: v.nullable(v.number()), + cmd_count: v.number(), + identifier: v.string(), + downloads: v.number(), + demo_images: v.array(v.string()), + api_version: v.nullable(v.string()), + extension_state: ExtensionPublishState, + package_json: ExtPackageJson, + metadata: ExtPublishMetadata, + readme: v.nullable(v.string()) +}) +export type ExtPublish = v.InferOutput + +export const DBExtension = v.object({}) diff --git a/packages/extension/src/install.ts b/packages/extension/src/install.ts index 0b2197f..29f5592 100644 --- a/packages/extension/src/install.ts +++ b/packages/extension/src/install.ts @@ -4,8 +4,8 @@ */ import { isCompatible } from "@kksh/api" import { copy_dir_all, db, decompressTarball } from "@kksh/api/commands" -import type { ExtPackageJsonExtra } from "@kksh/api/models" -import { SBExt } from "@kksh/supabase/models" +import type { ExtensionStoreListItem, ExtPackageJsonExtra } from "@kksh/api/models" +// import { SBExt } from "@kksh/supabase/models" import { greaterThan, parse as parseSemver } from "@std/semver" import * as path from "@tauri-apps/api/path" import * as dialog from "@tauri-apps/plugin-dialog" @@ -193,7 +193,7 @@ export async function uninstallExtensionByPath(extPath: string) { return fs.remove(extPath, { recursive: true }).then(() => db.deleteExtensionByPath(extPath)) } -export function isUpgradable(dbExt: SBExt, installedExtVersion: string) { +export function isUpgradable(dbExt: ExtensionStoreListItem, installedExtVersion: string) { const upgradable = greaterThan(parseSemver(dbExt.version), parseSemver(installedExtVersion)) && dbExt.api_version ? isCompatible(dbExt.api_version) diff --git a/packages/schema/scripts/upload-schema-to-supabase.ts b/packages/schema/scripts/upload-schema-to-supabase.ts index 09b56d8..7196dc6 100644 --- a/packages/schema/scripts/upload-schema-to-supabase.ts +++ b/packages/schema/scripts/upload-schema-to-supabase.ts @@ -1,11 +1,10 @@ import { ExtPackageJson } from "@kksh/api/models" -import { type Database } from "@kksh/supabase/types" import { createClient } from "@supabase/supabase-js" import { parse, string } from "valibot" import * as v from "valibot" import { getJsonSchema } from "../src" -const supabase = createClient( +const supabase = createClient( parse(string(), process.env.SUPABASE_URL), parse(string(), process.env.SUPABASE_SERVICE_ROLE_KEY) ) diff --git a/packages/tauri-plugins/jarvis/setup.ts b/packages/tauri-plugins/jarvis/setup.ts index b91d3f9..42e8903 100644 --- a/packages/tauri-plugins/jarvis/setup.ts +++ b/packages/tauri-plugins/jarvis/setup.ts @@ -1,12 +1,12 @@ import { writeFileSync } from "fs" -import { type Database } from "@kksh/supabase/types" +// import { type Database } from "@kksh/supabase/types" import { createClient } from "@supabase/supabase-js" if (!process.env.SUPABASE_URL || !process.env.SUPABASE_ANON_KEY) { throw new Error("SUPABASE_URL and SUPABASE_ANON_KEY must be set") } -const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY) +const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY) const { data, error } = await supabase.storage.from("pub").download("server_public_key.pem") if (error) { diff --git a/packages/ui/src/components/extension/ExtListItem.svelte b/packages/ui/src/components/extension/ExtListItem.svelte index 20387c0..e1673de 100644 --- a/packages/ui/src/components/extension/ExtListItem.svelte +++ b/packages/ui/src/components/extension/ExtListItem.svelte @@ -1,7 +1,6 @@