@seamapi/blueprint
Version:
Build tools for the Seam API using this blueprint.
78 lines (63 loc) • 2.56 kB
text/typescript
import { camelCase, pascalCase } from 'change-case'
import type { Json, NonNullJson } from 'lib/json.js'
import type { CodeSampleContext, CodeSampleDefinition } from './code-sample.js'
import { createJsonResponse } from './json.js'
interface JavaRequestBuilderOptions {
path: string
parameters: NonNullJson
}
export const createJavaRequest = (
{ request }: CodeSampleDefinition,
_context: CodeSampleContext,
): string => {
const pathParts = request.path.split('/').slice(1)
const requestBuilderOptions: JavaRequestBuilderOptions = {
path: request.path,
parameters: request.parameters,
}
const clientArgs = createJavaRequestBuilder(requestBuilderOptions)
return `seam.${pathParts.map((p) => camelCase(p)).join('().')}(${clientArgs});`
}
const createJavaRequestBuilder = ({
path,
parameters,
}: JavaRequestBuilderOptions): string => {
const requestBuilderName = getRequestBuilderName(path)
const isReqWithParams = Object.keys(parameters).length !== 0
if (!isReqWithParams) return ''
const formattedParams = formatJavaArgs(parameters)
return `${requestBuilderName}.builder()${formattedParams}.build()`
}
const getRequestBuilderName = (path: string): string => {
const requestBuilderNameSuffix = 'Request'
const pathParts = path.split('/').slice(1)
return isPathNested(pathParts)
? `${pascalCase(pathParts.slice(1).join('_'))}${requestBuilderNameSuffix}`
: `${pascalCase(path)}${requestBuilderNameSuffix}`
}
const isPathNested = (pathParts: string[]): boolean => pathParts.length > 2
const formatJavaArgs = (jsonParams: NonNullJson): string =>
Object.entries(jsonParams as Record<string, Json>)
.map(([paramKey, paramValue]) => {
const formattedValue = formatJavaValue(paramValue)
return `.${camelCase(paramKey)}(${formattedValue})`
})
.join('\n')
const formatJavaValue = (value: Json): string => {
if (value === null) return 'null'
if (typeof value === 'boolean') return value.toString()
if (typeof value === 'number') return value.toString()
if (typeof value === 'string') return `"${value}"`
if (Array.isArray(value)) {
const formattedItems = value.map(formatJavaValue).join(', ')
return `List.of(${formattedItems})`
}
if (typeof value === 'object') {
const formattedEntries = Object.entries(value)
.map(([key, val]) => `"${key}", ${formatJavaValue(val)}`)
.join(', ')
return `Map.of(${formattedEntries})`
}
throw new Error(`Unsupported type: ${typeof value}`)
}
export const createJavaResponse = createJsonResponse