//native
import * as wmill from "windmill-client"
export type DynSelect_operation = string
// Every operation of the instance's own OpenAPI document, so the list always matches its version.
async function listOperations() {
const response = await fetch(`${wmill.OpenAPI.BASE}/openapi.json`)
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const spec = (await response.json()) as {
paths: { [path: string]: { [method: string]: { operationId?: string } } }
}
return Object.entries(spec.paths).flatMap(([path, methods]) =>
Object.entries(methods)
.filter(([, op]) => op?.operationId)
.map(([method, op]) => ({
id: op.operationId!,
value: `${method.toUpperCase()} ${path}`,
}))
)
}
export async function operation() {
return (await listOperations())
.map((op) => ({ value: op.value, label: `${op.id}: ${op.value}` }))
.sort((a, b) => a.label.localeCompare(b.label))
}
/**
* Call Windmill API
* Call any operation of this instance's own API, picked from its OpenAPI document. Runs with the job's token, which only reaches the job's workspace; pass a user API token to call instance-level operations or another workspace.
*/
export async function main(
operation: DynSelect_operation,
path_params: { [key: string]: any } | undefined,
query: { [key: string]: any } | undefined,
body: { [key: string]: any } | undefined,
token: string | undefined
) {
// `operation` is "METHOD /path" (what the dropdown stores) or a bare operationId
const resolved = operation.includes(" ")
? operation
: (await listOperations()).find((op) => op.id === operation)?.value
if (!resolved) {
throw new Error(`Unknown operation ${operation}`)
}
const [method, path] = resolved.split(" ")
const params: { [key: string]: any } = {
workspace: wmill.getWorkspace(),
...path_params,
}
const url = new URL(
wmill.OpenAPI.BASE +
path.replace(/\{(\w+)\}/g, (_, name) => {
if (params[name] == null || params[name] === "") {
throw new Error(`Missing path parameter ${name} for ${resolved}`)
}
return encodeURI(String(params[name]))
})
)
for (const [name, value] of Object.entries(query ?? {})) {
if (value != null && value !== "") {
url.searchParams.append(name, String(value))
}
}
const hasBody = body != null && method !== "GET"
const response = await fetch(url, {
method,
headers: {
// the job's own token only reaches its workspace: pass an API token for anything else
Authorization: `Bearer ${token || wmill.OpenAPI.TOKEN}`,
...(hasBody ? { "Content-Type": "application/json" } : {}),
},
body: hasBody ? JSON.stringify(body) : undefined,
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const text = await response.text()
return response.headers.get("Content-Type")?.includes("json")
? JSON.parse(text)
: text
}
Submitted by hugo989 5 hours ago