import { doesExist, Maybe } from '@apextoaster/js-utils'; import { merge } from 'lodash'; import { Img2ImgParams, InpaintParams, ModelParams, OutpaintParams, STATUS_SUCCESS, Txt2ImgParams, UpscaleParams } from './client.js'; export interface ConfigNumber { default: number; min: number; max: number; step: number; } export interface ConfigString { default: string; keys: Record; } /** * Helper type to filter keys whose value extends `TValid`. */ export type KeyFilter = { [K in keyof T]: T[K] extends TValid ? K : never; }[keyof T]; /** * Keep fields with a file-like value, but make them optional. */ export type ConfigFiles = { [K in KeyFilter>]: Maybe; }; /** * Map numbers and strings to their corresponding config types and drop the rest of the fields. */ export type ConfigRanges = { [K in KeyFilter]: T[K] extends number ? ConfigNumber : T[K] extends string ? ConfigString : never; }; /** * Keep fields whose value extends `TValid` and drop the rest. */ export type ConfigState = { [K in KeyFilter]: T[K] extends TValid ? T[K] : never; }; // eslint does not understand how to indent this and expects each line to increase /* eslint-disable */ /** * Combine all of the request parameter groups, make optional parameters required, then * map them to the number/string ranges. */ export type ServerParams = ConfigRanges> & { version: string; }; /* eslint-enable */ /** * Parameters that can be customized on the client, through the config file or settings tab. */ export interface ClientParams { model: ConfigString; platform: ConfigString; scheduler: ConfigString; prompt: ConfigString; } export interface Config { api: { root: string; }; params: T; } export const IMAGE_FILTER = '.bmp, .jpg, .jpeg, .png'; export const PARAM_VERSION = '>=0.4.0'; export const STALE_TIME = 300_000; // 5 minutes export const POLL_TIME = 5_000; // 5 seconds export const SAVE_TIME = 5_000; // 5 seconds export async function loadConfig(): Promise { const configPath = new URL('./config.json', window.location.href); const configReq = await fetch(configPath); if (configReq.status === STATUS_SUCCESS) { return configReq.json(); } else { throw new Error('could not load config'); } } export function mergeConfig(client: Config, server: ServerParams): Config { const full = merge({}, server, client.params);; return { ...client, params: full, }; } export function getApiRoot(config: Config): string { const query = new URLSearchParams(window.location.search); const api = query.get('api'); if (doesExist(api)) { return api; } else { return config.api.root; } }