import { planetscaleRequest } from './client.ts'
import { PLANETSCALE_API_BASE_URL } from './setup.ts'
import type { JsonRecord, PlanetscaleAuthInput } from './types.ts'
import { optionalBoolean, optionalString, optionalStringArray, requireRecord, requireString } from './types.ts'
export type CreateWebhookInput = PlanetscaleAuthInput & {
organization: string
database: string
url: string
events?: Array<string>
enabled?: boolean
dryRun?: boolean
confirm?: boolean
}
/**
* Create a PlanetScale database webhook (default event: branch.anomaly).
* Preview with dryRun. Live create requires confirm: true and write_database.
* @example
* import createWebhook from 'kody:@kody/planetscale/create-webhook'
* await createWebhook({
* organization: 'acme',
* database: 'app',
* url: 'https://example.kody.run/webhooks/insights',
* dryRun: true,
* })
*/
export async function createWebhook(input: CreateWebhookInput) {
const organization = requireString(input.organization, 'organization')
const database = requireString(input.database, 'database')
const url = requireString(input.url, 'url')
const events = input.events?.length ? input.events : ['branch.anomaly']
const path = `/organizations/${encodeURIComponent(organization)}/databases/${encodeURIComponent(database)}/webhooks`
const body: JsonRecord = {
url,
events,
enabled: input.enabled ?? true,
}
if (input.dryRun) {
return {
dryRun: true,
wouldCall: {
method: 'POST',
url: `${PLANETSCALE_API_BASE_URL}${path}`,
body,
},
}
}
if (input.confirm !== true) {
throw new Error(
'Creating a PlanetScale webhook may mutate data. Pass confirm: true only after explicit user approval, or use dryRun: true.',
)
}
return planetscaleRequest({
...input,
operation: 'webhooks.write',
method: 'POST',
path,
body,
})
}
/**
* Create a PlanetScale database webhook (default event: branch.anomaly).
* @example
* import createWebhook from 'kody:@kody/planetscale/create-webhook'
* await createWebhook({ organization: 'acme', database: 'app', url: 'https://example', dryRun: true })
*/
export default async function createWebhookEntrypoint(
params: Partial<CreateWebhookInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'create-webhook')
return createWebhook({
organization: requireString(input.organization, 'organization'),
database: requireString(input.database, 'database'),
url: requireString(input.url, 'url'),
events: optionalStringArray(input.events, 'events'),
enabled: optionalBoolean(input.enabled, 'enabled'),
account: optionalString(input.account, 'account'),
secretName: optionalString(input.secretName, 'secretName'),
dryRun: optionalBoolean(input.dryRun, 'dryRun'),
confirm: optionalBoolean(input.confirm, 'confirm'),
})
}