All files / src headers.ts

100% Statements 15/15
100% Branches 8/8
100% Functions 1/1
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47            3x           3x                             10x 9x 9x 19x   4x   5x 5x   6x 6x   4x 4x     9x    
import { z } from 'zod/mini';
import type { JsonDict } from './types';
 
/**
 * Known StackOne API header keys that are forwarded as HTTP headers
 */
export const STACKONE_HEADER_KEYS = ['x-account-id'] as const;
 
/**
 * Zod schema for StackOne API headers (branded)
 * These headers are forwarded as HTTP headers in API requests
 */
export const stackOneHeadersSchema = z.record(z.string(), z.string()).brand<'StackOneHeaders'>();
 
/**
 * Branded type for StackOne API headers
 */
export type StackOneHeaders = z.infer<typeof stackOneHeadersSchema>;
 
/**
 * Normalises header values from JsonDict to StackOneHeaders (branded type)
 * Converts numbers and booleans to strings, and serialises objects to JSON
 *
 * @param headers - Headers object with unknown value types
 * @returns Normalised headers with string values only (branded type)
 */
export function normaliseHeaders(headers: JsonDict | undefined): StackOneHeaders {
	if (!headers) return stackOneHeadersSchema.parse({});
	const result: Record<string, string> = {};
	for (const [key, value] of Object.entries(headers)) {
		switch (true) {
			case value == null:
				continue;
			case typeof value === 'string':
				result[key] = value;
				break;
			case typeof value === 'number' || typeof value === 'boolean':
				result[key] = String(value);
				break;
			default:
				result[key] = JSON.stringify(value);
				break;
		}
	}
	return stackOneHeadersSchema.parse(result);
}