Skip to content
← Public packages

@kody/doordash

Order food on DoorDash as a customer through the consumer MCP used by dd-cli.

src/cart.ts

95 lines · 3.0 KB · TypeScript
/**
 * Cart helpers (list / show / add / remove / delete).
 *
 * ```ts
 * import cart from 'kody:@kody/doordash/cart'
 * await cart({ action: 'list' })
 * await cart({ action: 'add-items', storeId: '…', itemsJson: […] , confirm: true })
 * ```
 */

import { callMcpTool, TOOLS, type DoorDashMcpAuthInput } from './mcp.ts'

const ACTIONS = ['list', 'show', 'add-items', 'remove-item', 'delete'] as const
export type CartAction = (typeof ACTIONS)[number]

export type CartInput = DoorDashMcpAuthInput & {
	action?: CartAction
	cartUuid?: string
	storeId?: string | number
	menuId?: string | number
	cartItemId?: string | number
	itemsJson?: unknown
	groupCartUrl?: string
	/** Mutations default to dry-run. Pass confirm: true to execute. */
	confirm?: boolean
	dryRun?: boolean
}

function shouldDryRun(input: CartInput, mutating: boolean) {
	if (input.dryRun === true) return true
	if (mutating && input.confirm !== true && input.dryRun !== false) return true
	return false
}

export default async function cart(input: CartInput = {}) {
	const action = (input.action ?? 'list') as CartAction
	if (!ACTIONS.includes(action)) {
		throw new Error('Unknown cart action: ' + action + '. Valid: ' + ACTIONS.join(', '))
	}

	if (action === 'list') {
		const args: Record<string, unknown> = {}
		if (input.storeId != null) args.store_id = String(input.storeId)
		return callMcpTool({ ...input, name: TOOLS.listActiveCarts, arguments: args })
	}
	if (action === 'show') {
		const cartUuid = String(input.cartUuid ?? '').trim()
		if (!cartUuid) throw new Error('cartUuid is required for show.')
		return callMcpTool({
			...input,
			name: TOOLS.getCart,
			arguments: { cart_uuid: cartUuid },
		})
	}
	if (action === 'add-items') {
		const storeId = String(input.storeId ?? '').trim()
		if (!storeId) throw new Error('storeId is required for add-items.')
		if (input.itemsJson == null) throw new Error('itemsJson is required for add-items.')
		const args: Record<string, unknown> = {
			store_id: storeId,
			items: input.itemsJson,
		}
		if (input.menuId != null) args.menu_id = String(input.menuId)
		if (input.cartUuid) args.cart_uuid = String(input.cartUuid)
		if (input.groupCartUrl) args.group_cart_url = String(input.groupCartUrl)
		return callMcpTool({
			...input,
			name: TOOLS.addToCart,
			arguments: args,
			dryRun: shouldDryRun(input, true),
		})
	}
	if (action === 'remove-item') {
		const cartUuid = String(input.cartUuid ?? '').trim()
		const cartItemId = String(input.cartItemId ?? '').trim()
		if (!cartUuid || !cartItemId) {
			throw new Error('cartUuid and cartItemId are required for remove-item.')
		}
		return callMcpTool({
			...input,
			name: TOOLS.removeCartItem,
			arguments: { cart_uuid: cartUuid, cart_item_id: cartItemId },
			dryRun: shouldDryRun(input, true),
		})
	}
	// delete
	const cartUuid = String(input.cartUuid ?? '').trim()
	if (!cartUuid) throw new Error('cartUuid is required for delete.')
	return callMcpTool({
		...input,
		name: TOOLS.clearCart,
		arguments: { cart_uuid: cartUuid },
		dryRun: shouldDryRun(input, true),
	})
}