/** * @fileoverview Shared Kit types: `JsonRecord`, `KitAuthMode`, `KitAuthInput`, `KitPageInfo`, `DryRunResult`, `MutationInput`, `KitQuery`, `SubscriberSummary`, and related shapes. * Import from `kody:@kody/kit/types` when typing Kit helpers. Default export returns a type-name catalog. * * @example * import { type KitAuthMode } from 'kody:@kody/kit/types' */ export type JsonRecord = Record export type KitAuthMode = 'oauth' | 'apiKey' export type KitAuthInput = { /** Saved OAuth integration name. Defaults to `kit`. */ integrationName?: string /** Alias of `integrationName`. */ integration?: string /** * Short account alias. `work` → `kit-work`. Values that already start * with `kit-` are used as-is. `default` / `kit` / omitted → `kit`. */ account?: string /** User secret name for a v4 API key. Defaults to `kitApiKey`. */ secretName?: string /** Force OAuth or API-key auth when both exist. */ auth?: KitAuthMode } export type KitPageInfo = { hasNextPage: boolean after: string | null } export type DryRunResult = { dryRun: true method: string path: string body?: T } export type MutationInput = { confirm?: boolean dryRun?: boolean } export type KitQuery = Record export type SubscriberSummary = { id: number email_address?: string first_name?: string state?: string created_at?: string fields?: unknown } export type TagSummary = { id: number name: string } export type FormSummary = { id: number name?: string created_at?: string } export type SegmentSummary = { id: number name?: string } export type BroadcastSummary = { id: number subject?: string status?: string editUrl: string } export type SequenceSummary = { id: number name?: string active?: boolean email_address?: string } export type SequenceEmailSummary = { id: number sequenceId?: number subject?: string published?: boolean } /** * Shared Kit types and parsing helpers for this package. * Import from `kody:@kody/kit/types` when typing other Kit exports. * * @returns Catalog of exported type/helper names for agent discovery. * * @example * import types from 'kody:@kody/kit/types' * const catalog = await types() */ export function requireRecord(value: unknown, label: string): JsonRecord { if (!value || typeof value !== 'object' || Array.isArray(value)) { throw new Error(`${label} must be an object.`) } return value as JsonRecord } export function requireString( value: unknown, label: string, options: { allowEmpty?: boolean } = {}, ): string { if (typeof value !== 'string' || (!options.allowEmpty && value.trim().length === 0)) { throw new Error( `${label} must be ${options.allowEmpty ? 'a string' : 'a non-empty string'}.`, ) } return options.allowEmpty ? value : value.trim() } export function optionalString(value: unknown, label: string): string | undefined { if (value === undefined || value === null) return undefined return requireString(value, label) } export function optionalBoolean(value: unknown, label: string): boolean | undefined { if (value === undefined) return undefined if (typeof value !== 'boolean') throw new Error(`${label} must be a boolean.`) return value } export function optionalNumber(value: unknown, label: string): number | undefined { if (value === undefined || value === null) return undefined if (typeof value !== 'number' || !Number.isFinite(value)) { throw new Error(`${label} must be a number.`) } return value } export function requireId(value: unknown, label: string): string { if (typeof value === 'number' && Number.isFinite(value)) return String(value) return requireString(value, label) } export function clampInt( value: unknown, min: number, max: number, fallback: number, label = 'maxItems', ): number { if (value === undefined || value === null) return fallback if (typeof value !== 'number' || !Number.isInteger(value)) { throw new Error(`${label} must be an integer.`) } if (value < min || value > max) { throw new Error(`${label} must be between ${min} and ${max}.`) } return value } export function compactRecord(value: T): T { const output: JsonRecord = {} for (const [key, item] of Object.entries(value)) { if (item === undefined) continue output[key] = item } return output as T } export function parseAction( value: unknown, allowed: ReadonlyArray, fallback: T, label: string, ): T { if (value === undefined || value === null || value === '') return fallback const action = requireString(value, 'action') if (!allowed.includes(action as T)) { throw new Error(`${label} action must be one of: ${allowed.join(', ')}.`) } return action as T } /** * Shared Kit types for this package: `JsonRecord`, `KitAuthMode`, `KitAuthInput`, `KitPageInfo`, `DryRunResult`, `MutationInput`, `KitQuery`, `SubscriberSummary`, and related shapes. * Import from `kody:@kody/kit/types` when typing Kit helpers without pulling runtime clients. * * @returns Catalog of exported type names for agent discovery. * * @example * import types from 'kody:@kody/kit/types' * const catalog = await types() */ export default async function typesOverview() { return { auth: ['KitAuthInput', 'KitAuthMode'], models: [ 'SubscriberSummary', 'TagSummary', 'FormSummary', 'BroadcastSummary', 'SequenceSummary', ], } }