All files / shared / utils schemaHelp.ts

100% Statements 34/34
90.32% Branches 28/31
100% Functions 7/7
100% Lines 26/26

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                  43x       11x 11x 11x 11x   11x 11x 2x 2x 1x 1x     2x 3x 3x 2x     11x       11x 8x 11x   6x 6x 1x 1x       6x 10x 8x    
import type { ConfigSchemaHelpNode } from '@/layers/interfaces'
 
// Converts a fetched config JSON Schema document (draft-07, e.g. the API's
// GET /api/v1/config-schemas/pipeline response) into the help tree consumed
// by YamlEditor. Every property becomes a node; object-typed properties get
// their children recursed (required marks come from each level's `required`
// array). Malformed input yields an empty result.
 
function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
}
 
function nodeForKey(key: string, schema: Record<string, unknown>, required: Set<string>): ConfigSchemaHelpNode {
  const node: ConfigSchemaHelpNode = { key }
  if (typeof schema.title === 'string') node.title = schema.title
  if (typeof schema.description === 'string') node.description = schema.description
  if (required.has(key)) node.required = true
 
  const properties = isRecord(schema.properties) ? schema.properties : undefined
  if (schema.type === 'object' && properties) {
    const childRequired = new Set<string>()
    if (Array.isArray(schema.required)) {
      for (const name of schema.required) {
        Eif (typeof name === 'string') childRequired.add(name)
      }
    }
    const children = Object.entries(properties)
      .filter((entry): entry is [string, Record<string, unknown>] => isRecord(entry[1]))
      .map(([childKey, child]) => nodeForKey(childKey, child, childRequired))
    Eif (children.length > 0) node.children = children
  }
 
  return node
}
 
export function schemaToHelp(schema: unknown): ConfigSchemaHelpNode[] {
  if (!isRecord(schema)) return []
  const properties = isRecord(schema.properties) ? schema.properties : undefined
  if (!properties) return []
 
  const required = new Set<string>()
  if (Array.isArray(schema.required)) {
    for (const name of schema.required) {
      Eif (typeof name === 'string') required.add(name)
    }
  }
 
  return Object.entries(properties)
    .filter((entry): entry is [string, Record<string, unknown>] => isRecord(entry[1]))
    .map(([key, child]) => nodeForKey(key, child, required))
}