import { asanaRequest } from './client.ts'
import { mapTask, TASK_FIELDS } from './models.ts'
import type {
AsanaAuthInput,
AsanaTaskSummary,
DryRunResult,
JsonRecord,
} from './types.ts'
import {
compactRecord,
optionalBoolean,
optionalString,
requireRecord,
requireString,
} from './types.ts'
import { requireAuthMode } from './auth.ts'
export type UpdateTaskInput = AsanaAuthInput & {
/** Task GID. */
gid: string
name?: string
notes?: string
assignee?: string
dueOn?: string
dueAt?: string
completed?: boolean
confirm?: boolean
dryRun?: boolean
}
function taskUpdatePayload(input: UpdateTaskInput): JsonRecord {
const payload = compactRecord({
name: optionalString(input.name, 'name'),
notes: optionalString(input.notes, 'notes'),
assignee: optionalString(input.assignee, 'assignee'),
due_on: optionalString(input.dueOn, 'dueOn'),
due_at: optionalString(input.dueAt, 'dueAt'),
completed: optionalBoolean(input.completed, 'completed'),
})
if (Object.keys(payload).length === 0) {
throw new Error('update-task requires at least one field to change.')
}
return payload
}
/**
* Update an Asana task. Requires `confirm: true`, or use `dryRun: true`.
* Needs `tasks:write`.
* @example
* import updateTask from 'kody:@kody/asana/update-task'
* const preview = await updateTask({
* gid: '123',
* completed: true,
* dryRun: true,
* })
*/
export async function updateTask(
input: UpdateTaskInput,
): Promise<
AsanaTaskSummary | DryRunResult<{ method: string; path: string; data: JsonRecord }>
> {
const gid = requireString(input.gid, 'gid')
const payload = taskUpdatePayload(input)
const path = `/tasks/${encodeURIComponent(gid)}`
if (input.dryRun) {
return { dryRun: true, wouldCall: { method: 'PUT', path, data: payload } }
}
if (input.confirm !== true) {
throw new Error(
'Updating an Asana task requires confirm: true after explicit user approval, or dryRun: true.',
)
}
const result = await asanaRequest<unknown>({
...input,
operation: 'tasks.write',
method: 'PUT',
path,
query: { opt_fields: TASK_FIELDS },
body: payload,
})
if (!result.data) throw new Error('Asana update task did not return a task.')
return mapTask(result.data)
}
/**
* Update an Asana task. Requires `confirm: true`, or use `dryRun: true`.
* @example
* import updateTask from 'kody:@kody/asana/update-task'
* const preview = await updateTask({ gid: '123', name: 'Renamed', dryRun: true })
*/
export default async function updateTaskEntrypoint(
params: Partial<UpdateTaskInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'update-task')
return updateTask({
gid: requireString(input.gid, 'gid'),
name: optionalString(input.name, 'name'),
notes: optionalString(input.notes, 'notes'),
assignee: optionalString(input.assignee, 'assignee'),
dueOn: optionalString(input.dueOn, 'dueOn'),
dueAt: optionalString(input.dueAt, 'dueAt'),
completed: optionalBoolean(input.completed, 'completed'),
integrationName: optionalString(input.integrationName, 'integrationName'),
integration: optionalString(input.integration, 'integration'),
account: optionalString(input.account, 'account'),
secretName: optionalString(input.secretName, 'secretName'),
auth: requireAuthMode(input.auth),
confirm: optionalBoolean(input.confirm, 'confirm'),
dryRun: optionalBoolean(input.dryRun, 'dryRun'),
})
}