(pluginId: string)
| 189 | } |
| 190 | |
| 191 | async function loadPlugin(pluginId: string): Promise<LoadResult | null> { |
| 192 | const supabase = await createClient(); |
| 193 | |
| 194 | const { data, error } = await supabase |
| 195 | .from("plugins") |
| 196 | .select( |
| 197 | "id, name, slug, description, repository, homepage, keywords, active, permanently_blocked, plugin_components(type, name, slug, description, content, metadata)", |
| 198 | ) |
| 199 | .eq("id", pluginId) |
| 200 | .single(); |
| 201 | |
| 202 | if (error || !data) return null; |
| 203 | |
| 204 | const components = ((data.plugin_components ?? []) as ComponentRow[]).map( |
| 205 | (c) => ({ |
| 206 | type: c.type, |
| 207 | name: c.name, |
| 208 | slug: c.slug, |
| 209 | description: c.description, |
| 210 | content: c.content, |
| 211 | metadata: (c.metadata ?? {}) as Record<string, unknown>, |
| 212 | }), |
| 213 | ); |
| 214 | |
| 215 | return { |
| 216 | prevActive: data.active === true, |
| 217 | permanentlyBlocked: data.permanently_blocked === true, |
| 218 | plugin: { |
| 219 | id: data.id, |
| 220 | name: data.name, |
| 221 | slug: data.slug, |
| 222 | description: data.description, |
| 223 | repository: data.repository, |
| 224 | homepage: data.homepage, |
| 225 | keywords: data.keywords ?? [], |
| 226 | components, |
| 227 | }, |
| 228 | }; |
| 229 | } |
| 230 | |
| 231 | async function markScanning(pluginId: string) { |
| 232 | const supabase = await createClient(); |
no test coverage detected