import {z} from 'zod' export type GetApiApiV30OrgsOrgUuidScansCompareArgs = {orgUuid: string, sourceScanUuid: string, targetScanUuid?: string | undefined, type: 'security' | 'legal' | 'library' | 'ai_inventory'}; export type GetApiApiV30OrgsOrgUuidScansCompareOptions = {baseUrl?: string | undefined, bearerKey?: string | undefined, fetch?: typeof fetch | undefined}; export const scanAgentInfo = z.object({agentName: z.string().optional(), agentVersion: z.string().optional(), errorMessage: z.string().optional()}); export const progressDTO = z.object({overallPercentage: z.number().int().gte(0).lte(100), currentStage: z.string().max(255)}); export const scanDTOV3 = z.object({uuid: z.string().optional(), name: z.string().optional(), engine: z.enum(["UNIFIED", "SCA", "SAST", "IAC", "IMG", "AI", "DAST"]).optional(), status: z.enum(["RUNNING", "PARTIAL", "PROCESSING", "FINISHED", "FAILED"]).optional(), projectId: z.number().int().optional(), productId: z.number().int().optional(), domainId: z.number().int().optional(), projectUuid: z.string().optional(), processUuid: z.string().optional(), hasViolations: z.boolean().optional(), startTime: z.string().optional(), endTime: z.string().optional(), lastModified: z.string().optional(), configurationName: z.string().optional(), reference: z.string().optional(), triggeredBy: z.string().optional(), agentInfo: scanAgentInfo.optional(), progress: progressDTO.optional()}); export const scanDiffStatsDTOV3 = z.object({added: z.number().int().optional(), removed: z.number().int().optional(), modified: z.number().int().optional(), unchanged: z.number().int().optional()}); export const suppressMetadataDTO = z.object({reason: z.string().optional(), comment: z.string().optional(), userEmail: z.string().optional(), userUuid: z.string().optional(), updatedAt: z.string().optional()}); export const unifiedFindingDTOV3 = z.object({uuid: z.string().optional(), findingId: z.string().optional(), findingName: z.string().optional(), type: z.string().optional(), severity: z.string().optional(), score: z.number().optional(), element: z.string().optional(), elementId: z.string().optional(), refId: z.string().optional(), grouping: z.string().optional(), status: z.string().optional(), state: z.string().optional(), suppressMetadata: suppressMetadataDTO.optional(), paths: z.array(z.string()).optional(), sources: z.array(z.string()).optional(), createdAt: z.string().optional(), updatedAt: z.string().optional(), dynamicFields: z.record(z.string(), z.object({})).optional(), riskFactors: z.array(z.string()).optional(), riskFactorsJson: z.record(z.string(), z.object({})).optional(), engine: z.enum(["UNIFIED", "SCA", "SAST", "IAC", "IMG", "AI", "DAST"]).optional(), vendor: z.string().optional(), orgUuid: z.string().optional(), projectUuid: z.string().optional(), projectName: z.string().optional(), branch: z.string().optional(), scanUuid: z.string().optional(), firstScanUuid: z.string().optional(), findingCategory: z.string().optional(), hasViolation: z.boolean().optional(), numberOfViolations: z.number().int().optional(), violationWorkflowUuids: z.array(z.string()).optional(), applicationUuid: z.string().optional(), applicationName: z.string().optional(), isNew: z.boolean().optional(), isDetectedAtFirstScan: z.boolean().optional(), isRemediationAvailable: z.boolean().optional()}); export const diffChangeDTOV3 = z.object({field: z.string().optional(), before: z.object({}).optional(), after: z.object({}).optional()}); export const diffUnifiedFindingDTOV3 = z.object({diffType: z.string().optional(), finding: unifiedFindingDTOV3.optional(), changes: z.array(diffChangeDTOV3).optional()}); export const scanDiffResponseDTOV3 = z.object({source: scanDTOV3.optional(), target: scanDTOV3.optional(), stats: scanDiffStatsDTOV3.optional(), findings: z.array(diffUnifiedFindingDTOV3).optional()}); export const dWRResponseV3ScanDiffResponseDTOV3 = z.object({supportToken: z.string().optional(), response: scanDiffResponseDTOV3.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 }; /** * Get Scans Comparison * * GET /api/v3.0/orgs/{orgUuid}/scans/compare */ export const getApiApiV30OrgsOrgUuidScansCompare = async (args: GetApiApiV30OrgsOrgUuidScansCompareArgs, options?: GetApiApiV30OrgsOrgUuidScansCompareOptions) => { const {baseUrl = "https://baseUrl", fetch: fetchFn = fetch, bearerKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.sourceScanUuid != null) query.append("sourceScanUuid", String(args.sourceScanUuid)) if (args.targetScanUuid != null) query.append("targetScanUuid", String(args.targetScanUuid)) if (args.type != null) query.append("type", String(args.type)) if (bearerKey !== undefined) headers.set('authorization', `Bearer ${bearerKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/v3.0/orgs/${encodeURIComponent(String(args.orgUuid))}/scans/compare${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(dWRResponseV3ScanDiffResponseDTOV3, await res.json()) };