Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/microsoft

src/todo.ts

91 lines · 2.9 KB · TypeScript
import { resolveMicrosoftIntegration, type MicrosoftAccountParams } from './accounts.ts'
import { graphItems, graphRequest, requireConfirmOrDryRun, type JsonObject } from './core.ts'
import { boundedTop } from './validation.ts'

export type TodoListParams = MicrosoftAccountParams & {
  top?: number
}

export type TodoTasksParams = MicrosoftAccountParams & {
  listId: string
  top?: number
  filter?: string
}

export type TodoCreateParams = MicrosoftAccountParams & {
  listId: string
  title: string
  body?: string
  dueDateTime?: string
  importance?: 'low' | 'normal' | 'high'
  dryRun?: boolean
  confirm?: boolean
}

/** List Microsoft To Do lists. */
export async function listTaskLists(params: TodoListParams = {}) {
  const data = await graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: '/me/todo/lists',
    query: {
      $top: boundedTop(params.top, 20, 100),
      $select: 'id,displayName,isOwner,isShared,wellknownListName',
    },
  })
  return graphItems<JsonObject>(data)
}

/** List tasks in a To Do list. */
export async function listTasks(params: TodoTasksParams) {
  const listId = params.listId?.trim()
  if (!listId) throw new Error('listTasks requires listId.')
  const data = await graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: '/me/todo/lists/' + encodeURIComponent(listId) + '/tasks',
    query: {
      $top: boundedTop(params.top, 20, 100),
      $filter: params.filter,
      $select: 'id,title,status,importance,dueDateTime,completedDateTime,createdDateTime,body,isReminderOn',
    },
  })
  return graphItems<JsonObject>(data)
}

/** Preview or create a To Do task. Creating requires confirm: true. */
export async function createTask(params: TodoCreateParams) {
  const listId = params.listId?.trim()
  if (!listId) throw new Error('createTask requires listId.')
  const title = params.title?.trim()
  if (!title) throw new Error('createTask requires title.')
  const path = '/me/todo/lists/' + encodeURIComponent(listId) + '/tasks'
  const body: JsonObject = { title }
  if (params.body) body.body = { content: params.body, contentType: 'text' }
  if (params.importance) body.importance = params.importance
  if (params.dueDateTime) {
    body.dueDateTime = { dateTime: params.dueDateTime, timeZone: 'UTC' }
  }
  const mode = requireConfirmOrDryRun({
    dryRun: params.dryRun,
    confirm: params.confirm,
    action: 'createTask',
  })
  if (mode.dryRun) {
    return { dryRun: true as const, method: 'POST', path, body }
  }
  return graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    method: 'POST',
    path,
    body,
  })
}

/**
 * Microsoft To Do helpers for Microsoft Graph.
 * @example
 * import todo from 'kody:@kody/microsoft/todo'
 * const { items } = await todo().listTaskLists()
 */
export default function todo() {
  return { listTaskLists, listTasks, createTask }
}