import {z} from 'zod' export type GetApiApiV1DeploymentsDeploymentSlugFindingsArgs = {deploymentSlug: string, issue_type?: ('sast' | 'sca' | 'ai_sast') | undefined, since?: number | undefined, page?: number | undefined, dedup?: boolean | undefined, page_size?: number | undefined, repos?: Array | undefined, repository_ids?: Array | undefined, status?: ('open' | 'fixed' | 'ignored' | 'reviewing' | 'fixing' | 'provisionally_ignored') | undefined, triage_reasons?: Array | undefined, severities?: Array | undefined, ref?: string | undefined, policies?: Array | undefined, rules?: Array | undefined, categories?: Array | undefined, confidence?: ('low' | 'medium' | 'high') | undefined, autotriage_verdict?: ('true_positive' | 'false_positive') | undefined, component_tags?: Array | undefined, exposures?: Array | undefined, transitivities?: Array | undefined, is_malicious?: boolean | undefined, click_to_fix_pr_state?: Array | undefined}; export type GetApiApiV1DeploymentsDeploymentSlugFindingsOptions = {baseUrl: string, SemgrepWebToken?: string | undefined, fetch?: typeof fetch | undefined}; export const protosOpenapiV1AssistantAutofix = z.object({explanation: z.string().optional(), fix_code: z.string().optional()}); export const protosOpenapiV1AssistantAutotriage = z.object({reason: z.string().optional(), verdict: z.enum(["false_positive", "true_positive"]).optional()}); export const protosOpenapiV1AssistantComponent = z.object({risk: z.enum(["high", "low", "neutral"]).optional(), tag: z.string().optional()}); export const protosOpenapiV1AssistantGuidance = z.object({instructions: z.string().optional(), summary: z.string().optional()}); export const protosOpenapiV1AssistantRuleExplanation = z.object({explanation: z.string().optional(), summary: z.string().optional()}); export const protosOpenapiV1SastFindingAssistant = z.object({autofix: protosOpenapiV1AssistantAutofix.optional(), autotriage: protosOpenapiV1AssistantAutotriage.optional(), component: protosOpenapiV1AssistantComponent.optional(), guidance: protosOpenapiV1AssistantGuidance.optional(), rule_explanation: protosOpenapiV1AssistantRuleExplanation.optional()}); export const protosOpenapiV1SastFindingClickToFixFailure = z.object({created_at: z.string().optional(), reason: z.string().optional()}); export const protosOpenapiV1SastFindingClickToFixPr = z.object({created_at: z.string().optional(), url: z.string().optional()}); export const protosOpenapiV1ExternalTicket = z.object({external_slug: z.string().optional(), id: z.number().int().optional(), linked_issue_ids: z.array(z.number().int()).optional(), url: z.string().optional()}); export const protosOpenapiV1FindingLocation = z.object({column: z.number().int().optional(), end_column: z.number().int().optional(), end_line: z.number().int().optional(), file_path: z.string().optional(), line: z.number().int().optional()}); export const protosOpenapiV1FindingRepository = z.object({name: z.string().optional(), url: z.string().optional()}); export const protosOpenapiV1ReviewComment = z.object({external_discussion_id: z.string().optional(), external_note_id: z.string().optional()}); export const protosOpenapiV1FindingRule = z.object({category: z.string().optional(), confidence: z.enum(["low", "medium", "high"]).optional(), cwe_names: z.array(z.string()).optional(), message: z.string().optional(), name: z.string().optional(), owasp_names: z.array(z.string()).optional(), subcategories: z.array(z.string()).optional(), vulnerability_classes: z.array(z.string()).optional()}); export const protosOpenapiV1SastFindingPolicyReference = z.object({id: z.number().int().optional(), name: z.string().optional(), slug: z.string().optional()}); export const protosOpenapiV1SastFinding = z.object({assistant: protosOpenapiV1SastFindingAssistant.optional(), categories: z.array(z.string()).optional(), click_to_fix_failures: z.array(protosOpenapiV1SastFindingClickToFixFailure).optional(), click_to_fix_prs: z.array(protosOpenapiV1SastFindingClickToFixPr).optional(), confidence: z.enum(["low", "medium", "high"]).optional(), created_at: z.string().optional(), external_ticket: protosOpenapiV1ExternalTicket.optional(), first_seen_scan_id: z.number().int().optional(), id: z.number().int().optional(), line_of_code_url: z.string().optional(), location: protosOpenapiV1FindingLocation.optional(), match_based_id: z.string().optional(), ref: z.string().optional(), relevant_since: z.string().optional(), repository: protosOpenapiV1FindingRepository.optional(), review_comments: z.array(protosOpenapiV1ReviewComment).optional(), rule: protosOpenapiV1FindingRule.optional(), rule_message: z.string().optional(), rule_name: z.string().optional(), severity: z.enum(["low", "medium", "high", "critical"]).optional(), sourcing_policy: protosOpenapiV1SastFindingPolicyReference.optional(), state: z.enum(["fixed", "muted", "unresolved"]).optional(), state_updated_at: z.string().optional(), status: z.enum(["open", "fixed", "ignored", "reviewing", "fixing", "provisionally_ignored"]).optional(), syntactic_id: z.string().optional(), triage_comment: z.string().optional(), triage_reason: z.enum(["acceptable_risk", "false_positive", "no_time", "no_triage_reason", "duplicate"]).optional(), triage_state: z.enum(["untriaged", "ignored", "reopened", "reviewing", "fixing", "provisionally_ignored"]).optional(), triaged_at: z.string().optional()}); export const protosOpenapiV1ScaFindingEpssScore = z.object({percentile: z.number().optional(), score: z.number().optional()}); export const protosOpenapiV1ScaFindingFixRecommendation = z.object({package: z.string().optional(), version: z.string().optional()}); export const protosOpenapiV1ScaFindingFoundDependency = z.object({ecosystem: z.enum(["no_package_manager", "npm", "pypi", "gomod", "cargo", "maven", "gem", "composer", "nuget", "pub", "swiftpm", "hex"]).optional(), lockfile_line_url: z.string().optional(), package: z.string().optional(), transitivity: z.enum(["direct", "transitive", "unknown"]).optional(), version: z.string().optional()}); export const protosOpenapiV1ScaFindingUsage = z.object({external_ticket: protosOpenapiV1ExternalTicket.optional(), location: protosOpenapiV1FindingLocation.optional()}); export const protosOpenapiV1ScaFinding = z.object({categories: z.array(z.string()).optional(), confidence: z.enum(["low", "medium", "high"]).optional(), created_at: z.string().optional(), epss_score: protosOpenapiV1ScaFindingEpssScore.optional(), external_ticket: protosOpenapiV1ExternalTicket.optional(), first_seen_scan_id: z.number().int().optional(), fix_recommendations: z.array(protosOpenapiV1ScaFindingFixRecommendation).optional(), found_dependency: protosOpenapiV1ScaFindingFoundDependency.optional(), id: z.number().int().optional(), is_malicious: z.boolean().optional(), line_of_code_url: z.string().optional(), location: protosOpenapiV1FindingLocation.optional(), match_based_id: z.string().optional(), reachability: z.enum(["no reachability analysis", "reachable", "always reachable", "conditionally reachable", "unreachable"]).optional(), reachable_condition: z.string().optional(), ref: z.string().optional(), relevant_since: z.string().optional(), repository: protosOpenapiV1FindingRepository.optional(), review_comments: z.array(protosOpenapiV1ReviewComment).optional(), rule: protosOpenapiV1FindingRule.optional(), rule_message: z.string().optional(), rule_name: z.string().optional(), severity: z.enum(["low", "medium", "high", "critical"]).optional(), state: z.enum(["fixed", "muted", "unresolved"]).optional(), state_updated_at: z.string().optional(), status: z.enum(["open", "fixed", "ignored", "reviewing", "fixing", "provisionally_ignored"]).optional(), syntactic_id: z.string().optional(), triage_comment: z.string().optional(), triage_reason: z.enum(["acceptable_risk", "false_positive", "no_time", "no_triage_reason", "duplicate"]).optional(), triage_state: z.enum(["untriaged", "ignored", "reopened", "reviewing", "fixing", "provisionally_ignored"]).optional(), triaged_at: z.string().optional(), usage: protosOpenapiV1ScaFindingUsage.optional(), vulnerability_identifier: z.string().optional()}); export const protosOpenapiV1AiSastFinding = z.object({ai_impact: z.string().optional(), assistant: protosOpenapiV1SastFindingAssistant.optional(), click_to_fix_failures: z.array(protosOpenapiV1SastFindingClickToFixFailure).optional(), click_to_fix_prs: z.array(protosOpenapiV1SastFindingClickToFixPr).optional(), confidence: z.enum(["low", "medium", "high"]).optional(), created_at: z.string().optional(), external_ticket: protosOpenapiV1ExternalTicket.optional(), first_seen_scan_id: z.number().int().optional(), id: z.number().int().optional(), line_of_code_url: z.string().optional(), location: protosOpenapiV1FindingLocation.optional(), match_based_id: z.string().optional(), ref: z.string().optional(), relevant_since: z.string().optional(), repository: protosOpenapiV1FindingRepository.optional(), review_comments: z.array(protosOpenapiV1ReviewComment).optional(), rule: protosOpenapiV1FindingRule.optional(), rule_message: z.string().optional(), rule_name: z.string().optional(), severity: z.enum(["low", "medium", "high", "critical"]).optional(), sourcing_policy: protosOpenapiV1SastFindingPolicyReference.optional(), state: z.enum(["fixed", "muted", "unresolved"]).optional(), state_updated_at: z.string().optional(), status: z.enum(["open", "fixed", "ignored", "reviewing", "fixing", "provisionally_ignored"]).optional(), syntactic_id: z.string().optional(), triage_comment: z.string().optional(), triage_reason: z.enum(["acceptable_risk", "false_positive", "no_time", "no_triage_reason", "duplicate"]).optional(), triage_state: z.enum(["untriaged", "ignored", "reopened", "reviewing", "fixing", "provisionally_ignored"]).optional(), triaged_at: z.string().optional()}); export const getApiApiV1DeploymentsDeploymentSlugFindingsResponse = z.object({findings: z.array(z.union([protosOpenapiV1SastFinding, protosOpenapiV1ScaFinding, protosOpenapiV1AiSastFinding])).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 }; /** * List code, supply chain, or AI-powered scan findings * * GET /api/v1/deployments/{deploymentSlug}/findings */ export const getApiApiV1DeploymentsDeploymentSlugFindings = async (args: GetApiApiV1DeploymentsDeploymentSlugFindingsArgs, options: GetApiApiV1DeploymentsDeploymentSlugFindingsOptions) => { const {baseUrl, fetch: fetchFn = fetch, SemgrepWebToken} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.issue_type != null) query.append("issue_type", String(args.issue_type)) if (args.since != null) query.append("since", String(args.since)) if (args.page != null) query.append("page", String(args.page)) if (args.dedup != null) query.append("dedup", String(args.dedup)) if (args.page_size != null) query.append("page_size", String(args.page_size)) for (const item of args.repos ?? []) query.append("repos", String(item)) for (const item of args.repository_ids ?? []) query.append("repository_ids", String(item)) if (args.status != null) query.append("status", String(args.status)) for (const item of args.triage_reasons ?? []) query.append("triage_reasons", String(item)) for (const item of args.severities ?? []) query.append("severities", String(item)) if (args.ref != null) query.append("ref", String(args.ref)) for (const item of args.policies ?? []) query.append("policies", String(item)) for (const item of args.rules ?? []) query.append("rules", String(item)) for (const item of args.categories ?? []) query.append("categories", String(item)) if (args.confidence != null) query.append("confidence", String(args.confidence)) if (args.autotriage_verdict != null) query.append("autotriage_verdict", String(args.autotriage_verdict)) for (const item of args.component_tags ?? []) query.append("component_tags", String(item)) for (const item of args.exposures ?? []) query.append("exposures", String(item)) for (const item of args.transitivities ?? []) query.append("transitivities", String(item)) if (args.is_malicious != null) query.append("is_malicious", String(args.is_malicious)) for (const item of args.click_to_fix_pr_state ?? []) query.append("click_to_fix_pr_state", String(item)) if (SemgrepWebToken !== undefined) headers.set('authorization', `Bearer ${SemgrepWebToken}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/deployments/${encodeURIComponent(String(args.deploymentSlug))}/findings${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(getApiApiV1DeploymentsDeploymentSlugFindingsResponse, await res.json()) };