import {z} from 'zod' export type GetApiMePreferencesClientArgs = {client: 'desktop' | 'web'}; export type GetApiMePreferencesClientOptions = {baseUrl: string, BasicAuth?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const modelsAlphaFeature = z.object({alpha_feature_id: z.number().int().optional(), code: z.string().optional(), deleted_at: z.string().optional(), description: z.string().optional(), enabled: z.boolean().optional()}); export const modelsAllPreferences = z.object({alpha_features: z.array(modelsAlphaFeature).optional(), calendar_visible_hours_end: z.number().int().optional(), calendar_visible_hours_start: z.number().int().optional(), charts_view_type: z.string().optional(), collapseDetailedReportEntries: z.boolean().optional(), collapseTimeEntries: z.boolean().optional(), dashboards_view_type: z.string().optional(), date_format: z.string().optional(), decimal_separator: z.string().optional(), displayDensity: z.string().optional(), distinctRates: z.string().optional(), duration_format: z.string().optional(), duration_format_on_timer_duration_field: z.boolean().optional(), firstSeenBusinessPromo: z.number().int().optional(), hide_keyboard_shortcut: z.boolean().optional(), keyboard_increment_timer_page: z.number().int().optional(), keyboard_shortcuts_enabled: z.boolean().optional(), manualEntryMode: z.string().optional(), manualMode: z.boolean().optional(), manualModeOverlaySeen: z.boolean().optional(), offlineMode: z.string().optional(), pg_time_zone_name: z.string().optional(), projectDashboardActivityMode: z.string().optional(), record_timeline: z.boolean().optional(), reportRounding: z.boolean().optional(), reportRoundingDirection: z.string().optional(), reportRoundingStepInMinutes: z.number().int().optional(), reportsHideWeekends: z.boolean().optional(), seenFollowModal: z.boolean().optional(), seenFooterPopup: z.boolean().optional(), seenProjectDashboardOverlay: z.boolean().optional(), seenTogglButtonModal: z.boolean().optional(), send_product_emails: z.boolean().optional(), send_timer_notifications: z.boolean().optional(), send_weekly_report: z.boolean().optional(), showTimeInTitle: z.boolean().optional(), show_timeline_in_day_view: z.boolean().optional(), show_total_billable_hours: z.boolean().optional(), show_weekend_on_timer_page: z.boolean().optional(), snowballReportRounding: z.string().optional(), stack_times_on_manual_mode_after: z.string().optional(), summaryReportAmounts: z.string().optional(), summaryReportDistinctRates: z.boolean().optional(), summaryReportGrouping: z.string().optional(), summaryReportSortAsc: z.boolean().optional(), summaryReportSortField: z.string().optional(), summaryReportSubGrouping: z.string().optional(), theme: z.string().optional(), timeofday_format: z.string().optional(), timerView: z.string().optional(), timerViewMobile: z.string().optional(), toSAcceptNeeded: z.boolean().optional(), visibleFooter: z.string().optional(), webTimeEntryStarted: z.boolean().optional(), webTimeEntryStopped: z.boolean().optional(), weeklyReportGrouping: z.string().optional(), weeklyReportValueToShow: z.string().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Preferences for an specific client of the current user * * GET /me/preferences/{client} */ export const getApiMePreferencesClient = async (args: GetApiMePreferencesClientArgs, options: GetApiMePreferencesClientOptions) => { const {baseUrl, fetch: fetchFn = fetch, BasicAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (BasicAuth !== undefined) headers.set('authorization', `Basic ${btoa(`${BasicAuth.username}:${BasicAuth.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/me/preferences/${encodeURIComponent(String(args.client))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(modelsAllPreferences, await res.json()) };