import {z} from 'zod' export type UpdateApiAppsAppIdContainersContainerIdEnvArgs = {appId: string, containerId: string, body: {[key: string]: string}}; export type UpdateApiAppsAppIdContainersContainerIdEnvOptions = {baseUrl?: string | undefined, AccessKey?: string | undefined, fetch?: typeof fetch | undefined}; export const imagePullPolicy = z.enum(["always", "ifNotPresent"]); export const containerEntryPoint = z.object({command: z.string().nullable().optional(), commandArray: z.array(z.string()).nullable().optional(), arguments: z.string().nullable().optional(), argumentsArray: z.array(z.string()).nullable().optional(), workingDirectory: z.string().nullable().optional()}); export const httpGetProbeRequestDetails = z.object({path: z.string().optional(), portNumber: z.number().int().gte(1).lte(65535).optional()}); export const httpStatusCode = z.enum(["continue", "switchingProtocols", "processing", "earlyHints", "ok", "created", "accepted", "nonAuthoritativeInformation", "noContent", "resetContent", "partialContent", "multiStatus", "alreadyReported", "imUsed", "multipleChoices", "movedPermanently", "found", "seeOther", "notModified", "useProxy", "unused", "temporaryRedirect", "permanentRedirect", "badRequest", "unauthorized", "paymentRequired", "forbidden", "notFound", "methodNotAllowed", "notAcceptable", "proxyAuthenticationRequired", "requestTimeout", "conflict", "gone", "lengthRequired", "preconditionFailed", "requestEntityTooLarge", "requestUriTooLong", "unsupportedMediaType", "requestedRangeNotSatisfiable", "expectationFailed", "misdirectedRequest", "unprocessableEntity", "locked", "failedDependency", "upgradeRequired", "preconditionRequired", "tooManyRequests", "requestHeaderFieldsTooLarge", "unavailableForLegalReasons", "internalServerError", "notImplemented", "badGateway", "serviceUnavailable", "gatewayTimeout", "httpVersionNotSupported", "variantAlsoNegotiates", "insufficientStorage", "loopDetected", "notExtended", "networkAuthenticationRequired"]); export const httpGetProbeResponseDetails = z.object({expectedStatusCode: httpStatusCode.optional()}); export const httpGetProbe = z.object({request: httpGetProbeRequestDetails.optional(), response: httpGetProbeResponseDetails.optional()}); export const tcpSocketProbeRequestDetails = z.object({portNumber: z.number().int().gte(1).lte(65535).optional()}); export const tcpSocketProbe = z.object({request: tcpSocketProbeRequestDetails.optional()}); export const grpcProbeRequestDetails = z.object({portNumber: z.number().int().gte(1).lte(65535).optional(), serviceName: z.string().nullable().optional()}); export const grpcProbe = z.object({request: grpcProbeRequestDetails.optional()}); export const containerProbe = z.object({initialDelaySeconds: z.number().int().gte(1).lte(3600).nullable().optional(), periodSeconds: z.number().int().gte(1).lte(3600).nullable().optional(), timeoutSeconds: z.number().int().gte(1).lte(3600).nullable().optional(), failureThreshold: z.number().int().gte(1).lte(1000).nullable().optional(), successThreshold: z.number().int().gte(1).lte(1000).nullable().optional(), httpGet: httpGetProbe.optional(), tcpSocket: tcpSocketProbe.optional(), grpc: grpcProbe.optional()}); export const containerProbes = z.object({startup: containerProbe.optional(), readiness: containerProbe.optional(), liveness: containerProbe.optional()}); export const environmentVariable = z.object({name: z.string().min(1), value: z.string().optional()}); export const endpointType = z.enum(["cdn", "anycast", "publicIp"]); export const protocolV3 = z.enum(["tcp", "udp", "sctp"]); export const endpointPortMapping = z.object({containerPort: z.number().int(), exposedPort: z.number().int(), protocols: z.array(protocolV3)}); export const endpointStickySession = z.object({enabled: z.boolean(), sessionHeaders: z.array(z.string()), cookieName: z.string().min(1)}); export const endpointInternalIp = z.object({address: z.string().min(1), region: z.string().min(1)}); export const containerEndpoint = z.object({id: z.string().min(1), displayName: z.string().min(1), publicHost: z.string().min(1), type: endpointType, isSslEnabled: z.boolean(), pullZoneId: z.string().min(1), portMappings: z.array(endpointPortMapping), stickySessions: endpointStickySession.optional(), internalIpAddresses: z.array(endpointInternalIp).nullable().optional(), publicIpAddresses: z.array(endpointInternalIp).nullable().optional()}); export const containerVolumeMount = z.object({name: z.string().min(1), mountPath: z.string().min(1)}); export const containerTemplate = z.object({id: z.string().min(1), name: z.string().min(1), packageId: z.string().min(1), image: z.string().min(1), imageName: z.string().min(1), imageNamespace: z.string().min(1), imageTag: z.string().min(1), imageRegistryId: z.string().min(1), imageDigest: z.string().min(1), imagePullPolicy: imagePullPolicy, entryPoint: containerEntryPoint, probes: containerProbes, environmentVariables: z.array(environmentVariable), endpoints: z.array(containerEndpoint), volumeMounts: z.array(containerVolumeMount)}); 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 }; /** * Set Container Environment Variables * * PUT /apps/{appId}/containers/{containerId}/env */ export const updateApiAppsAppIdContainersContainerIdEnv = async (args: UpdateApiAppsAppIdContainersContainerIdEnvArgs, options?: UpdateApiAppsAppIdContainersContainerIdEnvOptions) => { const {baseUrl = "https://api.bunny.net/mc", fetch: fetchFn = fetch, AccessKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (AccessKey !== undefined) headers.set("AccessKey", AccessKey) const url = `${baseUrl.replace(/\/+$/, '')}/apps/${encodeURIComponent(String(args.appId))}/containers/${encodeURIComponent(String(args.containerId))}/env${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "PUT", 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(containerTemplate, await res.json()) };