Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## unreleased

- CLI: add yamlCompat option for YAML 1.1

## [1.33.3] - 2026-06-18

- Sort: Keep stable sorting for trailing-slash paths (#228)
Expand All @@ -24,7 +26,7 @@

## [1.32.0] - 2026-05-23

- Casing - Configure characters to keep
- Casing: Configure characters to keep
- CLI: Fix YAML output to preserve x-version number formatting

## [1.31.0] - 2026-04-12
Expand Down
1 change: 1 addition & 0 deletions bin/__snapshots__/cli.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Options:
--no-sort don't sort the OpenAPI file
--keepComments don't remove the comments from the OpenAPI YAML file (default: false)
--yamlQuoteStyle <yamlQuoteStyle> YAML quote style: single, double, or detect
--yamlCompat <yamlCompat> YAML compatibility schema for older OpenAPI tools (yaml-1.1)
--sortComponentsFile <sortComponentsFile> the file with components to sort alphabetically
--sortComponentsProps sort properties within schema components alphabetically (default: false)
--lineWidth <lineWidth> max line width of YAML output (default: -1)
Expand Down
1 change: 1 addition & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ program
.option('--no-sort', `don't sort the OpenAPI file`)
.option('--keepComments', `don't remove the comments from the OpenAPI YAML file`, false)
.option('--yamlQuoteStyle <yamlQuoteStyle>', 'YAML quote style: single, double, or detect')
.option('--yamlCompat <yamlCompat>', 'YAML compatibility schema for older OpenAPI tools (yaml-1.1)')
.option('--sortComponentsFile <sortComponentsFile>', 'the file with components to sort alphabetically')
.option('--sortComponentsProps', 'sort properties within schema components alphabetically', false)
.option('--lineWidth <lineWidth>', 'max line width of YAML output', -1)
Expand Down
28 changes: 28 additions & 0 deletions bin/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,34 @@ describe('openapi-format CLI command', () => {
expect(sanitize(result.stderr)).toStrictEqual(sanitize(output));
});

it('should apply yamlCompat from config files', async () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openapi-format-yaml-compat-'));
const inputFile = path.join(tempDir, 'input.yaml');
const configFile = path.join(tempDir, 'options.json');
const outputFile = path.join(tempDir, 'output.yaml');

fs.writeFileSync(
inputFile,
`openapi: 3.0.3\ninfo:\n title: t\n version: 1.0.0\npaths: {}\ncomponents:\n schemas:\n CountryCode:\n type: string\n enum:\n - ca\n - "no"\n - us\n Feature:\n type: object\n properties:\n status:\n type: string\n enum:\n - "yes"\n - "no"\n - "on"\n - "off"\n example:\n status: "on"\n`
);
fs.writeFileSync(configFile, JSON.stringify({yamlCompat: 'yaml-1.1', sort: false}, null, 2));

const result = await testUtils.cli(['input.yaml', '--configFile options.json', `--output ${outputFile}`], tempDir);

expect(result.code).toBe(0);
expect(result.stdout).toContain('formatted successfully');
const output = fs.readFileSync(outputFile, 'utf8');
expect(output).toContain('CountryCode:');
expect(output).toContain('Feature:');
expect(output).toContain('- ca');
expect(output).toContain('- us');
expect(output).toContain('- "no"');
expect(output).toContain('- "yes"');
expect(output).toContain('- "on"');
expect(output).toContain('- "off"');
expect(output).toContain('status: "on"');
});

it('should load the default .openapiformatrc if configFile is not provided', async () => {
// Mock the existence of the .openapiformatrc file
const defaultConfigPath = '.openapiformatrc';
Expand Down
44 changes: 23 additions & 21 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,38 +158,39 @@ Arguments:

Options:

--output, -o Save the formatted OpenAPI file as JSON/YAML [path]
--output, -o Save the formatted OpenAPI file as JSON/YAML [path]

--sortFile The file to specify custom OpenAPI fields ordering [path]
--casingFile The file to specify casing rules [path]
--generateFile The file to specify generate rules [path]
--filterFile The file to specify filter rules [path]
--overlayFile The file to specify OpenAPI overlay actions [path]
--sortFile The file to specify custom OpenAPI fields ordering [path]
--casingFile The file to specify casing rules [path]
--generateFile The file to specify generate rules [path]
--filterFile The file to specify filter rules [path]
--overlayFile The file to specify OpenAPI overlay actions [path]

--no-sort Don't sort the OpenAPI file [boolean]
--keepComments Don't remove the comments from the OpenAPI YAML file [boolean]
--yamlQuoteStyle Preferred YAML quote style: single, double, detect [string]
--sortComponentsFile The file with components to sort alphabetically [path]
--sortComponentsProps Sort properties within schema components alphabetically [boolean]
--no-sort Don't sort the OpenAPI file [boolean]
--keepComments Don't remove the comments from the OpenAPI YAML file [boolean]
--yamlQuoteStyle Preferred YAML quote style: single, double, detect [string]
--yamlCompat YAML compatibility schema for older OpenAPI tools [string]
--sortComponentsFile The file with components to sort alphabetically [path]
--sortComponentsProps Sort properties within schema components alphabetically [boolean]

--no-bundle Don't bundle the local and remote $ref [boolean]
--split Split OpenAPI document into a multi-file structure [boolean]
--no-bundle Don't bundle the local and remote $ref [boolean]
--split Split OpenAPI document into a multi-file structure [boolean]

--rename Rename the OpenAPI title [string]
--rename Rename the OpenAPI title [string]

--convertTo convert the OpenAPI document to OpenAPI version 3.1 or 3.2 [string]
--convertTo convert the OpenAPI document to OpenAPI version 3.1 or 3.2 [string]

--configFile The file with the OpenAPI-format CLI options [path]
--configFile The file with the OpenAPI-format CLI options [path]

--lineWidth Max line width of YAML output [number]
--lineWidth Max line width of YAML output [number]

--json Prints the file to stdout as JSON [boolean]
--yaml Prints the file to stdout as YAML [boolean]
--json Prints the file to stdout as JSON [boolean]
--yaml Prints the file to stdout as YAML [boolean]

--playground, -p Open config in online playground
--help Show help [boolean]
--help Show help [boolean]
--version Output the version number
--verbose Output more details of the filter process [count]
--verbose Output more details of the filter process [count]
```

## OpenAPI format CLI options
Expand All @@ -206,6 +207,7 @@ Options:
| --no-sort | | don't sort the OpenAPI file | boolean | FALSE | optional |
| --keepComments | | don't remove the comments from the OpenAPI YAML file | boolean | FALSE | optional |
| --yamlQuoteStyle | | preferred YAML quote style for YAML output (`single`, `double`, `detect`) | string | detect | optional |
| --yamlCompat | | YAML compatibility schema for older OpenAPI tools (`yaml-1.1`) | string | | optional |
| --sortComponentsFile | | sort the items of the components (schemas, parameters, ...) by alphabet | path to file | defaultSortComponents.json | optional |
| --sortComponentsProps | | sort properties within schema components alphabetically | boolean | FALSE | optional |
| --no-bundle | | don't bundle the local and remote $ref in the OpenAPI document | boolean | FALSE | optional |
Expand Down
5 changes: 5 additions & 0 deletions schemas/openapi-format.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,11 @@
"enum": ["single", "double", "detect"],
"default": "detect"
},
"yamlCompat": {
"type": "string",
"description": "Compatibility schema to use when stringifying YAML. Enables YAML 1.1-safe quoting for compatibility with older parsers.",
"enum": ["yaml-1.1"]
},
"lineWidth": {
"type": "integer",
"description": "Maximum line width of YAML output. Use -1 for unlimited (default).",
Expand Down
92 changes: 92 additions & 0 deletions test/util-file.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,90 @@ describe('openapi-format CLI file tests', () => {
expect(result).not.toContain('name: "John"');
});

test('should leave YAML 1.2 boolean-like strings unquoted by default', async () => {
const obj = {
components: {
schemas: {
CountryCode: {
type: 'string',
enum: ['ca', 'no', 'us']
},
Feature: {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['yes', 'no', 'on', 'off']
}
},
example: {
status: 'on'
}
}
}
}
};

const result = await stringify(obj, {
format: 'yaml'
});

expect(result).toContain('CountryCode:');
expect(result).toContain('enum:');
expect(result).toContain('- ca');
expect(result).toContain('- no');
expect(result).toContain('- us');
expect(result).toContain('Feature:');
expect(result).toContain('- yes');
expect(result).toContain('- on');
expect(result).toContain('- off');
expect(result).toContain('status: on');
});

test('should quote YAML 1.1 boolean-like strings when yamlCompat is yaml-1.1', async () => {
const obj = {
components: {
schemas: {
CountryCode: {
type: 'string',
enum: ['ca', 'no', 'us']
},
Feature: {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['yes', 'no', 'on', 'off']
}
},
example: {
status: 'on'
}
}
}
}
};

const result = await stringify(obj, {
format: 'yaml',
yamlCompat: 'yaml-1.1'
});

expect(result).toContain('CountryCode:');
expect(result).toContain('- ca');
expect(result).toContain("- 'no'");
expect(result).toContain('- us');
expect(result).toContain('Feature:');
expect(result).toContain("- 'yes'");
expect(result).toContain("- 'on'");
expect(result).toContain("- 'off'");
expect(result).toContain("status: 'on'");
expect(result).not.toContain('- yes');
expect(result).not.toContain('- no');
expect(result).not.toContain('- on');
expect(result).not.toContain('- off');
});

test('should preserve comments while honoring the resolved quote style', async () => {
const parsed = yaml.parseDocument('name: "Hello: world" # person\ncity: London\n');
const options = {
Expand Down Expand Up @@ -289,6 +373,14 @@ describe('openapi-format CLI file tests', () => {

expect(result).toEqual(JSON.stringify(obj, null, 2));
});

test('should leave JSON output unchanged when yamlCompat is set', async () => {
const obj = {name: 'John'};

const result = await stringify(obj, {format: 'json', yamlCompat: 'yaml-1.1'});

expect(result).toEqual(JSON.stringify(obj, null, 2));
});
});

describe('parseString', () => {
Expand Down
25 changes: 25 additions & 0 deletions test/yaml-compat/input.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
openapi: 3.0.3
info:
title: t
version: 1.0.0
paths: {}
components:
schemas:
CountryCode:
type: string
enum:
- ca
- "no"
- us
Feature:
type: object
properties:
status:
type: string
enum:
- "yes"
- "no"
- "on"
- "off"
example:
status: "on"
4 changes: 4 additions & 0 deletions test/yaml-compat/options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
verbose: true
no-sort: true
output: output.yaml
yamlCompat: yaml-1.1
25 changes: 25 additions & 0 deletions test/yaml-compat/output.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
openapi: 3.0.3
info:
title: t
version: 1.0.0
paths: {}
components:
schemas:
CountryCode:
type: string
enum:
- ca
- "no"
- us
Feature:
type: object
properties:
status:
type: string
enum:
- "yes"
- "no"
- "on"
- "off"
example:
status: "on"
1 change: 1 addition & 0 deletions types/openapi-format.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ declare module 'openapi-format' {
json?: boolean;
keepComments?: boolean;
yamlQuoteStyle?: 'single' | 'double' | 'detect';
yamlCompat?: 'yaml-1.1';
yamlComments?: Record<string, unknown>;
lineWidth?: string | number;
mode?: string;
Expand Down
10 changes: 8 additions & 2 deletions utils/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,20 @@ function resolveYamlQuoteStyle(options = {}) {
* Build YAML stringify/toString options, including quote-style control.
* @param {number} lineWidth
* @param {object} [options]
* @returns {{lineWidth: number, singleQuote: boolean}}
* @returns {{lineWidth: number, singleQuote: boolean, compat?: 'yaml-1.1'}}
*/
function buildYamlStringifyOptions(lineWidth, options = {}) {
const style = resolveYamlQuoteStyle(options);
return {
const yamlStringifyOptions = {
lineWidth,
singleQuote: style !== YAML_QUOTE_STYLE.DOUBLE
};

if (options.yamlCompat === 'yaml-1.1') {
yamlStringifyOptions.compat = 'yaml-1.1';
}

return yamlStringifyOptions;
}

/**
Expand Down
Loading