Skip to content

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

Package listing

@kody/microsoft

src/onedrive.ts

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

export type DriveChildrenParams = MicrosoftAccountParams & {
  itemId?: string
  path?: string
  top?: number
  select?: string
}

export type DriveSearchParams = MicrosoftAccountParams & {
  q: string
  top?: number
  select?: string
}

export type DriveItemParams = MicrosoftAccountParams & {
  itemId: string
  select?: string
}

const ITEM_SELECT = 'id,name,size,lastModifiedDateTime,webUrl,folder,file,parentReference,createdBy'

/** Read the signed-in user's OneDrive drive metadata. */
export async function getDrive(params: MicrosoftAccountParams = {}) {
  return graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: '/me/drive',
    query: { $select: 'id,driveType,name,quota,webUrl' },
  })
}

function childrenPath(params: DriveChildrenParams): string {
  if (params.itemId) return '/me/drive/items/' + encodeURIComponent(params.itemId) + '/children'
  if (params.path) {
    const trimmed = params.path.replace(/^\/+/, '').replace(/\/+$/, '')
    if (!trimmed || trimmed === 'root') return '/me/drive/root/children'
    return '/me/drive/root:/' + trimmed + ':/children'
  }
  return '/me/drive/root/children'
}

/** List files and folders under a OneDrive item or path. */
export async function listChildren(params: DriveChildrenParams = {}) {
  const data = await graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: childrenPath(params),
    query: {
      $top: boundedTop(params.top, 20, 200),
      $select: params.select ?? ITEM_SELECT,
    },
  })
  return graphItems<JsonObject>(data)
}

/** Search the signed-in user's OneDrive. */
export async function searchItems(params: DriveSearchParams) {
  const q = params.q?.trim()
  if (!q) throw new Error('searchItems requires q.')
  const data = await graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: '/me/drive/root/search(q=\'' + encodeURIComponent(q) + '\')',
    query: {
      $top: boundedTop(params.top, 10, 100),
      $select: params.select ?? ITEM_SELECT,
    },
  })
  return graphItems<JsonObject>(data)
}

/** Read OneDrive item metadata. */
export async function getItem(params: DriveItemParams) {
  const itemId = params.itemId?.trim()
  if (!itemId) throw new Error('getItem requires itemId.')
  return graphRequest<JsonObject>({
    integration: resolveMicrosoftIntegration(params),
    path: '/me/drive/items/' + encodeURIComponent(itemId),
    query: { $select: params.select ?? ITEM_SELECT },
  })
}

/**
 * OneDrive helpers for Microsoft Graph.
 * @example
 * import onedrive from 'kody:@kody/microsoft/onedrive'
 * const { items } = await onedrive().listChildren({ top: 10 })
 */
export default function onedrive() {
  return { getDrive, listChildren, searchItems, getItem }
}