mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-05-24 21:55:04 +00:00

* chore: add vendor submodules * feat: add packages for db,ci,schema,api,jarvis cmds * feat: add tauri-jarvis-plugin * feat: implement extension commands list * fix(desktop): import path errors after packages refactor * chore: add self signed cert * fix: prevent prerender for desktop * fix(desktop): desktop sveltekit static build, use csr for dynamic route * feat: add error handling page and components * refactor: component lib * refactor: move more types, functions and components out of desktop * refactor(ui): more refactor * refactor(ui): move store components to @kksh/ui * ci: add CI for build & test * refactor: rename @kksh/extensions to @kksh/extension * ci: add 2 more ci * ci: fix * fix: CI env var * chore: add changeset * feat: implement extension store item detail view * feat: implement extension store install, uninstall, upgrade * format * revert: upgradable logic, the new one doesn't work yet * refactor: make @kksh/ui dependent only on @kksh/api Reason: @kksh/ui may be published later for building website, all its dependency packages must be also published. To avoid trouble it should be standalone, depend only on packages already published * refactor: cleanup * fixed: some typescript error * chore: got typedoc working on @kksh/api * ci: disable manifest schema upload CI on push
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { SBExt } from "@kksh/api/supabase"
|
|
import type { Database, Tables } from "@kksh/api/supabase/types"
|
|
import type { PostgrestSingleResponse, SupabaseClient } from "@supabase/supabase-js"
|
|
import * as v from "valibot"
|
|
|
|
export class SupabaseAPI {
|
|
constructor(private supabase: SupabaseClient<Database>) {}
|
|
async getExtList(): Promise<SBExt[]> {
|
|
const res = await this.supabase
|
|
.from("extensions")
|
|
.select(
|
|
"identifier, version, api_version, name, downloads, short_description, long_description, icon, created_at"
|
|
)
|
|
.order("downloads", { ascending: false })
|
|
.select()
|
|
const dbExts: Tables<"extensions">[] = res.data ?? []
|
|
return dbExts
|
|
.map((x) => {
|
|
const parsedNode = v.safeParse(SBExt, x)
|
|
if (!parsedNode.success) {
|
|
console.error(`Fail to parse extension`, x)
|
|
console.warn(parsedNode.issues)
|
|
console.error(v.flatten(parsedNode.issues))
|
|
}
|
|
return parsedNode.success ? v.parse(SBExt, parsedNode.output) : null
|
|
})
|
|
.filter((x) => x !== null)
|
|
}
|
|
|
|
async getLatestExtPublish(
|
|
identifier: string
|
|
): Promise<PostgrestSingleResponse<Tables<"ext_publish">>> {
|
|
return this.supabase
|
|
.from("ext_publish")
|
|
.select(
|
|
"created_at, name, version, manifest, shasum, size, tarball_path, cmd_count, identifier, downloads, demo_images, api_version"
|
|
)
|
|
.order("created_at", { ascending: false })
|
|
.eq("identifier", identifier)
|
|
.select()
|
|
.limit(1)
|
|
.single()
|
|
}
|
|
|
|
async incrementDownloads({
|
|
identifier,
|
|
version
|
|
}: {
|
|
identifier: string
|
|
version: string
|
|
}): Promise<{ downloads: number }> {
|
|
return this.supabase.functions
|
|
.invoke("increment-downloads", {
|
|
body: { identifier, version }
|
|
})
|
|
.then(({ data, error }) => {
|
|
if (error) {
|
|
throw error
|
|
}
|
|
const parsed = v.safeParse(
|
|
v.object({
|
|
downloads: v.number()
|
|
}),
|
|
data
|
|
)
|
|
if (!parsed.success) {
|
|
throw new Error("Fail to parse increment downloads response")
|
|
}
|
|
return parsed.output
|
|
})
|
|
}
|
|
|
|
translateExtensionFilePathToUrl(tarballPath: string): string {
|
|
return this.supabase.storage.from("extensions").getPublicUrl(tarballPath).data.publicUrl
|
|
}
|
|
}
|