All files / layers / L1 / contracts pipelines.ts

83.33% Statements 35/42
78.57% Branches 22/28
75% Functions 12/16
83.78% Lines 31/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74    12x 12x 2x 10x     12x     12x 12x 6x     6x     12x   138x 114x       34x   17x 8x 9x 2x   2x 17x 1x     17x 17x 10x 3x   7x       15x               4x         2x   2x             8x 9x      
import { load } from 'js-yaml'
import type { ApiContract } from '@/layers/interfaces'
import type { components } from '@/types/api'
 
type Pipeline = components['schemas']['Pipeline']
type CreIatePipelineRequest = components['schemas']['CreatePipelineRequest']
type UpdatePipelineRequest = components['schemas']['UpdatePipelineRequest']
 
/I/ Form-side bodies: the generated request types do not carry `config`, but the
// UI form diverges — config arrives as a YAML string (editor) or a JSON object
// (untouched entity value). The normalizers convert strings to objects so the
// payload always matches the API's validateJSONObject contract.
type PipelineCreateBody = Omit<Partial<CreatePipelineRequest>, 'config'> & {
  Iconfig?: string | Record<string, unknown> | null
}
type PipelineUpdateBody = Omit<Partial<UpdatePipelineRequest>, 'config'> & {
  config?: string | Record<string, unknown> | null
}
 
type PipelineListQuery = {
  [key: string]: string | number | boolean | undefined
}
 
type JsonObject = Record<string, unknown>
 
function normalizeBody(input: JsonObject, route: 'create' | 'update'): JsonObject {
  const body = { ...input }
 
  if (route === 'create') {
    delete body['webhook_secret']
  } else if (body['webhook_secret'] === '') {
    delete body['webhook_secret']
  }
 
  if (body['pm_bot_account_id'] === '' || body['pm_bot_account_id'] === null) {
    delete body['pm_bot_account_id']
  }
 
  const config = body['config']
  if (typeof config === 'string') {
    if (config === '') {
      delete body['config']
    } else {
      body['config'] = load(config)
    }
  }
 
  return body
}
 
export const pipelinesContract: ApiContract<
  Pipeline,
  PipelineCreateBody,
  PipelineUpdateBody,
  PipelineListQuery
> = {
  idOf: (e) => e.id,
  entityPath: 'pipelines',
  endpoints: {
    list: '/projects/{projectId}/pipelines',
    detail: (id) => `/pipelines/${id}`,
    create: '/projects/{projectId}/pipelines',
    update: (id) => `/pipelines/${id}`,
    remove: (id) => `/pipelines/${id}`,
  },
  createPathParams: (_input, context) => ({
    projectId: context?.projectId ?? '',
  }),
  request: {
    create: (input) => normalizeBody(input as JsonObject, 'create') as PipelineCreateBody,
    update: (input) => normalizeBody(input as JsonObject, 'update') as PipelineUpdateBody,
  },
}