// Minimal YAML emitter for action results (objects, arrays, scalars). // Output only; parsing is done by the vendored yaml package (see source.mjs). const PLAIN = /^[A-Za-z0-9_./@+-][A-Za-z0-9_ ./@+:-]*$/; const RESERVED = /^(true|false|null|yes|no|on|off|~|-?\d+(\.\d+)?)$/i; function scalar(value) { if (value === null || value === undefined) return 'null'; if (typeof value === 'boolean' || typeof value === 'number') return String(value); const text = String(value); if (text === '' || !PLAIN.test(text) || RESERVED.test(text) || text.endsWith(':') || text.includes(': ') || text.includes(' #')) { return JSON.stringify(text); } return text; } function isEmpty(value) { return (Array.isArray(value) && value.length === 0) || (value && typeof value === 'object' && Object.keys(value).length === 0); } function emit(value, indent) { const pad = ' '.repeat(indent); if (Array.isArray(value)) { return value .map((item) => { if (item && typeof item === 'object' && !isEmpty(item)) { const body = emit(item, indent + 2); return `${pad}- ${body.slice(indent + 2)}`; } return `${pad}- ${isEmpty(item) ? (Array.isArray(item) ? '[]' : '{}') : scalar(item)}`; }) .join('\n'); } return Object.entries(value) .filter(([, item]) => item !== undefined) .map(([key, item]) => { if (item && typeof item === 'object' && !isEmpty(item)) return `${pad}${key}:\n${emit(item, indent + 2)}`; if (isEmpty(item)) return `${pad}${key}: ${Array.isArray(item) ? '[]' : '{}'}`; return `${pad}${key}: ${scalar(item)}`; }) .join('\n'); } export function toYaml(value) { return `${emit(value, 0)}\n`; }