← Public packages
@kentcdodds/raycast
Raycast launcher: stored execute commands via webhooks (canonical; do not use raycast-shortcuts).
src/invoke.ts
68 lines · 2.2 KB · TypeScriptimport getPackage from './get-package.ts'
export type InvokeInput = {
kodyId?: string
packageId?: string
exportName: string
params?: Record<string, unknown>
/**
* Deprecated: packages.invoke sunset (#1750 / codemod 0008). Exactly-once
* is not available on this lean path — use a workflow. The key is ignored.
*/
idempotencyKey?: string
/** Deprecated: ignored after packages.invoke sunset. */
topic?: string
}
/**
* Invoke one of the caller's saved package exports from an external client.
*
* HTTP callers authenticate against this `raycast` package, then pass the
* target `kodyId` (or `packageId`) and `exportName` here. The target loads via
* computed `import(specifier)` (name is data).
*
* @param params.kodyId - Target package kody.id (preferred).
* @param params.packageId - Target saved package id when kodyId is omitted.
* @param params.exportName - Export to run (`./post-message`, `post-message`, or `.`).
* @param params.params - JSON object passed to the target export.
* @returns The target export's unwrapped return value.
*
* @example
* import invoke from 'kody:@kentcdodds/raycast/invoke'
* const result = await invoke({
* kodyId: 'discord',
* exportName: './post-message',
* params: { content: 'hello' },
* })
*/
export default async function invoke(input: InvokeInput) {
const exportName = input.exportName?.trim()
if (!exportName) {
throw new Error('exportName is required.')
}
// idempotencyKey / topic intentionally ignored (no packages.invoke; no workflow).
void input.idempotencyKey
void input.topic
const target = await getPackage({
kodyId: input.kodyId,
packageId: input.packageId,
})
const matched = target.exports.find((entry) => {
return (
entry.subpath === exportName ||
entry.exportName === exportName.replace(/^\.\//, '') ||
(exportName === '.' && entry.subpath === '.')
)
})
if (!matched) {
throw new Error(`Package ${target.name} does not export ${exportName}.`)
}
const raw = matched.importSpecifier
const trimmed = typeof raw === 'string' ? raw.trim() : ''
const specifier =
typeof raw === 'string' && trimmed.startsWith('@')
? `kody:${trimmed}`
: trimmed
const mod = await import(specifier)
return await mod.default(input.params)
}