import {z} from 'zod' export type RcGlobalOptions = {_config?: {[key: string]: unknown} | undefined, _filter?: {[key: string]: unknown} | undefined, _group?: string | undefined}; export type CreateApiOptionsLocalArgs = {Prefer?: 'respond-async' | undefined, body: RcGlobalOptions}; export type CreateApiOptionsLocalOptions = {baseUrl?: string | undefined, basicAuth?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const createApiOptionsLocalResponse = z.object({config: z.object({AllowHTTPSDowngrade: z.boolean(), AskPassword: z.boolean(), AutoConfirm: z.boolean(), BackupDir: z.string(), BindAddr: z.string(), BufferSize: z.number().int(), BwLimit: z.string(), BwLimitFile: z.string(), CaCert: z.array(z.string()), CheckFirst: z.boolean(), CheckSum: z.boolean(), Checkers: z.number().int(), ClientCert: z.string(), ClientKey: z.string(), CompareDest: z.array(z.string()), ConnectTimeout: z.number().int(), Cookie: z.boolean(), CopyDest: z.array(z.string()), CutoffMode: z.string(), DataRateUnit: z.string(), DefaultTime: z.string(), DeleteMode: z.number().int(), DisableFeatures: z.string().nullable(), DisableHTTP2: z.boolean(), DisableHTTPKeepAlives: z.boolean(), DownloadHeaders: z.string().nullable(), DryRun: z.boolean(), Dump: z.string(), ErrorOnNoTransfer: z.boolean(), ExpectContinueTimeout: z.number().int(), FixCase: z.boolean(), FsCacheExpireDuration: z.number().int(), FsCacheExpireInterval: z.number().int(), Headers: z.string().nullable(), HumanReadable: z.boolean(), IgnoreCaseSync: z.boolean(), IgnoreChecksum: z.boolean(), IgnoreErrors: z.boolean(), IgnoreExisting: z.boolean(), IgnoreSize: z.boolean(), IgnoreTimes: z.boolean(), Immutable: z.boolean(), Inplace: z.boolean(), InsecureSkipVerify: z.boolean(), Interactive: z.boolean(), KvLockTime: z.number().int(), Links: z.boolean(), LogLevel: z.string(), LowLevelRetries: z.number().int(), MaxBacklog: z.number().int(), MaxBufferMemory: z.number().int(), MaxDelete: z.number().int(), MaxDeleteSize: z.number().int(), MaxDepth: z.number().int(), MaxDuration: z.number().int(), MaxStatsGroups: z.number().int(), MaxTransfer: z.number().int(), Metadata: z.boolean(), MetadataMapper: z.string().nullable(), MetadataSet: z.string().nullable(), ModifyWindow: z.number().int(), MultiThreadChunkSize: z.number().int(), MultiThreadCutoff: z.number().int(), MultiThreadSet: z.boolean(), MultiThreadStreams: z.number().int(), MultiThreadWriteBufferSize: z.number().int(), NoCheckDest: z.boolean(), NoConsole: z.boolean(), NoGzip: z.boolean(), NoTraverse: z.boolean(), NoUnicodeNormalization: z.boolean(), NoUpdateDirModTime: z.boolean(), NoUpdateModTime: z.boolean(), OrderBy: z.string(), PartialSuffix: z.string(), PasswordCommand: z.string().nullable(), Progress: z.boolean(), ProgressTerminalTitle: z.boolean(), RefreshTimes: z.boolean(), Retries: z.number().int(), RetriesInterval: z.number().int(), ServerSideAcrossConfigs: z.boolean(), SizeOnly: z.boolean(), StatsFileNameLength: z.number().int(), StatsLogLevel: z.string(), StatsOneLine: z.boolean(), StatsOneLineDate: z.boolean(), StatsOneLineDateFormat: z.string(), StreamingUploadCutoff: z.number().int(), Suffix: z.string(), SuffixKeepExtension: z.boolean(), TPSLimit: z.number(), TPSLimitBurst: z.number().int(), TerminalColorMode: z.string(), Timeout: z.number().int(), TrackRenames: z.boolean(), TrackRenamesStrategy: z.string(), TrafficClass: z.number().int(), Transfers: z.number().int(), UpdateOlder: z.boolean(), UploadHeaders: z.string().nullable(), UseJSONLog: z.boolean(), UseListR: z.boolean(), UseMmap: z.boolean(), UseServerModTime: z.boolean(), UserAgent: z.string(), ListCutoff: z.number().int(), ClientPass: z.string(), MaxConnections: z.number().int(), NameTransform: z.array(z.string()).nullable(), HTTPProxy: z.string()}), filter: z.object({DeleteExcluded: z.boolean(), ExcludeFile: z.array(z.string()), ExcludeFrom: z.array(z.string()), ExcludeRule: z.array(z.string()), FilesFrom: z.array(z.string()), FilesFromRaw: z.array(z.string()), FilterFrom: z.array(z.string()), FilterRule: z.array(z.string()), HashFilter: z.string(), IgnoreCase: z.boolean(), IncludeFrom: z.array(z.string()), IncludeRule: z.array(z.string()), MaxAge: z.number().int(), MaxSize: z.number().int(), MetaRules: z.object({ExcludeFrom: z.array(z.string()), ExcludeRule: z.array(z.string()), FilterFrom: z.array(z.string()), FilterRule: z.array(z.string()), IncludeFrom: z.array(z.string()), IncludeRule: z.array(z.string())}), MinAge: z.number().int(), MinSize: z.number().int(), FilesFrom0: z.array(z.string()).nullable()})}); 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 }; /** * Show effective options * * POST /options/local */ export const createApiOptionsLocal = async (args: CreateApiOptionsLocalArgs, options?: CreateApiOptionsLocalOptions) => { const {baseUrl = "http://localhost:5572", fetch: fetchFn = fetch, basicAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args.Prefer != null) headers.set("Prefer", String(args.Prefer)) if (basicAuth !== undefined) headers.set('authorization', `Basic ${btoa(`${basicAuth.username}:${basicAuth.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/options/local${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiOptionsLocalResponse, await res.json()) };