/** * cli:publish-api-contract — validate.ts */ import { existsSync } from 'node:fs' import { resolve } from 'node:path' import { PublishApiContractInputSchema, type ValidationResult } from './types.js' export function validate(raw: unknown): ValidationResult { const parsed = PublishApiContractInputSchema.safeParse(raw) if (!parsed.success) { return { valid: false, errors: parsed.error.issues.map(i => `[${i.path.join('.')}] ${i.message}`), warnings: [], } } const spec = parsed.data const errors: string[] = [] const warnings: string[] = [] if (!existsSync(resolve(spec.projectPath))) { errors.push(`projectPath does not exist: ${spec.projectPath}`) } if (spec.allowBreaking && spec.mode === 'write') { warnings.push('allowBreaking is set: a change that breaks an existing integration will be published under the SAME version. Only do this when nobody consumes the contract yet.') } if (spec.baseUrl.includes('{host}')) { warnings.push('baseUrl still carries the {host} placeholder — the third party cannot call the API from the contract as published.') } return { valid: errors.length === 0, errors, warnings } }