import type { OpenCollectionRoot, AuthConfig, HeaderItem, VarItem } from '../types.js' const INDENT = ' ' function dictBlock(name: string, entries: string[]): string { if (entries.length === 0) return `${name} {\n}\n` return `${name} {\n${entries.map(e => `${INDENT}${e}`).join('\n')}\n}\n` } function textBlock(name: string, content: string): string { const trimmed = content.trimEnd() return `${name} {\n${trimmed.split('\n').map(l => `${INDENT}${l}`).join('\n')}\n}\n` } function quoteKey(key: string): string { if (/[:{}"' ]/.test(key)) return `"${key.replace(/"/g, '\\"')}"` return key } function formatHeaders(headers: HeaderItem[]): string { const entries = headers.map(h => { const prefix = h.disabled ? '~' : '' return `${prefix}${quoteKey(h.name)}: ${h.value}` }) return dictBlock('headers', entries) } function formatAuthBlock(auth: AuthConfig): string { const type = auth.type if (type === 'none') return '' let out = dictBlock('auth', [`mode: ${type}`]) if (type === 'basic' && auth.basic) { out += '\n' + dictBlock('auth:basic', [ `username: ${auth.basic.username}`, `password: ${auth.basic.password}`, ]) } else if (type === 'bearer' && auth.bearer) { out += '\n' + dictBlock('auth:bearer', [`token: ${auth.bearer.token}`]) } else if (type === 'apikey' && auth.apikey) { out += '\n' + dictBlock('auth:apikey', [ `key: ${auth.apikey.key}`, `value: ${auth.apikey.value}`, `placement: ${auth.apikey.placement}`, ]) } else if (type === 'oauth2' && auth.oauth2) { const entries = Object.entries(auth.oauth2).map(([k, v]) => `${k}: ${String(v)}`) out += '\n' + dictBlock('auth:oauth2', entries) } return out } function formatVars(blockName: string, vars: VarItem[]): string { if (vars.length === 0) return '' const entries = vars.map(v => { const disabled = v.enabled === false ? '~' : '' const local = v.local ? '@' : '' return `${disabled}${local}${v.name}: ${v.value}` }) return dictBlock(blockName, entries) } export function formatCollectionBru(root: OpenCollectionRoot): string { const parts: string[] = [] const req = root.request if (req?.headers && req.headers.length > 0) { parts.push(formatHeaders(req.headers)) } if (req?.auth) { const authStr = formatAuthBlock(req.auth) if (authStr) parts.push(authStr) } if (req?.vars?.req && req.vars.req.length > 0) { parts.push(formatVars('vars:pre-request', req.vars.req)) } if (req?.vars?.res && req.vars.res.length > 0) { parts.push(formatVars('vars:post-response', req.vars.res)) } if (req?.script?.req) parts.push(textBlock('script:pre-request', req.script.req)) if (req?.script?.res) parts.push(textBlock('script:post-response', req.script.res)) if (req?.tests) parts.push(textBlock('tests', req.tests)) return parts.join('\n') } export function formatBrunoJson(root: OpenCollectionRoot): string { const manifest: Record = { version: '1', name: root.info.name, type: 'collection', } const ignore = root.extensions?.bruno?.ignore if (ignore && ignore.length > 0) { manifest.ignore = ignore } else { manifest.ignore = ['node_modules', '.git'] } if (root.config?.proxy) { const p = root.config.proxy manifest.proxy = { enabled: p.hostname ? true : false, protocol: p.protocol ?? 'http', hostname: p.hostname ?? '', port: p.port ? Number(p.port) : 8080, auth: { enabled: Boolean(p.auth?.username), username: p.auth?.username ?? '', password: p.auth?.password ?? '', }, bypassProxy: p.bypassProxy ?? '', } } return JSON.stringify(manifest, null, 2) }