mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-04-20 05:29:17 +00:00

* feat: add required license field to manifest * chore: add license MIT to all templates * feat: add license check to jsr and npm validation * fix: supabase export split every item into its own subexport for better debugability * fix: supabase imports * feat: hide app when escape is pressed * fix: update package version in api test from 0.0.6 to 0.0.20 * fix: update test for kunkun extension with new version and commit details * fix: update kunkun extension test to use version 0.0.4 * fix: update kunkun extension test to reflect new version 0.0.20 and updated commit details * feat: display downloads in extension details * feat: add downloads display to store
108 lines
2.7 KiB
TypeScript
108 lines
2.7 KiB
TypeScript
import type { PostgrestSingleResponse, SupabaseClient } from "@supabase/supabase-js"
|
|
import * as v from "valibot"
|
|
import type { Database, Tables } from "./database.types"
|
|
import { SBExt } from "./models"
|
|
|
|
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, metadata"
|
|
)
|
|
.order("created_at", { ascending: false })
|
|
.eq("identifier", identifier)
|
|
.select()
|
|
.limit(1)
|
|
.single()
|
|
}
|
|
|
|
getExtension(identifier: string) {
|
|
return this.supabase
|
|
.from("extensions")
|
|
.select("*")
|
|
.eq("identifier", identifier)
|
|
.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
|
|
})
|
|
}
|
|
|
|
async publishExtFromJSR(payload: {
|
|
scope: string
|
|
version: string
|
|
name: string
|
|
}): Promise<void> {
|
|
return this.supabase.functions
|
|
.invoke("publish-jsr-ext", {
|
|
body: payload
|
|
})
|
|
.then(async ({ data, error }) => {
|
|
if (data && data.isValid) {
|
|
return
|
|
}
|
|
if (error?.name === "FunctionsHttpError") {
|
|
const errorMessage = await error.context.json()
|
|
throw new Error(errorMessage.error)
|
|
} else {
|
|
throw new Error(`Unknown error: ${error?.message}`)
|
|
}
|
|
})
|
|
}
|
|
|
|
translateExtensionFilePathToUrl(tarballPath: string): string {
|
|
return this.supabase.storage.from("extensions").getPublicUrl(tarballPath).data.publicUrl
|
|
}
|
|
}
|