Skip to content
Open
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
11 changes: 11 additions & 0 deletions .changeset/lazy-trees-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@redocly/openapi-core': patch
'@redocly/cli': patch
---

Updated js-yaml from `4.2.0` to `5.2.1`.
Fixed an issue where strings that look like numbers with underscores (for example `'12_34'`) had quotation marks removed by the `bundle` command.
These strings stay quoted in the output.

**Note**: YAML parsing is stricter: a multi-line flow collection whose closing bracket is not indented deeper than its parent key is now a parse error.
Parse errors are reported at the offending token instead of the end of the document.
33 changes: 24 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,13 @@
"colorette": "^1.2.0",
"graphql": "^16.14.1",
"js-levenshtein": "^1.1.6",
"js-yaml": "^4.2.0",
"js-yaml": "^5.2.1",
"picomatch": "^4.0.4",
"pluralize": "^8.0.0",
"yaml-ast-parser": "0.0.43"
},
"devDependencies": {
"@types/js-levenshtein": "^1.1.0",
"@types/js-yaml": "^4.0.3",
"@types/picomatch": "^4.0.2",
"@types/pluralize": "^0.0.29",
"json-schema-to-ts": "^3.1.0",
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/__tests__/js-yaml.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,16 @@ describe('js-yaml', () => {
'unacceptable kind of an object to dump [object Function]'
);
});

it('should return a nullish value instead of throwing for empty or comment-only input', () => {
expect(parseYaml('')).toBeUndefined();
expect(parseYaml(' \n ')).toBeUndefined();
expect(parseYaml('# just a comment\n')).toBeNull();
});

it('throws when the stream contains more than one document', () => {
expect(() => parseYaml('a: 1\n---\nb: 2\n')).toThrow(
'expected a single document in the stream, but found more'
);
});
});
40 changes: 30 additions & 10 deletions packages/core/src/js-yaml/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
// TODO: add a type for "types" https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/js-yaml/index.d.ts
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { JSON_SCHEMA, types, load, dump, type LoadOptions, type DumpOptions } from 'js-yaml';
import {
CORE_SCHEMA,
mergeTag,
binaryTag,
omapTag,
pairsTag,
setTag,
loadAll,
dump,
YAMLException,
type LoadOptions,
type DumpOptions,
} from 'js-yaml';

const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = JSON_SCHEMA.extend({
implicit: [types.merge],
explicit: [types.binary, types.omap, types.pairs, types.set],
});
const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = CORE_SCHEMA.withTags(
mergeTag,
binaryTag,
omapTag,
pairsTag,
setTag
);

export const parseYaml = (str: string, opts?: LoadOptions): unknown =>
load(str, { schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts });
export const parseYaml = (str: string, opts?: LoadOptions): unknown => {
const documents = loadAll(str, { schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts });
if (documents.length === 0) {
return str.trim() === '' ? undefined : null;
}
if (documents.length > 1) {
throw new YAMLException('expected a single document in the stream, but found more');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multi-doc YAML loses error location

Low Severity

When parseYaml sees more than one YAML document, it throws a hand-written YAMLException without a (line:col) suffix. YamlParseError parses location from that suffix, so unresolved-ref and parse diagnostics for multi-document streams get NaN line/column instead of pointing at the extra --- separator.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e4aecb4. Configure here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a regression: js-yaml v4 load() threw the same exception
per the oas/AsyncAPI specs a description is a single document

}
return documents[0];
};

export const stringifyYaml = (obj: any, opts?: DumpOptions): string => dump(obj, opts);
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ describe('oas3 boolean-parameter-prefixes', () => {
"reportOnKey": false,
"source": "fixtures/invalid-yaml.yaml",
"start": {
"col": 1,
"line": 2,
"col": 8,
"line": 1,
},
},
],
"message": "Failed to parse: unexpected end of the stream within a single quoted scalar in "fixtures/invalid-yaml.yaml" (2:1)",
"message": "Failed to parse: unexpected end of the stream within a single quoted scalar in "fixtures/invalid-yaml.yaml" (1:8)",
"ruleId": "no-unresolved-refs",
"severity": "error",
"suggest": [],
Expand All @@ -103,7 +103,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
"source": "foobar.yaml",
},
],
"message": "Can't resolve $ref: unexpected end of the stream within a single quoted scalar in "fixtures/invalid-yaml.yaml" (2:1)",
"message": "Can't resolve $ref: unexpected end of the stream within a single quoted scalar in "fixtures/invalid-yaml.yaml" (1:8)",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please test this in the VSCE.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vadyvas please take a look.

"reference": "https://redocly.com/docs/cli/rules/oas/no-unresolved-refs",
"ruleId": "no-unresolved-refs",
"severity": "error",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ describe('no-invalid-media-type-examples', () => {
example: {
"a": "test",
"b": "test"
}
}
Comment thread
DmitryAnansky marked this conversation as resolved.
schema:
$ref: '#/components/schemas/C'

Expand Down
2 changes: 2 additions & 0 deletions tests/e2e/bundle/primitive-types/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ paths:
object:
key1: 1
key2: 2
underscoreNumberTransformedToString: 12_34
underscoreNumberString: '12_34'
2 changes: 2 additions & 0 deletions tests/e2e/bundle/primitive-types/snapshot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ paths:
object:
key1: 1
key2: 2
underscoreNumberTransformedToString: '12_34'
underscoreNumberString: '12_34'
components: {}

bundling openapi.yaml using configuration for api 'main'...
Expand Down
Loading