import { asanaRequest } from './client.ts'
import { mapStory, STORY_FIELDS } from './models.ts'
import type {
AsanaAuthInput,
AsanaStorySummary,
DryRunResult,
JsonRecord,
} from './types.ts'
import {
compactRecord,
optionalBoolean,
optionalString,
requireRecord,
requireString,
} from './types.ts'
import { requireAuthMode } from './auth.ts'
export type CreateStoryInput = AsanaAuthInput & {
/** Task GID to comment on. */
taskGid: string
/** Comment text. */
text: string
confirm?: boolean
dryRun?: boolean
}
function storyCreatePayload(input: CreateStoryInput): { path: string; data: JsonRecord } {
const taskGid = requireString(input.taskGid, 'taskGid')
return {
path: `/tasks/${encodeURIComponent(taskGid)}/stories`,
data: compactRecord({
text: requireString(input.text, 'text'),
}),
}
}
/**
* Create an Asana story (comment) on a task. Requires `confirm: true`, or use
* `dryRun: true`. Needs `stories:write`.
* @example
* import createStory from 'kody:@kody/asana/create-story'
* const preview = await createStory({
* taskGid: '123',
* text: 'Shipped in #482.',
* dryRun: true,
* })
*/
export async function createStory(
input: CreateStoryInput,
): Promise<AsanaStorySummary | DryRunResult<{ method: string; path: string; data: JsonRecord }>> {
const payload = storyCreatePayload(input)
if (input.dryRun) {
return { dryRun: true, wouldCall: { method: 'POST', ...payload } }
}
if (input.confirm !== true) {
throw new Error(
'Creating an Asana story requires confirm: true after explicit user approval, or dryRun: true.',
)
}
const result = await asanaRequest<unknown>({
...input,
operation: 'stories.write',
method: 'POST',
path: payload.path,
query: { opt_fields: STORY_FIELDS },
body: payload.data,
})
if (!result.data) throw new Error('Asana create story did not return a story.')
return mapStory(result.data)
}
/**
* Create an Asana story (comment) on a task. Requires `confirm: true`, or use
* `dryRun: true`.
* @example
* import createStory from 'kody:@kody/asana/create-story'
* const preview = await createStory({ taskGid: '123', text: 'Noted', dryRun: true })
*/
export default async function createStoryEntrypoint(
params: Partial<CreateStoryInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'create-story')
return createStory({
taskGid: requireString(input.taskGid, 'taskGid'),
text: requireString(input.text, 'text'),
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'),
})
}