102 lines
3.3 KiB
TypeScript
102 lines
3.3 KiB
TypeScript
import { atom, map } from 'nanostores'
|
|
import { createFetcherStore, createMutatorStore } from './fetcher'
|
|
|
|
export interface Plugin {
|
|
id: string
|
|
name: string
|
|
language: 'typescript' | 'go'
|
|
source: string
|
|
hooks: string[]
|
|
enabled: boolean
|
|
wasm?: string
|
|
wasm_size?: number
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface CompileResult {
|
|
success: boolean
|
|
wasm?: string
|
|
size?: number
|
|
errors?: string[]
|
|
time_ms?: number
|
|
}
|
|
|
|
export const $plugins = createFetcherStore<Plugin[]>(['/api/studio/plugins'])
|
|
|
|
export const $currentPlugin = map<Partial<Plugin>>({
|
|
name: '',
|
|
language: 'typescript',
|
|
source: '',
|
|
hooks: [],
|
|
enabled: true,
|
|
})
|
|
|
|
export const $compileResult = atom<CompileResult | null>(null)
|
|
export const $isCompiling = atom(false)
|
|
|
|
export const $savePlugin = createMutatorStore(async ({ data, invalidate }: { data: Plugin; invalidate: (key: string) => void }) => {
|
|
const res = await fetch('/api/studio/plugins', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(data),
|
|
})
|
|
if (!res.ok) throw new Error('Failed to save plugin')
|
|
invalidate('/api/studio/plugins')
|
|
return res.json()
|
|
})
|
|
|
|
export const $deletePlugin = createMutatorStore(async ({ data: id, invalidate }: { data: string; invalidate: (key: string) => void }) => {
|
|
const res = await fetch(`/api/studio/plugins/${id}`, { method: 'DELETE' })
|
|
if (!res.ok) throw new Error('Failed to delete plugin')
|
|
invalidate('/api/studio/plugins')
|
|
})
|
|
|
|
export const $togglePlugin = createMutatorStore(async ({ data, invalidate }: { data: { id: string; enabled: boolean }; invalidate: (key: string) => void }) => {
|
|
const res = await fetch(`/api/studio/plugins/${data.id}/toggle`, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ enabled: data.enabled }),
|
|
})
|
|
if (!res.ok) throw new Error('Failed to toggle plugin')
|
|
invalidate('/api/studio/plugins')
|
|
})
|
|
|
|
export async function compilePlugin(language: string, source: string): Promise<CompileResult> {
|
|
$isCompiling.set(true)
|
|
$compileResult.set(null)
|
|
|
|
try {
|
|
const res = await fetch('/api/studio/plugins/compile', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ language, source }),
|
|
})
|
|
const result = await res.json()
|
|
$compileResult.set(result)
|
|
return result
|
|
} finally {
|
|
$isCompiling.set(false)
|
|
}
|
|
}
|
|
|
|
export async function testPlugin(pluginId: string, hook: string, testData: object): Promise<any> {
|
|
const res = await fetch(`/api/studio/plugins/${pluginId}/test`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ hook, data: testData }),
|
|
})
|
|
return res.json()
|
|
}
|
|
|
|
export const AVAILABLE_HOOKS = [
|
|
{ value: 'post.published', label: 'Post Published', description: 'Triggered when a post is published' },
|
|
{ value: 'post.updated', label: 'Post Updated', description: 'Triggered when a published post is updated' },
|
|
{ value: 'comment.created', label: 'Comment Created', description: 'Triggered when a new comment is posted' },
|
|
{ value: 'subscriber.created', label: 'Subscriber Created', description: 'Triggered when someone subscribes' },
|
|
]
|
|
|
|
export const LANGUAGES = [
|
|
{ value: 'typescript', label: 'TypeScript', extension: '.ts' },
|
|
{ value: 'go', label: 'Go', extension: '.go' },
|
|
]
|