Skip to content

Conversation

@AlbinaBlazhko17
Copy link
Contributor

What/Why/How?

New linting rules to handle illogical use of composition keys: oneOf, anyOf, allOf.

Reference

Resolves #2326

Testing

Screenshots (optional)

Check yourself

  • Code changed? - Tested with Redoc/Realm/Reunite (internal)
  • All new/updated code is covered by tests
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update considered

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

@changeset-bot
Copy link

changeset-bot bot commented Oct 15, 2025

⚠️ No Changeset found

Latest commit: 8cec854

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Oct 15, 2025

Command Mean [s] Min [s] Max [s] Relative
redocly lint packages/core/src/benchmark/benches/rebilly.yaml 1.433 ± 0.020 1.407 1.478 1.00 ± 0.02
redocly-next lint packages/core/src/benchmark/benches/rebilly.yaml 1.431 ± 0.028 1.391 1.478 1.00

@AlbinaBlazhko17 AlbinaBlazhko17 force-pushed the feat/new-linting-rules-for-oneof-anyof-allof branch from 50557a0 to 4ee9d5e Compare October 21, 2025 11:46
…ords

feat: add proper check for mutually exclusive schemas in oneOf

feat: add checks for object min/max props, required props and additionlProperties

feat: add rule to the oas3_2 spec

refactor: functions naming and returning type

refactor: change if statement

refactor: move areDuplicatedSchemas function to utility and change naming

feat: add new rule no-illogical-any-of-usage

chore: add new rule to type

fix: getEffectiveBounds functionality, pattern check and mutualExclusibity check

feat: add functionality to report more then 1 problem

chore: improve warning messages

feat: add proper checks, refactor and change error messages

fix: error message in areDuplicatedSchemas

refactor: move logic into main function, add helper function, rename utility function

refactor: change naming and functionality for duplicated shcemas function

refactor: nullable function and return statement

fix: nullable type detection

refactor: add utility functions

refactor: remove functions, clean code, refactor additionalProperties

refactor: functions naming, if statement

chore: remove oneOf/anyOf/allOf separate rules and add one to handle different behavior

feat: add proper handling for additionalProperties

chore: update type

feat: add functionality to handle anyOf and allOf checks
@AlbinaBlazhko17 AlbinaBlazhko17 force-pushed the feat/new-linting-rules-for-oneof-anyof-allof branch from 4ee9d5e to b6216c1 Compare October 21, 2025 11:51
Copy link
Collaborator

@tatomyr tatomyr left a comment

Choose a reason for hiding this comment

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

Had a quick look. I suggest to reorganise the checks, so they cover fist for oneOfs, then anyOfs, and then allOfs. Just duplicate the checks when needed.
Will have another look after you implement those changes.

Comment on lines +33 to +34
// Helper function to get the composition keyword and schemas
const compositionData = (() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use correct naming so you don't need the comments, e.g.:

Suggested change
// Helper function to get the composition keyword and schemas
const compositionData = (() => {
const getSchemaCompositionData = (() => {

or something similar.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, wait, it's an IIFE? Then it's a bit of overengineering. You can do simply this:

const oneOfs = schema.oneOf

if you prefer to have a separate variable, and then just do every needed check. Don't be afraid to repeat yourself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking about using a separate variable for every composition keyword, but in that case, i need to duplicate checks (duplicated schemas, length of schemas) for every composition keyword and the only difference will be in the warning message. So, the purpose of the IIFE is to return the schema and string, and after that to easily retrieve them in the report message and checks.

// Helper function to get the composition keyword and schemas
const compositionData = (() => {
if (schema.oneOf && Array.isArray(schema.oneOf)) {
return { keyword: 'oneOf' as const, schemas: schema.oneOf };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Technically, your schema could contain oneOf and allOf simultaneously. The code doesn't handle this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This functionality at all doesn't resolve all nested composition keywords, because we consider, that every composition keyword is a new scope of validation.


const { keyword, schemas } = compositionData;

// Check for minimum schema count (oneOf and anyOf require at least 2)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need comments like this as the intention should be clear enough from the condition and the report message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, you are right. I just left all comments to simplify the review of PR, i will remove it after finalizing the functionality.

return null;
})();

if (!compositionData) return;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This duplicates the skip() functianality.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it is duplication, because it doesn't see proper type, even we check in skip method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New linting rules for oneOf/anyOf/allOf

3 participants