import {z} from 'zod' export type AgentKey = {value: unknown, status?: ('certified' | 'undefined') | undefined}; export type NodeSettings = {properties?: Array<{name: string, value: unknown}> | undefined, policyMode?: ('audit' | 'enforce' | 'default') | undefined, state?: ('enabled' | 'ignored' | 'empty-policies' | 'initializing' | 'preparing-eol') | undefined, agentKey?: AgentKey | undefined, documentation?: string | undefined}; export type CreateApiNodesNodeIdArgs = {nodeId: unknown, body: NodeSettings}; export type CreateApiNodesNodeIdOptions = {baseUrl?: string | undefined, APITokens?: string | undefined, fetch?: typeof fetch | undefined}; export const nodeFull = z.object({id: z.string(), hostname: z.string(), status: z.enum(["pending", "accepted", "deleted"]), architectureDescription: z.string().optional(), description: z.string().optional(), ipAddresses: z.array(z.string()), lastRunDate: z.string().optional(), acceptanceDate: z.string().optional(), lastInventoryDate: z.string().optional(), machine: z.object({id: z.string().optional(), type: z.enum(["Physical", "Virtual"]).optional(), provider: z.string().optional(), manufacturer: z.string().optional(), serialNumber: z.string().optional()}).optional(), os: z.object({type: z.enum(["Windows", "Linux"]), name: z.string(), version: z.string(), fullName: z.string(), servicePack: z.string().optional(), kernelVersion: z.string()}).optional(), managementTechnology: z.array(z.object({name: z.string(), version: z.string().optional(), capabilities: z.array(z.string()), nodeKind: z.string(), rootComponents: z.array(z.string()).optional()})), policyServerId: z.string(), properties: z.array(z.object({name: z.string(), value: z.string()})), policyMode: z.enum(["enforce", "audit", "default"]).optional(), ram: z.number().int().optional(), timezone: z.object({name: z.string(), offset: z.string()}).optional(), accounts: z.array(z.string()).optional(), bios: z.object({name: z.string().optional(), version: z.string().optional(), editor: z.string().optional(), quantity: z.number().int().optional(), releaseDate: z.string().optional(), description: z.string().optional()}).optional(), controllers: z.array(z.object({name: z.string().optional(), type: z.string().optional(), quantity: z.number().int().optional(), description: z.string().optional(), manufacturer: z.string().optional()})).optional(), environmentVariables: z.array(z.object({name: z.string().optional(), value: z.string().optional()})).optional(), instanceId: z.string().optional(), fileSystems: z.array(z.object({name: z.string().optional(), mountPoint: z.string().optional(), description: z.string().optional(), fileCount: z.number().int().optional(), freeSpace: z.number().int().optional(), totalSpace: z.number().int().optional()})).optional(), managementTechnologyDetails: z.object({cfengineKeys: z.array(z.string()).optional(), cfengineUser: z.string().optional(), scheduleOverride: z.object({runInterval: z.string().optional(), firstRun: z.string().optional(), splayTime: z.string().optional()}).optional()}).optional(), memories: z.array(z.object({name: z.string().optional(), speed: z.number().int().optional(), type: z.string().optional(), caption: z.string().optional(), quantity: z.number().int().optional(), capacity: z.number().int().optional(), slotNumber: z.number().int().optional(), description: z.string().optional(), serialNumber: z.string().optional()})).optional(), networkInterfaces: z.array(z.object({name: z.string().optional(), mask: z.array(z.string()).optional(), type: z.string().optional(), speed: z.string().optional(), status: z.string().optional(), dhcpServer: z.string().optional(), macAddress: z.string().optional(), ipAddresses: z.array(z.string()).optional()})).optional(), ports: z.array(z.object({name: z.string().optional(), type: z.string().optional(), quantity: z.number().int().optional(), description: z.string().optional()})).optional(), processes: z.array(z.object({pid: z.number().int().optional(), tty: z.string().optional(), name: z.string().optional(), user: z.string().optional(), started: z.string().optional(), memory: z.number().optional(), virtualMemory: z.number().int().optional(), cpuUsage: z.number().int().optional(), description: z.string().optional()})).optional(), processors: z.array(z.object({name: z.string().optional(), arch: z.string().optional(), model: z.number().int().optional(), familyName: z.string().optional(), core: z.number().int().optional(), speed: z.number().int().optional(), thread: z.number().int().optional(), stepping: z.number().int().optional(), manufacturer: z.string().optional(), quantity: z.number().int().optional(), cpuid: z.string().optional(), externalClock: z.string().optional(), description: z.string().optional()})).optional(), slots: z.array(z.object({name: z.string().optional(), status: z.string().optional(), quantity: z.number().int().optional(), description: z.string().optional()})).optional(), software: z.array(z.object({name: z.string().optional(), version: z.string().optional(), editor: z.string().optional(), description: z.string().optional(), releaseDate: z.string().optional(), license: z.object({oem: z.string().optional(), name: z.string().optional(), productId: z.string().optional(), productKey: z.string().optional(), description: z.string().optional(), expirationDate: z.string().optional()}).optional()})).optional(), softwareUpdate: z.array(z.object({name: z.string().optional(), version: z.string().optional(), arch: z.string().optional(), from: z.string().optional(), kind: z.enum(["none", "security", "defect", "enhancement", "other"]).optional(), source: z.string().optional(), description: z.string().optional(), severity: z.enum(["critical", "high", "moderate", "low", "other"]).optional(), ids: z.array(z.string()).optional()})).optional(), sound: z.array(z.object({name: z.string().optional(), quantity: z.number().int().optional(), description: z.string().optional()})).optional(), storage: z.array(z.object({name: z.string().optional(), type: z.string().optional(), size: z.number().int().optional(), model: z.string().optional(), firmware: z.string().optional(), quantity: z.number().int().optional(), description: z.string().optional(), manufacturer: z.string().optional(), serialNumber: z.string().optional()})).optional(), videos: z.array(z.object({name: z.string().optional(), memory: z.string().optional(), chipset: z.string().optional(), quantity: z.number().int().optional(), resolution: z.string().optional(), description: z.string().optional()})).optional(), virtualMachines: z.array(z.object({name: z.string().optional(), type: z.string().optional(), uuid: z.string().optional(), vcpu: z.string().optional(), owner: z.string().optional(), status: z.string().optional(), memory: z.string().optional(), subsystem: z.string().optional(), description: z.string().optional()})).optional()}); export const createApiNodesNodeIdResponse = z.object({result: z.enum(["success", "error"]), action: z.literal("updateNode"), data: z.object({nodes: z.array(nodeFull)})}); 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 }; /** * Update node settings and properties * * POST /nodes/{nodeId} */ export const createApiNodesNodeId = async (args: CreateApiNodesNodeIdArgs, options?: CreateApiNodesNodeIdOptions) => { const {baseUrl = "https://rudder.example.com/rudder/api/latest", fetch: fetchFn = fetch, APITokens} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (APITokens !== undefined) headers.set("X-API-Token", APITokens) const url = `${baseUrl.replace(/\/+$/, '')}/nodes/${encodeURIComponent(String(args.nodeId))}${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(createApiNodesNodeIdResponse, await res.json()) };