import { Parser } from "ts-matches" import * as T from "../types" import FileHelper from "./fileHelper" import nullIfEmpty from "./nullIfEmpty" import { GetWrapperData, getWrapperData } from "./getWrapperData" import { CheckResult, checkPortListening, checkWebUrl, } from "../health/checkFns" import { ExtractWrapperData } from "../types" import { GetSystemSmtp } from "./GetSystemSmtp" import "./nullIfEmpty" import "./fileHelper" import "./getWrapperData" import "./deepEqual" import "./deepMerge" import "./once" import { LocalBinding } from "../mainFn/LocalBinding" import { LocalPort } from "../mainFn/LocalPort" import { NetworkBuilder } from "../mainFn/NetworkBuilder" import { TorHostname } from "../mainFn/TorHostname" // prettier-ignore export type FlattenIntersection = T extends ArrayLike ? T : T extends object ? {} & {[P in keyof T]: T[P]} : T; export type _ = FlattenIntersection /** Used to check if the file exists before hand */ export const exists = ( effects: T.Effects, props: { path: string; volumeId: string }, ) => effects.metadata(props).then( (_) => true, (_) => false, ) export const isKnownError = (e: unknown): e is T.KnownError => e instanceof Object && ("error" in e || "error-code" in e) type Cdr = A extends [unknown, ...infer Cdr] ? Cdr : [] declare const affine: unique symbol function withAffine() { return {} as { [affine]: B } } export type WrapperDataOptionals = { validator?: Parser> /** Defaults to what ever the package currently in */ packageId?: string | undefined } export type Utils = { readFile: (fileHelper: FileHelper) => ReturnType["read"]> writeFile: ( fileHelper: FileHelper, data: A, ) => ReturnType["write"]> getSystemSmtp: () => GetSystemSmtp & WrapperOverWrite getWrapperData: ( packageId: string, path: T.EnsureWrapperDataPath, ) => GetWrapperData & WrapperOverWrite getOwnWrapperData: ( path: T.EnsureWrapperDataPath, ) => GetWrapperData & WrapperOverWrite setOwnWrapperData: ( path: T.EnsureWrapperDataPath, value: ExtractWrapperData, ) => Promise checkPortListening( port: number, options: { errorMessage: string successMessage: string timeoutMessage?: string timeout?: number }, ): Promise checkWebUrl( url: string, options?: { timeout?: number successMessage?: string errorMessage?: string }, ): Promise bindLan: (port: number) => Promise networkBuilder: () => NetworkBuilder torHostName: (id: string) => TorHostname exists: (props: { path: string; volumeId: string }) => Promise nullIfEmpty: typeof nullIfEmpty } export const utils = ( effects: T.Effects, ): Utils => ({ getSystemSmtp: () => new GetSystemSmtp(effects) as GetSystemSmtp & WrapperOverWrite, readFile: (fileHelper: FileHelper) => fileHelper.read(effects), writeFile: (fileHelper: FileHelper, data: A) => fileHelper.write(data, effects), exists: (props: { path: string; volumeId: string }) => exists(effects, props), nullIfEmpty, getWrapperData: ( packageId: string, path: T.EnsureWrapperDataPath, ) => getWrapperData(effects, path as any, { packageId, }) as any, getOwnWrapperData: ( path: T.EnsureWrapperDataPath, ) => getWrapperData(effects, path as any) as any, setOwnWrapperData: ( path: T.EnsureWrapperDataPath, value: ExtractWrapperData, ) => effects.setWrapperData({ value, path: path as any }), checkPortListening: checkPortListening.bind(null, effects), checkWebUrl: checkWebUrl.bind(null, effects), bindLan: async (port: number) => LocalPort.bindLan(effects, port), networkBuilder: () => NetworkBuilder.of(effects), torHostName: (id: string) => TorHostname.of(effects, id), }) type NeverPossible = { [affine]: string } export type NoAny = NeverPossible extends A ? keyof NeverPossible extends keyof A ? never : A : A