import {z} from 'zod' export type GetApiApiV1AppsArgs = {page?: number | undefined, page_size?: number | undefined, search?: (string | null) | undefined, status?: (Array | null) | undefined, listed?: (boolean | null) | undefined, base_image?: (string | null) | undefined, instance_type?: (string | null) | undefined, instance_types?: (Array | null) | undefined, family?: ('all' | 'cpu' | 'gpu') | undefined, kms_slug?: (string | null) | undefined, kms_type?: (string | null) | undefined, node?: (string | null) | undefined, region?: (string | null) | undefined, summary_only?: boolean | undefined}; export type GetApiApiV1AppsOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const profileGetResponse = z.object({display_name: z.string().nullable().optional(), avatar_url: z.string().nullable().optional(), description: z.string().nullable().optional(), custom_domain: z.string().nullable().optional()}); export const machineInfo = z.object({vcpu: z.number().int(), memory: z.number().int(), disk_size: z.number().int(), gpu_count: z.number().int()}); export const teehouseApiRoutesWorkspaceAppsV20251028SchemasCvmBasicInfo = z.object({vm_uuid: z.string().nullable(), app_id: z.string(), name: z.string().optional(), status: z.string(), vcpu: z.number().int(), memory: z.number().int(), disk_size: z.number().int(), teepod_id: z.number().int(), teepod_name: z.string(), region_identifier: z.string().nullable(), kms_type: z.string().nullable(), instance_type: z.string().nullable(), listed: z.boolean().nullable().optional(), base_image: z.string().nullable().optional(), kms_slug: z.string().nullable().optional(), kms_id: z.string().nullable().optional(), kms_contract_id: z.string().nullable().optional(), instance_id: z.string().nullable().optional(), machine_info: machineInfo.nullable().optional(), updated_at: z.string().nullable().optional(), enabled_ssh_access: z.boolean()}); export const teehouseApiRoutesWorkspaceAppsV20251028SchemasDstackAppFullResponse = z.object({id: z.string(), name: z.string(), app_id: z.string(), app_provision_type: z.string().nullable().optional(), app_icon_url: z.string().nullable().optional(), created_at: z.string(), enabled_guest_agent_access: z.boolean(), kms_type: z.string(), profile: profileGetResponse.nullable().optional(), current_cvm: teehouseApiRoutesWorkspaceAppsV20251028SchemasCvmBasicInfo.nullable().optional(), cvms: z.array(teehouseApiRoutesWorkspaceAppsV20251028SchemasCvmBasicInfo).optional(), cvm_count: z.number().int().optional(), team_slug: z.string().nullable().optional(), team_name: z.string().nullable().optional()}); export const teehouseApiRoutesWorkspaceAppsV20251028SchemasDstackAppListResponse = z.object({dstack_apps: z.array(teehouseApiRoutesWorkspaceAppsV20251028SchemasDstackAppFullResponse), page: z.number().int(), page_size: z.number().int(), total: z.number().int(), total_pages: z.number().int()}); export const billingPeriod = z.enum(["skip", "hourly", "monthly"]); export const cVMResourceInfo = z.object({instance_type: z.string().nullable().optional(), vcpu: z.number().int().nullable().optional(), memory_in_gb: z.number().nullable().optional(), disk_in_gb: z.number().int().nullable().optional(), gpus: z.number().int().nullable().optional(), compute_billing_price: z.string().nullable().optional(), billing_period: billingPeriod.nullable().optional()}); export const nodeDeviceIdOut = z.object({device_id: z.string(), algorithm_version: z.string(), enabled: z.boolean()}); export const teepodStatus = z.enum(["ONLINE", "OFFLINE", "MAINTENANCE"]); export const nodeRef = z.object({object_type: z.literal("node").optional(), id: z.number().int().nullable().optional(), node_id: z.number().int().nullable().optional(), node: z.string().nullable().optional(), name: z.string().nullable().optional(), region: z.string().nullable().optional(), device_id: z.string().nullable().optional(), device_ids: z.array(nodeDeviceIdOut).optional(), ppid: z.string().nullable().optional(), status: teepodStatus.nullable().optional(), version: z.string().nullable().optional()}); export const cVMOSInfo = z.object({name: z.string().nullable().optional(), version: z.string().nullable().optional(), is_dev: z.boolean().nullable().optional(), os_image_hash: z.string().nullable().optional()}); export const kmsType = z.enum(["phala", "ethereum", "base", "local", "legacy"]); export const cVMKmsInfo = z.object({chain_id: z.number().int().nullable().optional(), dstack_kms_address: z.string().nullable().optional(), dstack_app_address: z.string().nullable().optional(), deployer_address: z.string().nullable().optional(), rpc_endpoint: z.string().nullable().optional(), encrypted_env_pubkey: z.string().nullable().optional(), k256_pubkey: z.string().nullable().optional()}); export const cVMProgressInfo = z.object({target: z.string().nullable().optional(), started_at: z.string().nullable().optional(), correlation_id: z.string().nullable().optional()}); export const cVMGatewayInfo = z.object({base_domain: z.string().nullable().optional(), cname: z.string().nullable().optional()}); export const cVMLogUrls = z.object({serial: z.string().nullable().optional(), stdout: z.string().nullable().optional(), stderr: z.string().nullable().optional(), container_log_base: z.string().nullable().optional()}); export const cvmNetworkUrls = z.object({app: z.string(), instance: z.string()}); export const workspaceRef = z.object({object_type: z.literal("workspace").optional(), id: z.string(), name: z.string(), slug: z.string().nullable().optional(), avatar_url: z.string().nullable().optional()}); export const userRef = z.object({object_type: z.literal("user").optional(), id: z.string().nullable().optional(), username: z.string().nullable().optional(), avatar_url: z.string().nullable().optional()}); export const cVMHourlyRate = z.object({total: z.string().nullable().optional(), compute: z.string().nullable().optional(), disk: z.string().nullable().optional()}); export const gpuRentalOrderStatus = z.enum(["pending", "provisioning", "active", "teardown", "completed", "cancelled"]); export const gpuSkuPricingPlan = z.enum(["on_demand", "commitment"]); export const cVMGpuRentalOrderInfo = z.object({order_id: z.string(), status: gpuRentalOrderStatus, pricing_plan: gpuSkuPricingPlan.nullable().optional(), commitment_days: z.number().int().nullable().optional(), auto_renew: z.boolean().optional(), expires_at: z.string().nullable().optional(), renewal_in_progress: z.boolean().optional(), renewal_next_attempt_at: z.string().nullable().optional(), agreed_hourly_rate: z.string().nullable().optional(), hourly_billing_start_time: z.string().nullable().optional(), activated_at: z.string().nullable().optional(), completed_at: z.string().nullable().optional(), cancelled_at: z.string().nullable().optional(), decoupled_at: z.string().nullable().optional(), sku_code: z.string().nullable().optional(), sku_display_name: z.string().nullable().optional()}); export const teehouseApiRoutesCvmsV20260121SchemasCVMInfo = z.object({id: z.string(), name: z.string(), app_id: z.string().nullable().optional(), vm_uuid: z.string().nullable().optional(), instance_id: z.string().nullable().optional(), resource: cVMResourceInfo, node_info: nodeRef.nullable().optional(), os: cVMOSInfo.nullable().optional(), kms_type: kmsType.nullable().optional(), kms_info: cVMKmsInfo.nullable().optional(), status: z.string(), in_progress: z.boolean().optional(), progress: cVMProgressInfo.nullable().optional(), compose_hash: z.string().nullable().optional(), docker_compose_hash: z.string().nullable().optional(), pre_launch_script_hash: z.string().nullable().optional(), gateway: cVMGatewayInfo, logs: cVMLogUrls.optional(), services: z.array(z.record(z.string(), z.unknown())).optional(), endpoints: z.array(cvmNetworkUrls).nullable().optional(), public_logs: z.boolean().optional(), public_sysinfo: z.boolean().optional(), public_tcbinfo: z.boolean().optional(), gateway_enabled: z.boolean().optional(), secure_time: z.boolean().optional(), managed_env: z.boolean().optional(), enabled_ssh_access: z.boolean(), storage_fs: z.string().optional(), workspace: workspaceRef.nullable().optional(), creator: userRef.nullable().optional(), hourly_rate: cVMHourlyRate.nullable().optional(), billing_interval: z.enum(["hourly", "monthly", "unmetered"]).nullable().optional(), gpu_rental_order: cVMGpuRentalOrderInfo.nullable().optional(), created_at: z.string().nullable().optional(), deleted_at: z.string().nullable().optional(), listed: z.boolean().optional(), project_type: z.string().nullable().optional()}); export const teehouseApiRoutesWorkspaceAppsV20260121SchemasDstackAppFullResponse = z.object({id: z.string(), name: z.string(), app_id: z.string(), app_provision_type: z.string().nullable().optional(), app_icon_url: z.string().nullable().optional(), created_at: z.string(), enabled_guest_agent_access: z.boolean(), kms_type: z.string(), profile: profileGetResponse.nullable().optional(), current_cvm: teehouseApiRoutesCvmsV20260121SchemasCVMInfo.nullable().optional(), cvms: z.array(teehouseApiRoutesCvmsV20260121SchemasCVMInfo).optional(), cvm_count: z.number().int().optional()}); export const teehouseApiRoutesWorkspaceAppsV20260121SchemasDstackAppListResponse = z.object({dstack_apps: z.array(teehouseApiRoutesWorkspaceAppsV20260121SchemasDstackAppFullResponse), page: z.number().int(), page_size: z.number().int(), total: z.number().int(), total_pages: z.number().int()}); export const getApiApiV1AppsResponse = z.union([teehouseApiRoutesWorkspaceAppsV20251028SchemasDstackAppListResponse, teehouseApiRoutesWorkspaceAppsV20260121SchemasDstackAppListResponse]); 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 }; /** * List apps * * GET /api/v1/apps */ export const getApiApiV1Apps = async (args: GetApiApiV1AppsArgs, options?: GetApiApiV1AppsOptions) => { const {baseUrl = "https://cloud-api.phala.com", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.page != null) query.append("page", String(args.page)) if (args.page_size != null) query.append("page_size", String(args.page_size)) if (args.search != null) query.append("search", String(args.search)) for (const item of args.status ?? []) query.append("status", String(item)) if (args.listed != null) query.append("listed", String(args.listed)) if (args.base_image != null) query.append("base_image", String(args.base_image)) if (args.instance_type != null) query.append("instance_type", String(args.instance_type)) for (const item of args.instance_types ?? []) query.append("instance_types", String(item)) if (args.family != null) query.append("family", String(args.family)) if (args.kms_slug != null) query.append("kms_slug", String(args.kms_slug)) if (args.kms_type != null) query.append("kms_type", String(args.kms_type)) if (args.node != null) query.append("node", String(args.node)) if (args.region != null) query.append("region", String(args.region)) if (args.summary_only != null) query.append("summary_only", String(args.summary_only)) const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/apps${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(getApiApiV1AppsResponse, await res.json()) };