diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index da769cb..1686a33 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -2,7 +2,7 @@ name: Node Tests CI on: push: branches: - - '*' # Trigger on all branches + - main pull_request: branches: - '*' # Trigger on all branches diff --git a/CHANGELOG.md b/CHANGELOG.md index e77915e..ed644ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## unreleased +## [1.30.1] - 2026-03-26 + +- CLI: Fix normalize YAML block scalar newlines (#202) + ## [1.30.0] - 2026-03-16 - Overlay: add OpenAPI Overlay 1.1.0 support diff --git a/test/test.js b/test/test.js index 65aedc2..8f87133 100644 --- a/test/test.js +++ b/test/test.js @@ -16,7 +16,7 @@ const tests = !localTesting ? fs.readdirSync(__dirname).filter(file => { return fs.statSync(path.join(__dirname, file)).isDirectory() && !file.startsWith('_'); }) - : ['yaml-filter-inverse-flags-stripFlags']; + : ['yaml-default-newline']; describe('openapi-format tests', () => { let consoleLogSpy, consoleWarnSpy; diff --git a/test/yaml-default-newline/input.yaml b/test/yaml-default-newline/input.yaml new file mode 100644 index 0000000..6f751fd --- /dev/null +++ b/test/yaml-default-newline/input.yaml @@ -0,0 +1,4 @@ +openapi: 3.0.0 +info: + description: |2 + Example \ No newline at end of file diff --git a/test/yaml-default-newline/options.yaml b/test/yaml-default-newline/options.yaml new file mode 100644 index 0000000..9854198 --- /dev/null +++ b/test/yaml-default-newline/options.yaml @@ -0,0 +1,2 @@ +verbose: true +output: output.yaml diff --git a/test/yaml-default-newline/output.yaml b/test/yaml-default-newline/output.yaml new file mode 100644 index 0000000..90d312b --- /dev/null +++ b/test/yaml-default-newline/output.yaml @@ -0,0 +1,4 @@ +openapi: 3.0.0 +info: + description: |2 + Example diff --git a/utils/file.js b/utils/file.js index 039dda0..23fb840 100644 --- a/utils/file.js +++ b/utils/file.js @@ -28,7 +28,7 @@ async function parseString(str, options = {}) { try { const result = yaml.parseWithPointers(encodedContent, {attachComments: options?.keepComments || false}); options.yamlComments = result.comments; - const obj = result.data; + const obj = normalizeYamlBlockScalarNewlines(result.data); if (typeof obj === 'object') { return obj; } else { @@ -338,6 +338,35 @@ function addQuotesToRefInString(yamlString) { return yamlString.replace(/(\$ref:\s*)([^"'\s>]+)/g, '$1"$2"'); } +/** + * Normalize a parser artifact where block scalars with indentation indicators + * gain a spurious leading newline during YAML parsing. + * This keeps genuine blank first lines intact by only stripping a single + * leading newline when the string also has a trailing newline. + * @param {*} value - Parsed YAML value. + * @returns {*} Normalized value. + */ +function normalizeYamlBlockScalarNewlines(value) { + if (typeof value === 'string') { + if (value.startsWith('\n') && !value.startsWith('\n\n') && value.endsWith('\n')) { + return value.slice(1); + } + return value; + } + + if (Array.isArray(value)) { + return value.map(item => normalizeYamlBlockScalarNewlines(item)); + } + + if (value && typeof value === 'object') { + for (const key of Object.keys(value)) { + value[key] = normalizeYamlBlockScalarNewlines(value[key]); + } + } + + return value; +} + /** * Analyze the OpenAPI document. * @param {object} oaObj - The OpenAPI document as a JSON object.