Skip to content

feat: add support for validating Arazzo 1.1.0#2877

Open
DmitryAnansky wants to merge 13 commits into
mainfrom
feat/support-linting-for-arazzo-3.1.0-version
Open

feat: add support for validating Arazzo 1.1.0#2877
DmitryAnansky wants to merge 13 commits into
mainfrom
feat/support-linting-for-arazzo-3.1.0-version

Conversation

@DmitryAnansky

@DmitryAnansky DmitryAnansky commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What/Why/How?

What's new in Arazzo 1.1.0 (verified against spec.openapis.org/arazzo/latest.html)

Object Change
Root New optional $self (URI-reference, base URI for the doc)
Source Description type gains asyncapi (was openapi/arazzo)
Step New channelPath (AsyncAPI channel pointer, joins mutual-exclusivity group with operationId/operationPath/workflowId), action (send/receive), correlationId, timeout (integer, ms), dependsOn (list of stepIds)
Parameter in gains querystring (OpenAPI 3.2 alignment)
Criterion Object form of type is now the generalized Expression Type Object; jsonpath versions gain rfc9535, xpath versions gain xpath-31
Expression Type Object type: jsonpath/xpath/jsonpointer; version REQUIRED: jsonpath→rfc9535,draft-goessner-dispatch-jsonpath-00; xpath→xpath-31,xpath-30,xpath-20,xpath-10; jsonpointer→rfc6901
Selector Object (new) context (REQUIRED), selector (REQUIRED), type (REQUIRED, string enum or Expression Type Object). Usable in outputs, parameter values, requestBody payload, payload replacement values
Outputs Values may be runtime-expression strings or Selector Objects
Payload Replacement New targetSelectorType (string enum or Expression Type Object); value may be a Selector Object
Success/Failure Action New parameters (list of Parameter Object | Reusable Object) for passing inputs to the referenced workflow
Runtime expressions New $message.header.*, $message.payload, $self sources (no lint impact — expressions are opaque strings to lint)

Reference

Closes: #2825

Testing

Screenshots (optional)

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

Security

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

Note

Medium Risk
Broad config and spec-detection changes affect all Arazzo lint paths; incorrect version routing could mis-validate documents, but behavior is heavily covered by new unit and e2e tests.

Overview
Adds Arazzo 1.1.0 validation to lint: arazzo: 1.1.x is detected as arazzo1_1 and checked with a new Arazzo1_1Types schema (1.0.x still uses arazzo1 / 1.0.1). Config gains parallel arazzo1_1Rules / preprocessors / decorators slots across presets and redocly.yaml, while docs steer users toward the shared rules: block instead of arazzo1Rules only.

1.1 struct support covers $self, AsyncAPI sourceDescriptions, step channelPath / action / correlationId / timeout / dependsOn, expression and selector objects, and related typing/visitor updates.

New spec-step-mutually-exclusive-fields rule flags steps that set more than one of x-operation, operationId, operationPath, workflowId, or channelPath. sourceDescription-type now allows asyncapi for 1.1 only. CLI telemetry and Respect collectors treat arazzo1_1 like arazzo1 where relevant.

Reviewed by Cursor Bugbot for commit 4eacfbf. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4eacfbf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@redocly/openapi-core Minor
@redocly/cli Minor
@redocly/respect-core Minor

Not sure what this means? Click here to learn what changesets are.

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

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 81.46% (🎯 81%) 7472 / 9172
🔵 Statements 80.81% (🎯 80%) 7765 / 9608
🔵 Functions 84.53% (🎯 84%) 1487 / 1759
🔵 Branches 73.15% (🎯 73%) 5046 / 6898
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/wrapper.ts 73.8% 47.22% 100% 73.17% 50, 68, 72-75, 93-100
packages/cli/src/utils/telemetry.ts 93.23% 75% 94.44% 93.89% 58, 63, 252, 288, 301-302, 387, 392
packages/core/src/detect-spec.ts 95.74% 95.83% 100% 95.74% 34, 40
packages/core/src/oas-types.ts 100% 100% 100% 100%
packages/core/src/visitors.ts 92.94% 90.12% 90% 92.5% 565, 602, 605, 626, 658, 672
packages/core/src/config/all.ts 100% 100% 100% 100%
packages/core/src/config/config.ts 61.45% 61.64% 69.76% 61.98% 176-206, 232, 236, 240-246, 249, 253-259, 291, 309-329, 384-392, 419-449
packages/core/src/config/minimal.ts 100% 100% 100% 100%
packages/core/src/config/recommended-strict.ts 100% 100% 100% 100%
packages/core/src/config/recommended.ts 100% 100% 100% 100%
packages/core/src/config/spec.ts 100% 100% 100% 100%
packages/core/src/config/utils.ts 97.53% 81.81% 100% 98.75% 33, 84-86
packages/core/src/rules/arazzo/index.ts 100% 100% 100% 100%
packages/core/src/rules/arazzo/sourceDescription-type.ts 88.88% 83.33% 100% 100% 8
packages/core/src/rules/arazzo/spec-step-mutually-exclusive-fields.ts 100% 100% 100% 100%
packages/core/src/types/arazzo1_1.ts 93.33% 86.36% 100% 93.33% 25, 163-166, 222
packages/core/src/types/redocly-yaml.ts 91.75% 83.01% 100% 91.48% 410, 442, 448, 491-498, 500, 651-656, 659-664, 667-672
packages/core/src/typings/arazzo.ts 100% 100% 100% 100%
Generated in workflow #10429 for commit 4eacfbf by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Performance Benchmark (Lower is Faster)

CLI Version Bundle Lint Check Config
cli-latest ▓ 1.00x ± 0.01 ▓ 1.00x (Fastest) ▓ 1.00x (Fastest)
cli-next ▓ 1.00x (Fastest) ▓ 1.01x ± 0.01 ▓ 1.00x ± 0.01

@DmitryAnansky DmitryAnansky force-pushed the feat/support-linting-for-arazzo-3.1.0-version branch 2 times, most recently from 25febda to 0126f35 Compare June 16, 2026 15:54
Comment thread packages/core/src/__tests__/arazzo1_1.test.ts Outdated
@DmitryAnansky DmitryAnansky force-pushed the feat/support-linting-for-arazzo-3.1.0-version branch from 05e73a3 to 856bc43 Compare June 17, 2026 15:09
@DmitryAnansky DmitryAnansky force-pushed the feat/support-linting-for-arazzo-3.1.0-version branch from 31e7814 to c360758 Compare June 18, 2026 13:57
@DmitryAnansky DmitryAnansky marked this pull request as ready for review June 18, 2026 15:16
@DmitryAnansky DmitryAnansky requested review from a team as code owners June 18, 2026 15:16
Comment thread packages/core/src/config/spec.ts
Comment thread packages/core/src/config/config.ts
Comment thread .changeset/eight-vans-cry.md Outdated
Comment thread docs/@v2/guides/lint-arazzo.md Outdated
Comment thread docs/@v2/rules/arazzo/spec-step-mutually-exclusive-fields.md Outdated
Comment thread docs/@v2/rules/arazzo/sourceDescription-type.md Outdated
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Comment thread docs/@v2/guides/lint-arazzo.md Outdated

| Arazzo | Compatibility |
| ------ | ------------- |
| 1.x | ✅ |

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.

If you're adding a separate 1.1 section, let's update this as well:

Suggested change
| 1.x ||
| 1.0.x ||
| 1.1.x ||

expect(replaceSourceWithRef(results)).toEqual([]);
});

it('rejects asyncapi sourceDescription type in Arazzo 1.0', async () => {

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.

This test doesn't make too much sense. We cannot evaluate all invalid fields for any spec, so why make an exception for asyncapi?

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.

To illustrate difference in 1.0.1 and 1.1.0 - there is new sourceDescription that does not exists in 1.0.1, called async.
If we are to chose the approach when we extent the version instead of separation - we could remove the test.

enter(sourceDescriptions, { report, location, specVersion }: UserContext) {
if (!sourceDescriptions.length) return;
const allowedTypes =
specVersion === 'arazzo1_1' ? ['openapi', 'arazzo', 'asyncapi'] : ['openapi', 'arazzo'];

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.

I see you compare the specVersion inside the rule. So does it make sense to introduce arazzo1_1Rules field (which is supposed to separate the rules)?

? MUTUALLY_EXCLUSIVE_FIELDS_1_1
: MUTUALLY_EXCLUSIVE_FIELDS_1_0;
const usedFields = fields.filter((field) =>
Object.prototype.hasOwnProperty.call(step, field)

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.

Is there a better alternative? I believe we already have the getOwn utility function. Let's reuse it? Or just use Object.hasOwn() if our configuration supports it.

...Arazzo1Types.Root,
properties: {
...Arazzo1Types.Root.properties,
$self: {

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.

There's no big deal in supporting this field in 1.0.

Comment thread packages/core/src/types/arazzo1_1.ts
targetSelectorType: (value: any) => {
if (!value) {
return undefined;
} else if (typeof value === 'string') {

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.

Comment thread packages/core/src/typings/arazzo.ts Outdated

export const ARAZZO_1_1_VERSION_PATTERN = /^1\.1\.\d+(-.+)?$/;

export const ARAZZO_VERSIONS_SUPPORTED_BY_RESPECT = ['1.0.1'];

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.

We should be supporting 1.1.x too, at least partially.

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.

Currently, we don't support anything new from Arazzo 1.1.0 in Respect.
So execution will be successful only when no new features needed.

import { ARAZZO_1_1_VERSION_PATTERN, VERSION_PATTERN } from './typings/arazzo.js';
import { isPlainObject } from './utils/is-plain-object.js';

export const specVersions = [

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.

spec_full_version,
respect_x_security_auth_types:
spec_version === 'arazzo1' && respect_x_security_auth_types?.length
(spec_version === 'arazzo1' || spec_version === 'arazzo1_1') &&

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.

Either use getMajorSpecVersion or don't introduce the 1.0/1.1 split.

Comment thread packages/core/src/rules/arazzo/spec-step-mutually-exclusive-fields.ts Outdated
Comment thread packages/core/src/config/config.ts
Comment thread packages/core/src/detect-spec.ts
Comment thread packages/core/src/config/config.ts
Comment thread packages/core/src/types/arazzo1_1.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4eacfbf. Configure here.

} else if (version === 'arazzo1') {
} else if (version === 'async3') {
return 'async3';
} else if (version === 'arazzo1' || version === 'arazzo1_1') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Plugin arazzo1_1 rules never load

Medium Severity

Lint loads plugin rule sets via getRulesForSpecVersion(getMajorSpecVersion(specVersion)), and getMajorSpecVersion maps arazzo1_1 to arazzo1. The new getRulesForSpecVersion branch for arazzo1_1 never runs, so plugin entries under rules.arazzo1_1 (now part of the plugin API) are not registered for 1.1 documents.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4eacfbf. Configure here.

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.

Adopt lint command to the new Arazzo v1.1.0 specification

4 participants