Skip to content
← Public packages

@kody/doordash-driver

Request DoorDash Drive (Dasher) deliveries with JWT auth from Developer Portal access keys.

src/smoke-test.ts

115 lines · 3.4 KB · TypeScript
/**
 * Safe setup check for DoorDash Drive: settings + signing secret metadata.
 * Does not call DoorDash unless you pass `live: true` (then hits a dry-run create-quote preview only by default).
 *
 * ```ts
 * import smokeTest from 'kody:@kody/doordash-driver/smoke-test'
 * await smokeTest()
 * ```
 */

import { kody } from 'kody:runtime'
import {
	API_HOST,
	DEVELOPER_PORTAL_URL,
	createDriveJwt,
	doorDashRequest,
	readDriveIdentity,
	resolveSigningSecretName,
	setupUrls,
	type DoorDashAuthInput,
} from './core.ts'
import { readDriveSettings } from './settings.ts'

function secretEntries(result: unknown): Array<{ name?: string; scope?: string }> {
	if (result && typeof result === 'object' && Array.isArray((result as { secrets?: unknown }).secrets)) {
		return (result as { secrets: Array<{ name?: string; scope?: string }> }).secrets
	}
	if (Array.isArray(result)) return result as Array<{ name?: string; scope?: string }>
	return []
}

export type SmokeTestInput = DoorDashAuthInput & {
	/** When true, also run a create-quote dry-run preview (no live DoorDash write). */
	live?: boolean
}

export default async function smokeTest(input: SmokeTestInput = {}) {
	const settings = await readDriveSettings()
	const signingSecretSecret = resolveSigningSecretName(input)
	let identityOk = false
	let identityError: string | null = null
	try {
		await readDriveIdentity(input)
		identityOk = true
	} catch (error) {
		identityError = error instanceof Error ? error.message : String(error)
	}

	const names = new Set<string>()
	try {
		const listed = await kody.secretList({ scope: 'user' })
		for (const entry of secretEntries(listed)) {
			if (entry?.name) names.add(String(entry.name))
		}
	} catch {
		/* listing can be empty in some contexts */
	}
	const hasSigningSecret = names.has(signingSecretSecret)

	const mintSelfCheck = await createDriveJwt({
		developerId: '00000000-0000-4000-8000-000000000001',
		keyId: '00000000-0000-4000-8000-000000000002',
		signingSecret: btoa('doordash-smoke-test-key'),
		ttlSeconds: 60,
	})
	const jwtParts = mintSelfCheck.split('.')

	const result: Record<string, unknown> = {
		ok: identityOk && hasSigningSecret && jwtParts.length === 3,
		identityOk,
		identityError,
		hasSigningSecret,
		signingSecretSecret,
		settings: {
			developerId: settings.developerId,
			keyId: settings.keyId,
		},
		jwtSelfCheck: { parts: jwtParts.length, algHeaderOk: jwtParts[0] != null },
		setup: setupUrls(input),
		portal: DEVELOPER_PORTAL_URL,
		approveHost: API_HOST,
		next: [] as string[],
	}

	const next = result.next as string[]
	if (!identityOk) {
		next.push(
			'Save developerId + keyId: import settings from "kody:@kody/doordash-driver/settings"; await settings({ developerId, keyId })',
		)
	}
	if (!hasSigningSecret) {
		next.push('Save signing_secret: ' + settings.signingSecretUrl)
		next.push('Approve host ' + API_HOST + ' on that secret.')
	}
	if (next.length === 0) {
		next.push('Try a quote dry-run: import { createQuote } from "kody:@kody/doordash-driver/create-quote"; await createQuote({ ... })')
	}

	if (input.live) {
		result.livePreview = await doorDashRequest({
			...input,
			method: 'POST',
			path: '/drive/v2/quotes',
			body: {
				external_delivery_id: 'kody-smoke-' + Date.now(),
				pickup_address: '901 Market Street, San Francisco, CA 94103',
				dropoff_address: '901 Market Street, San Francisco, CA 94103',
				order_value: 1999,
			},
			dryRun: true,
		})
	}

	return result
}