import {z} from 'zod' export type GetApiProfilesProfileIdArgs = {profileId: string}; export type GetApiProfilesProfileIdOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const device = z.object({type: z.string(), name: z.string().nullable().optional()}); export const os = z.object({family: z.string(), version: z.string(), platform: z.string()}); export const browser = z.object({product: z.string(), major: z.number().int(), version: z.string()}); export const webglMeta = z.object({vendor: z.string(), renderer: z.string().nullable().optional()}); export const fingerprint = z.object({version: z.string(), id: z.string(), userAgent: z.string(), device: device, os: os, browser: browser, webglMeta: webglMeta, resolution: z.string(), fonts: z.array(z.string())}); export const canvasSpoofingType = z.enum(["intelligent", "noise", "block", "off"]); export const webglSpoofingType = z.enum(["noise", "block", "off"]); export const webglMetaSpoofingType = z.enum(["automatic", "manual", "off"]); export const webglMetaSpoofingOptions = z.object({vendor: z.string().nullable().optional(), renderer: z.string().nullable().optional()}); export const webglMetaChoice = z.object({value: webglMetaSpoofingType, extra: webglMetaSpoofingOptions.nullable().optional()}); export const audioSpoofingType = z.enum(["off", "noise", "block"]); export const timezoneSpoofingType = z.enum(["automatic", "manual", "off"]); export const timezoneChoice = z.object({value: timezoneSpoofingType, extra: z.string().nullable().optional()}); export const geolocationSpoofingType = z.enum(["automatic", "manual", "block", "off"]); export const geolocationSpoofingOptions = z.object({latitude: z.number(), longitude: z.number()}); export const geolocationChoice = z.object({value: geolocationSpoofingType, extra: geolocationSpoofingOptions.nullable().optional()}); export const proxyConnectionType = z.enum(["none", "http", "socks5", "ssh"]); export const server = z.object({host: z.string(), port: z.number().int(), id: z.string().nullable().optional(), secret: z.string().nullable().optional()}); export const proxyChoice = z.object({value: proxyConnectionType, extra: server.nullable().optional()}); export const webRtcSpoofingType = z.enum(["automatic", "manual", "block", "off"]); export const webRtcSpoofingOptions = z.object({publicIp: z.string()}); export const webRtcChoice = z.object({value: webRtcSpoofingType, extra: webRtcSpoofingOptions.nullable().optional()}); export const fontSpoofingType = z.enum(["automatic", "off"]); export const screenSpoofingType = z.enum(["automatic", "manual", "off"]); export const screenChoice = z.object({value: screenSpoofingType, extra: z.string().nullable().optional()}); export const hardwareConcurrencySpoofingType = z.enum(["automatic", "manual", "off"]); export const hardwareConcurrencyChoice = z.object({value: hardwareConcurrencySpoofingType, extra: z.number().int().nullable().optional()}); export const deviceMemorySpoofingType = z.enum(["automatic", "manual", "off"]); export const deviceMemoryChoice = z.object({value: deviceMemorySpoofingType, extra: z.number().nullable().optional()}); export const passwordManagerType = z.enum(["enabled", "disabled"]); export const profileLifetimeState = z.enum(["created", "starting", "running", "terminating", "terminated", "locked", "loading", "unknown"]); export const statusResponse = z.object({lifetimeState: profileLifetimeState}); export const profileStorageLocation = z.enum(["local", "cloud"]); export const profileResponse = z.object({id: z.string(), name: z.string(), tags: z.array(z.string()), createdAt: z.string(), fingerprint: fingerprint, canvas: canvasSpoofingType, webgl: webglSpoofingType, webglMeta: webglMetaChoice, audio: audioSpoofingType, timezone: timezoneChoice, geolocation: geolocationChoice, proxy: proxyChoice, webRtc: webRtcChoice, fonts: fontSpoofingType, screen: screenChoice, hardwareConcurrency: hardwareConcurrencyChoice, deviceMemory: deviceMemoryChoice, language: z.string(), startPage: z.string(), passwordManager: passwordManagerType, extensions: z.array(z.string()), notes: z.string(), status: statusResponse, storage: profileStorageLocation.optional(), folderId: z.string().nullable().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 }; /** * Gets the profile with the specified GUID from the current workspace. On startup, Kameleo will automatically scan and load profiles stored * in your workspace folder on startup. * * GET /profiles/{profileId} */ export const getApiProfilesProfileId = async (args: GetApiProfilesProfileIdArgs, options?: GetApiProfilesProfileIdOptions) => { const {baseUrl = "http://localhost:5050", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/profiles/${encodeURIComponent(String(args.profileId))}${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(profileResponse, await res.json()) };