From 9b7f50f9a9421b519646aeedcdde44186cc4b8f2 Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Thu, 18 Jul 2024 02:40:13 -0500 Subject: [PATCH 01/14] account for root level paths --- packages/cli/src/utils/miscellaneous.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/utils/miscellaneous.ts b/packages/cli/src/utils/miscellaneous.ts index 0acdbbe3c2..dd1243c3e6 100644 --- a/packages/cli/src/utils/miscellaneous.ts +++ b/packages/cli/src/utils/miscellaneous.ts @@ -130,6 +130,9 @@ export function printExecutionTime(commandName: string, startedAt: number, api: } export function pathToFilename(path: string, pathSeparator: string) { + if (path === '/') { + return 'root'; + } return path .replace(/~1/g, '/') .replace(/~0/g, '~') From 7b39fde186bbe7f931aa435b2703e56061d5fda1 Mon Sep 17 00:00:00 2001 From: Dmytro Anansky Date: Fri, 13 Sep 2024 13:21:34 +0300 Subject: [PATCH 02/14] fix: changes in criteria-unique arazzo rule (#1733) --- .changeset/hungry-drinks-grab.md | 6 ++++++ packages/core/src/config/config.ts | 2 +- packages/core/src/rules/arazzo/criteria-unique.ts | 15 +++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 .changeset/hungry-drinks-grab.md diff --git a/.changeset/hungry-drinks-grab.md b/.changeset/hungry-drinks-grab.md new file mode 100644 index 0000000000..405e037612 --- /dev/null +++ b/.changeset/hungry-drinks-grab.md @@ -0,0 +1,6 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Added additional checks to `criteria-unique` Arazzo rule. diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index fecdaeafb2..453c2d0322 100755 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -74,7 +74,7 @@ export class StyleguideConfig { [SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules }, [SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules }, [SpecVersion.Arazzo]: { - ...rawConfig.arazzoRules, + ...(rawConfig.arazzoRules || {}), ...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}), }, }; diff --git a/packages/core/src/rules/arazzo/criteria-unique.ts b/packages/core/src/rules/arazzo/criteria-unique.ts index d1947c0675..82792296fa 100644 --- a/packages/core/src/rules/arazzo/criteria-unique.ts +++ b/packages/core/src/rules/arazzo/criteria-unique.ts @@ -5,7 +5,10 @@ export const CriteriaUnique: ArazzoRule = () => { return { FailureActionObject: { enter(action, { report, location }: UserContext) { - const criterias = action.criteria; + const criterias = action?.criteria; + if (!Array.isArray(criterias)) { + return; + } const seen = new Set(); for (const criteria of criterias) { const key = JSON.stringify(criteria); @@ -22,7 +25,10 @@ export const CriteriaUnique: ArazzoRule = () => { }, SuccessActionObject: { enter(action, { report, location }: UserContext) { - const criterias = action.criteria; + const criterias = action?.criteria; + if (!Array.isArray(criterias)) { + return; + } const seen = new Set(); for (const criteria of criterias) { const key = JSON.stringify(criteria); @@ -39,11 +45,12 @@ export const CriteriaUnique: ArazzoRule = () => { }, Step: { enter(step, { report, location }: UserContext) { - if (!step.successCriteria) { + const successCriterias = step?.successCriteria; + + if (!Array.isArray(successCriterias)) { return; } - const successCriterias = step.successCriteria; const seen = new Set(); for (const criteria of successCriterias) { From 09e924c747ffda00f3656685b5b2d656b7f4c364 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:37:21 +0300 Subject: [PATCH 03/14] =?UTF-8?q?chore:=20=F0=9F=94=96=20release=20new=20v?= =?UTF-8?q?ersions=20(#1734)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/hungry-drinks-grab.md | 6 ------ docs/changelog.md | 7 +++++++ package-lock.json | 8 ++++---- packages/cli/CHANGELOG.md | 7 +++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- 7 files changed, 27 insertions(+), 13 deletions(-) delete mode 100644 .changeset/hungry-drinks-grab.md diff --git a/.changeset/hungry-drinks-grab.md b/.changeset/hungry-drinks-grab.md deleted file mode 100644 index 405e037612..0000000000 --- a/.changeset/hungry-drinks-grab.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@redocly/openapi-core": patch -"@redocly/cli": patch ---- - -Added additional checks to `criteria-unique` Arazzo rule. diff --git a/docs/changelog.md b/docs/changelog.md index d7535c4460..51d039cf8b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,13 @@ toc: +## 1.25.1 (2024-09-13) + +### Patch Changes + +- Added additional checks to `criteria-unique` Arazzo rule. +- Updated @redocly/openapi-core to v1.25.1. + ## 1.25.0 (2024-09-11) ### Minor Changes diff --git a/package-lock.json b/package-lock.json index bc91b7ad91..349862ab9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13739,10 +13739,10 @@ }, "packages/cli": { "name": "@redocly/cli", - "version": "1.25.0", + "version": "1.25.1", "license": "MIT", "dependencies": { - "@redocly/openapi-core": "1.25.0", + "@redocly/openapi-core": "1.25.1", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", @@ -13796,7 +13796,7 @@ }, "packages/core": { "name": "@redocly/openapi-core", - "version": "1.25.0", + "version": "1.25.1", "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", @@ -16460,7 +16460,7 @@ "@redocly/cli": { "version": "file:packages/cli", "requires": { - "@redocly/openapi-core": "1.25.0", + "@redocly/openapi-core": "1.25.1", "@types/configstore": "^5.0.1", "@types/glob": "^8.1.0", "@types/pluralize": "^0.0.29", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 38533f55d3..562c1c7c9e 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # @redocly/cli +## 1.25.1 + +### Patch Changes + +- Added additional checks to `criteria-unique` Arazzo rule. +- Updated @redocly/openapi-core to v1.25.1. + ## 1.25.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 738bf01b53..f229e1efb3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/cli", - "version": "1.25.0", + "version": "1.25.1", "description": "", "license": "MIT", "bin": { @@ -36,7 +36,7 @@ "Roman Hotsiy (https://redoc.ly/)" ], "dependencies": { - "@redocly/openapi-core": "1.25.0", + "@redocly/openapi-core": "1.25.1", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e5a9aa228c..c3e7c3cde3 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @redocly/openapi-core +## 1.25.1 + +### Patch Changes + +- Added additional checks to `criteria-unique` Arazzo rule. + ## 1.25.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index 4bf0b98bad..3654921b6d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/openapi-core", - "version": "1.25.0", + "version": "1.25.1", "description": "", "main": "lib/index.js", "engines": { From 7589f393e06955773c86a76eee2578284f5c3bd0 Mon Sep 17 00:00:00 2001 From: Dmytro Anansky Date: Fri, 13 Sep 2024 17:06:18 +0300 Subject: [PATCH 04/14] fix: camelCase assertion for single letter (#1735) --- .changeset/fresh-cheetahs-love.md | 6 ++++++ .../src/rules/common/assertions/__tests__/asserts.test.ts | 8 ++++++++ packages/core/src/rules/common/assertions/asserts.ts | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/fresh-cheetahs-love.md diff --git a/.changeset/fresh-cheetahs-love.md b/.changeset/fresh-cheetahs-love.md new file mode 100644 index 0000000000..8d8971143f --- /dev/null +++ b/.changeset/fresh-cheetahs-love.md @@ -0,0 +1,6 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Fixed `camelCase` assertion for single-letter values. diff --git a/packages/core/src/rules/common/assertions/__tests__/asserts.test.ts b/packages/core/src/rules/common/assertions/__tests__/asserts.test.ts index 45f8bf0c98..4367ba93ae 100644 --- a/packages/core/src/rules/common/assertions/__tests__/asserts.test.ts +++ b/packages/core/src/rules/common/assertions/__tests__/asserts.test.ts @@ -317,6 +317,14 @@ describe('oas3 assertions', () => { expect(asserts.casing(['testExample', 'fooBar'], 'camelCase', assertionProperties)).toEqual( [] ); + expect(asserts.casing(['f'], 'camelCase', assertionProperties)).toEqual([]); + expect(asserts.casing(['Q'], 'camelCase', assertionProperties)).toEqual([ + { + message: '"Q" should use camelCase', + location: baseLocation.child('Q').key(), + }, + ]); + expect(asserts.casing(['fQ'], 'camelCase', assertionProperties)).toEqual([]); expect(asserts.casing(['testExample', 'FooBar'], 'camelCase', assertionProperties)).toEqual( [ { diff --git a/packages/core/src/rules/common/assertions/asserts.ts b/packages/core/src/rules/common/assertions/asserts.ts index 6794f98961..87eb276716 100644 --- a/packages/core/src/rules/common/assertions/asserts.ts +++ b/packages/core/src/rules/common/assertions/asserts.ts @@ -243,7 +243,7 @@ export const asserts: Asserts = { if (typeof value === 'undefined' || isPlainObject(value)) return []; // property doesn't exist or is an object, no need to lint it with this assert const values = Array.isArray(value) ? value : [value]; const casingRegexes: Record = { - camelCase: /^[a-z][a-zA-Z0-9]+$/g, + camelCase: /^[a-z][a-zA-Z0-9]*$/g, 'kebab-case': /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/g, snake_case: /^([a-z][a-z0-9]*)(_[a-z0-9]+)*$/g, PascalCase: /^[A-Z][a-zA-Z0-9]+$/g, From 8a787ebc87b9378eebb4f006ee58ca1f0767501e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 17:23:08 +0300 Subject: [PATCH 05/14] =?UTF-8?q?chore:=20=F0=9F=94=96=20release=20new=20v?= =?UTF-8?q?ersions=20(#1736)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/fresh-cheetahs-love.md | 6 ------ docs/changelog.md | 7 +++++++ package-lock.json | 8 ++++---- packages/cli/CHANGELOG.md | 7 +++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- 7 files changed, 27 insertions(+), 13 deletions(-) delete mode 100644 .changeset/fresh-cheetahs-love.md diff --git a/.changeset/fresh-cheetahs-love.md b/.changeset/fresh-cheetahs-love.md deleted file mode 100644 index 8d8971143f..0000000000 --- a/.changeset/fresh-cheetahs-love.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@redocly/openapi-core": patch -"@redocly/cli": patch ---- - -Fixed `camelCase` assertion for single-letter values. diff --git a/docs/changelog.md b/docs/changelog.md index 51d039cf8b..a2745e8f88 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,13 @@ toc: +## 1.25.2 (2024-09-13) + +### Patch Changes + +- Fixed `camelCase` assertion for single-letter values. +- Updated @redocly/openapi-core to v1.25.2. + ## 1.25.1 (2024-09-13) ### Patch Changes diff --git a/package-lock.json b/package-lock.json index 349862ab9c..22bbca2d3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13739,10 +13739,10 @@ }, "packages/cli": { "name": "@redocly/cli", - "version": "1.25.1", + "version": "1.25.2", "license": "MIT", "dependencies": { - "@redocly/openapi-core": "1.25.1", + "@redocly/openapi-core": "1.25.2", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", @@ -13796,7 +13796,7 @@ }, "packages/core": { "name": "@redocly/openapi-core", - "version": "1.25.1", + "version": "1.25.2", "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", @@ -16460,7 +16460,7 @@ "@redocly/cli": { "version": "file:packages/cli", "requires": { - "@redocly/openapi-core": "1.25.1", + "@redocly/openapi-core": "1.25.2", "@types/configstore": "^5.0.1", "@types/glob": "^8.1.0", "@types/pluralize": "^0.0.29", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 562c1c7c9e..cd93a69dd6 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # @redocly/cli +## 1.25.2 + +### Patch Changes + +- Fixed `camelCase` assertion for single-letter values. +- Updated @redocly/openapi-core to v1.25.2. + ## 1.25.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index f229e1efb3..bfce8b3690 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/cli", - "version": "1.25.1", + "version": "1.25.2", "description": "", "license": "MIT", "bin": { @@ -36,7 +36,7 @@ "Roman Hotsiy (https://redoc.ly/)" ], "dependencies": { - "@redocly/openapi-core": "1.25.1", + "@redocly/openapi-core": "1.25.2", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index c3e7c3cde3..13717df0dc 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @redocly/openapi-core +## 1.25.2 + +### Patch Changes + +- Fixed `camelCase` assertion for single-letter values. + ## 1.25.1 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 3654921b6d..680cc1f3a6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/openapi-core", - "version": "1.25.1", + "version": "1.25.2", "description": "", "main": "lib/index.js", "engines": { From e83a6a484f45aa522fc055d066b4b394937c1bc3 Mon Sep 17 00:00:00 2001 From: Dmytro Anansky Date: Wed, 18 Sep 2024 13:07:56 +0300 Subject: [PATCH 06/14] chore: update redocly config version (#1738) --- .changeset/proud-poets-wave.md | 5 +++++ package-lock.json | 16 ++++++++-------- packages/core/package.json | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 .changeset/proud-poets-wave.md diff --git a/.changeset/proud-poets-wave.md b/.changeset/proud-poets-wave.md new file mode 100644 index 0000000000..75aeb52ed5 --- /dev/null +++ b/.changeset/proud-poets-wave.md @@ -0,0 +1,5 @@ +--- +"@redocly/openapi-core": patch +--- + +Updated @redocly/config to v0.11.0. diff --git a/package-lock.json b/package-lock.json index 22bbca2d3a..a0e593a50c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3525,9 +3525,9 @@ "link": true }, "node_modules/@redocly/config": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.10.1.tgz", - "integrity": "sha512-H3LnKVGzOaxskwJu8pmJYwBOWjP61qOK7TuTrbafqArDVckE06fhA6l0nO4KvBbjLPjy1Al7UnlxOu23V4Nl0w==" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.11.0.tgz", + "integrity": "sha512-vAc77vCuWsVgLx2LN02P6jqLBhHuot6O1LsSJEAAkWEvXARSGSQVon50QW7jlbCMg9OFTYYYRPN4W6K/YmnM3w==" }, "node_modules/@redocly/openapi-core": { "resolved": "packages/core", @@ -13800,7 +13800,7 @@ "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.10.1", + "@redocly/config": "^0.11.0", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.4", "js-levenshtein": "^1.1.6", @@ -16502,15 +16502,15 @@ } }, "@redocly/config": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.10.1.tgz", - "integrity": "sha512-H3LnKVGzOaxskwJu8pmJYwBOWjP61qOK7TuTrbafqArDVckE06fhA6l0nO4KvBbjLPjy1Al7UnlxOu23V4Nl0w==" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.11.0.tgz", + "integrity": "sha512-vAc77vCuWsVgLx2LN02P6jqLBhHuot6O1LsSJEAAkWEvXARSGSQVon50QW7jlbCMg9OFTYYYRPN4W6K/YmnM3w==" }, "@redocly/openapi-core": { "version": "file:packages/core", "requires": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.10.1", + "@redocly/config": "^0.11.0", "@types/js-levenshtein": "^1.1.0", "@types/js-yaml": "^4.0.3", "@types/lodash.isequal": "^4.5.5", diff --git a/packages/core/package.json b/packages/core/package.json index 680cc1f3a6..63d46a82a3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,7 +36,7 @@ ], "dependencies": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.10.1", + "@redocly/config": "^0.11.0", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.4", "js-levenshtein": "^1.1.6", From b574cdb36bae72f532933b8737eccf01616c402b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:21:34 +0300 Subject: [PATCH 07/14] =?UTF-8?q?chore:=20=F0=9F=94=96=20release=20new=20v?= =?UTF-8?q?ersions=20(#1739)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/proud-poets-wave.md | 5 ----- docs/changelog.md | 6 ++++++ package-lock.json | 8 ++++---- packages/cli/CHANGELOG.md | 6 ++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- 7 files changed, 25 insertions(+), 12 deletions(-) delete mode 100644 .changeset/proud-poets-wave.md diff --git a/.changeset/proud-poets-wave.md b/.changeset/proud-poets-wave.md deleted file mode 100644 index 75aeb52ed5..0000000000 --- a/.changeset/proud-poets-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@redocly/openapi-core": patch ---- - -Updated @redocly/config to v0.11.0. diff --git a/docs/changelog.md b/docs/changelog.md index a2745e8f88..0e6c14eb91 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,12 @@ toc: +## 1.25.3 (2024-09-18) + +### Patch Changes + +- Updated @redocly/openapi-core to v1.25.3. + ## 1.25.2 (2024-09-13) ### Patch Changes diff --git a/package-lock.json b/package-lock.json index a0e593a50c..dbeb2a3c08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13739,10 +13739,10 @@ }, "packages/cli": { "name": "@redocly/cli", - "version": "1.25.2", + "version": "1.25.3", "license": "MIT", "dependencies": { - "@redocly/openapi-core": "1.25.2", + "@redocly/openapi-core": "1.25.3", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", @@ -13796,7 +13796,7 @@ }, "packages/core": { "name": "@redocly/openapi-core", - "version": "1.25.2", + "version": "1.25.3", "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", @@ -16460,7 +16460,7 @@ "@redocly/cli": { "version": "file:packages/cli", "requires": { - "@redocly/openapi-core": "1.25.2", + "@redocly/openapi-core": "1.25.3", "@types/configstore": "^5.0.1", "@types/glob": "^8.1.0", "@types/pluralize": "^0.0.29", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index cd93a69dd6..18f4ae4c80 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @redocly/cli +## 1.25.3 + +### Patch Changes + +- Updated @redocly/openapi-core to v1.25.3. + ## 1.25.2 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index bfce8b3690..8e94e87e14 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/cli", - "version": "1.25.2", + "version": "1.25.3", "description": "", "license": "MIT", "bin": { @@ -36,7 +36,7 @@ "Roman Hotsiy (https://redoc.ly/)" ], "dependencies": { - "@redocly/openapi-core": "1.25.2", + "@redocly/openapi-core": "1.25.3", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 13717df0dc..e09d57b9bd 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @redocly/openapi-core +## 1.25.3 + +### Patch Changes + +- Updated @redocly/config to v0.11.0. + ## 1.25.2 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 63d46a82a3..8bb77a6899 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/openapi-core", - "version": "1.25.2", + "version": "1.25.3", "description": "", "main": "lib/index.js", "engines": { From 07c053936eb4fe4810e6a5b4d19729f200b02954 Mon Sep 17 00:00:00 2001 From: Roman Sainchuk Date: Tue, 24 Sep 2024 13:53:06 +0300 Subject: [PATCH 08/14] feat: report endpoint sunset (#1677) --- .changeset/tiny-boats-check.md | 5 + .../src/cms/api/__tests__/api.client.test.ts | 195 ++++++++++++++++-- packages/cli/src/cms/api/api-client.ts | 153 +++++++++++--- .../commands/__tests__/push-status.test.ts | 3 +- .../src/cms/commands/__tests__/push.test.ts | 7 +- packages/cli/src/cms/commands/push-status.ts | 6 +- packages/cli/src/cms/commands/push.ts | 11 +- 7 files changed, 323 insertions(+), 57 deletions(-) create mode 100644 .changeset/tiny-boats-check.md diff --git a/.changeset/tiny-boats-check.md b/.changeset/tiny-boats-check.md new file mode 100644 index 0000000000..8cb64ea58c --- /dev/null +++ b/.changeset/tiny-boats-check.md @@ -0,0 +1,5 @@ +--- +"@redocly/cli": patch +--- + +Added a warning message to the `push` and `push-status` commands to notify users about upcoming or ongoing resource deprecation. diff --git a/packages/cli/src/cms/api/__tests__/api.client.test.ts b/packages/cli/src/cms/api/__tests__/api.client.test.ts index f85a341e96..77d4e5a3d7 100644 --- a/packages/cli/src/cms/api/__tests__/api.client.test.ts +++ b/packages/cli/src/cms/api/__tests__/api.client.test.ts @@ -1,7 +1,8 @@ import fetch, { Response } from 'node-fetch'; import * as FormData from 'form-data'; +import { red, yellow } from 'colorette'; -import { ReuniteApiClient, PushPayload, ReuniteApiError } from '../api-client'; +import { ReuniteApi, PushPayload, ReuniteApiError } from '../api-client'; jest.mock('node-fetch', () => ({ default: jest.fn(), @@ -21,10 +22,10 @@ describe('ApiClient', () => { const expectedUserAgent = `redocly-cli/${version} ${command}`; describe('getDefaultBranch()', () => { - let apiClient: ReuniteApiClient; + let apiClient: ReuniteApi; beforeEach(() => { - apiClient = new ReuniteApiClient({ domain: testDomain, apiKey: testToken, version, command }); + apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command }); }); it('should get default project branch', async () => { @@ -90,22 +91,23 @@ describe('ApiClient', () => { mountBranchName: 'remote-mount-branch-name', mountPath: 'remote-mount-path', }; - let apiClient: ReuniteApiClient; + + const responseMock = { + id: 'remote-id', + type: 'CICD', + mountPath: 'remote-mount-path', + mountBranchName: 'remote-mount-branch-name', + organizationId: testOrg, + projectId: testProject, + }; + + let apiClient: ReuniteApi; beforeEach(() => { - apiClient = new ReuniteApiClient({ domain: testDomain, apiKey: testToken, version, command }); + apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command }); }); it('should upsert remote', async () => { - const responseMock = { - id: 'remote-id', - type: 'CICD', - mountPath: 'remote-mount-path', - mountBranchName: 'remote-mount-branch-name', - organizationId: testOrg, - projectId: testProject, - }; - mockFetchResponse({ ok: true, json: jest.fn().mockResolvedValue(responseMock), @@ -204,10 +206,10 @@ describe('ApiClient', () => { outdated: false, }; - let apiClient: ReuniteApiClient; + let apiClient: ReuniteApi; beforeEach(() => { - apiClient = new ReuniteApiClient({ domain: testDomain, apiKey: testToken, version, command }); + apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command }); }); it('should push to remote', async () => { @@ -284,4 +286,165 @@ describe('ApiClient', () => { ).rejects.toThrow(new ReuniteApiError('Failed to push. Not found.', 404)); }); }); + + describe('Sunset header', () => { + const upsertRemoteMock = { + requestFn: () => + apiClient.remotes.upsert(testOrg, testProject, { + mountBranchName: 'remote-mount-branch-name', + mountPath: 'remote-mount-path', + }), + responseBody: { + id: 'remote-id', + type: 'CICD', + mountPath: 'remote-mount-path', + mountBranchName: 'remote-mount-branch-name', + organizationId: testOrg, + projectId: testProject, + }, + }; + + const getDefaultBranchMock = { + requestFn: () => apiClient.remotes.getDefaultBranch(testOrg, testProject), + responseBody: { + branchName: 'test-branch', + }, + }; + + const pushMock = { + requestFn: () => + apiClient.remotes.push( + testOrg, + testProject, + { + remoteId: 'test-remote-id', + commit: { + message: 'test-message', + author: { + name: 'test-name', + email: 'test-email', + }, + branchName: 'test-branch-name', + }, + }, + [{ path: 'some-file.yaml', stream: Buffer.from('text content') }] + ), + responseBody: { + branchName: 'rem/cicd/rem_01he7sr6ys2agb7w0g9t7978fn-main', + hasChanges: true, + files: [ + { + type: 'file', + name: 'some-file.yaml', + path: 'docs/remotes/some-file.yaml', + lastModified: 1698925132394.2993, + mimeType: 'text/yaml', + }, + ], + commitSha: 'bb23a2f8e012ac0b7b9961b57fb40d8686b21b43', + outdated: false, + }, + }; + + const endpointMocks = [upsertRemoteMock, getDefaultBranchMock, pushMock]; + + let apiClient: ReuniteApi; + + beforeEach(() => { + apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command }); + }); + + it.each(endpointMocks)( + 'should report endpoint sunset in the past', + async ({ responseBody, requestFn }) => { + jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true); + const sunsetDate = new Date('2024-09-06T12:30:32.456Z'); + + mockFetchResponse({ + ok: true, + json: jest.fn().mockResolvedValue(responseBody), + headers: new Headers({ + Sunset: sunsetDate.toISOString(), + }), + }); + + await requestFn(); + apiClient.reportSunsetWarnings(); + + expect(process.stdout.write).toHaveBeenCalledWith( + red( + `The "push" command is not compatible with your version of Redocly CLI. Update to the latest version by running "npm install @redocly/cli@latest".\n\n` + ) + ); + } + ); + + it.each(endpointMocks)( + 'should report endpoint sunset in the future', + async ({ responseBody, requestFn }) => { + jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true); + const sunsetDate = new Date(Date.now() + 1000 * 60 * 60 * 24); + + mockFetchResponse({ + ok: true, + json: jest.fn().mockResolvedValue(responseBody), + headers: new Headers({ + Sunset: sunsetDate.toISOString(), + }), + }); + + await requestFn(); + apiClient.reportSunsetWarnings(); + + expect(process.stdout.write).toHaveBeenCalledWith( + yellow( + `The "push" command will be incompatible with your version of Redocly CLI after ${sunsetDate.toLocaleString()}. Update to the latest version by running "npm install @redocly/cli@latest".\n\n` + ) + ); + } + ); + + it('should report only expired resource', async () => { + jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true); + + mockFetchResponse({ + ok: true, + json: jest.fn().mockResolvedValue(upsertRemoteMock.responseBody), + headers: new Headers({ + Sunset: new Date('2024-08-06T12:30:32.456Z').toISOString(), + }), + }); + + await upsertRemoteMock.requestFn(); + + mockFetchResponse({ + ok: true, + json: jest.fn().mockResolvedValue(getDefaultBranchMock.responseBody), + headers: new Headers({ + Sunset: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), + }), + }); + + await getDefaultBranchMock.requestFn(); + + mockFetchResponse({ + ok: true, + json: jest.fn().mockResolvedValue(pushMock.responseBody), + headers: new Headers({ + Sunset: new Date('2024-08-06T12:30:32.456Z').toISOString(), + }), + }); + + await pushMock.requestFn(); + + apiClient.reportSunsetWarnings(); + + expect(process.stdout.write).toHaveBeenCalledTimes(1); + expect(process.stdout.write).toHaveBeenCalledWith( + red( + `The "push" command is not compatible with your version of Redocly CLI. Update to the latest version by running "npm install @redocly/cli@latest".\n\n` + ) + ); + }); + }); }); diff --git a/packages/cli/src/cms/api/api-client.ts b/packages/cli/src/cms/api/api-client.ts index bdf790bfb3..3cd0fa5679 100644 --- a/packages/cli/src/cms/api/api-client.ts +++ b/packages/cli/src/cms/api/api-client.ts @@ -1,3 +1,4 @@ +import { yellow, red } from 'colorette'; import * as FormData from 'form-data'; import fetchWithTimeout, { type FetchWithTimeoutOptions, @@ -13,54 +14,100 @@ import type { UpsertRemoteResponse, } from './types'; +interface BaseApiClient { + request(url: string, options: FetchWithTimeoutOptions): Promise; +} +type CommandOption = 'push' | 'push-status'; +export type SunsetWarning = { sunsetDate: Date; isSunsetExpired: boolean }; +export type SunsetWarningsBuffer = SunsetWarning[]; + export class ReuniteApiError extends Error { constructor(message: string, public status: number) { super(message); } } -class ReuniteBaseApiClient { - constructor(protected version: string, protected command: string) {} - - protected async getParsedResponse(response: Response): Promise { - const responseBody = await response.json(); - - if (response.ok) { - return responseBody as T; - } +class ReuniteApiClient implements BaseApiClient { + public sunsetWarnings: SunsetWarningsBuffer = []; - throw new ReuniteApiError( - `${responseBody.title || response.statusText || 'Unknown error'}.`, - response.status - ); - } + constructor(protected version: string, protected command: string) {} - protected request(url: string, options: FetchWithTimeoutOptions) { + public async request(url: string, options: FetchWithTimeoutOptions) { const headers = { ...options.headers, 'user-agent': `redocly-cli/${this.version.trim()} ${this.command}`, }; - return fetchWithTimeout(url, { + const response = await fetchWithTimeout(url, { ...options, headers, }); + + this.collectSunsetWarning(response); + + return response; + } + + private collectSunsetWarning(response: Response) { + const sunsetTime = this.getSunsetDate(response); + + if (!sunsetTime) return; + + const sunsetDate = new Date(sunsetTime); + + if (sunsetTime > Date.now()) { + this.sunsetWarnings.push({ + sunsetDate, + isSunsetExpired: false, + }); + } else { + this.sunsetWarnings.push({ + sunsetDate, + isSunsetExpired: true, + }); + } + } + + private getSunsetDate(response: Response): number | undefined { + const { headers } = response; + + if (!headers) { + return; + } + + const sunsetDate = headers.get('sunset') || headers.get('Sunset'); + + if (!sunsetDate) { + return; + } + + return Date.parse(sunsetDate); } } -class RemotesApiClient extends ReuniteBaseApiClient { +class RemotesApi { constructor( + private client: BaseApiClient, private readonly domain: string, - private readonly apiKey: string, - version: string, - command: string - ) { - super(version, command); + private readonly apiKey: string + ) {} + + protected async getParsedResponse(response: Response): Promise { + const responseBody = await response.json(); + + if (response.ok) { + return responseBody as T; + } + + throw new ReuniteApiError( + `${responseBody.title || response.statusText || 'Unknown error'}.`, + response.status + ); } async getDefaultBranch(organizationId: string, projectId: string) { try { - const response = await this.request( + const response = await this.client.request( `${this.domain}/api/orgs/${organizationId}/projects/${projectId}/source`, { timeout: DEFAULT_FETCH_TIMEOUT, @@ -95,7 +142,7 @@ class RemotesApiClient extends ReuniteBaseApiClient { } ): Promise { try { - const response = await this.request( + const response = await this.client.request( `${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes`, { timeout: DEFAULT_FETCH_TIMEOUT, @@ -150,7 +197,7 @@ class RemotesApiClient extends ReuniteBaseApiClient { payload.isMainBranch && formData.append('isMainBranch', 'true'); try { - const response = await this.request( + const response = await this.client.request( `${this.domain}/api/orgs/${organizationId}/projects/${projectId}/pushes`, { method: 'POST', @@ -183,7 +230,7 @@ class RemotesApiClient extends ReuniteBaseApiClient { mountPath: string; }) { try { - const response = await this.request( + const response = await this.client.request( `${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes?filter=mountPath:/${mountPath}/`, { timeout: DEFAULT_FETCH_TIMEOUT, @@ -217,7 +264,7 @@ class RemotesApiClient extends ReuniteBaseApiClient { pushId: string; }) { try { - const response = await this.request( + const response = await this.client.request( `${this.domain}/api/orgs/${organizationId}/projects/${projectId}/pushes/${pushId}`, { timeout: DEFAULT_FETCH_TIMEOUT, @@ -242,8 +289,12 @@ class RemotesApiClient extends ReuniteBaseApiClient { } } -export class ReuniteApiClient { - remotes: RemotesApiClient; +export class ReuniteApi { + private apiClient: ReuniteApiClient; + private version: string; + private command: CommandOption; + + public remotes: RemotesApi; constructor({ domain, @@ -254,9 +305,49 @@ export class ReuniteApiClient { domain: string; apiKey: string; version: string; - command: 'push' | 'push-status'; + command: CommandOption; }) { - this.remotes = new RemotesApiClient(domain, apiKey, version, command); + this.command = command; + this.version = version; + this.apiClient = new ReuniteApiClient(this.version, this.command); + + this.remotes = new RemotesApi(this.apiClient, domain, apiKey); + } + + public reportSunsetWarnings(): void { + const sunsetWarnings = this.apiClient.sunsetWarnings; + + if (sunsetWarnings.length) { + const [{ isSunsetExpired, sunsetDate }] = sunsetWarnings.sort( + (a: SunsetWarning, b: SunsetWarning) => { + // First, prioritize by expiration status + if (a.isSunsetExpired !== b.isSunsetExpired) { + return a.isSunsetExpired ? -1 : 1; + } + + // If both are either expired or not, sort by sunset date + return a.sunsetDate > b.sunsetDate ? 1 : -1; + } + ); + + const updateVersionMessage = `Update to the latest version by running "npm install @redocly/cli@latest".`; + + if (isSunsetExpired) { + process.stdout.write( + red( + `The "${this.command}" command is not compatible with your version of Redocly CLI. ${updateVersionMessage}\n\n` + ) + ); + } else { + process.stdout.write( + yellow( + `The "${ + this.command + }" command will be incompatible with your version of Redocly CLI after ${sunsetDate.toLocaleString()}. ${updateVersionMessage}\n\n` + ) + ); + } + } } } diff --git a/packages/cli/src/cms/commands/__tests__/push-status.test.ts b/packages/cli/src/cms/commands/__tests__/push-status.test.ts index db02dcbc57..f36a7a34d5 100644 --- a/packages/cli/src/cms/commands/__tests__/push-status.test.ts +++ b/packages/cli/src/cms/commands/__tests__/push-status.test.ts @@ -17,8 +17,9 @@ jest.mock('colorette', () => ({ jest.mock('../../api', () => ({ ...jest.requireActual('../../api'), - ReuniteApiClient: jest.fn().mockImplementation(function (this: any, ...args) { + ReuniteApi: jest.fn().mockImplementation(function (this: any, ...args) { this.remotes = remotes; + this.reportSunsetWarnings = jest.fn(); }), })); diff --git a/packages/cli/src/cms/commands/__tests__/push.test.ts b/packages/cli/src/cms/commands/__tests__/push.test.ts index 31870d69f3..d6deda2378 100644 --- a/packages/cli/src/cms/commands/__tests__/push.test.ts +++ b/packages/cli/src/cms/commands/__tests__/push.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { handlePush } from '../push'; -import { ReuniteApiClient, ReuniteApiError } from '../../api'; +import { ReuniteApi, ReuniteApiError } from '../../api'; const remotes = { push: jest.fn(), @@ -15,8 +15,9 @@ jest.mock('@redocly/openapi-core', () => ({ jest.mock('../../api', () => ({ ...jest.requireActual('../../api'), - ReuniteApiClient: jest.fn().mockImplementation(function (this: any, ...args) { + ReuniteApi: jest.fn().mockImplementation(function (this: any, ...args) { this.remotes = remotes; + this.reportSunsetWarnings = jest.fn(); }), })); @@ -332,7 +333,7 @@ describe('handlePush()', () => { version: 'cli-version', }); - expect(ReuniteApiClient).toBeCalledWith({ + expect(ReuniteApi).toBeCalledWith({ domain: 'test-domain-from-env', apiKey: 'test-api-key', version: 'cli-version', diff --git a/packages/cli/src/cms/commands/push-status.ts b/packages/cli/src/cms/commands/push-status.ts index f819d18c16..7ead68340c 100644 --- a/packages/cli/src/cms/commands/push-status.ts +++ b/packages/cli/src/cms/commands/push-status.ts @@ -2,7 +2,7 @@ import * as colors from 'colorette'; import { exitWithError, printExecutionTime } from '../../utils/miscellaneous'; import { Spinner } from '../../utils/spinner'; import { DeploymentError } from '../utils'; -import { ReuniteApiClient, getApiKeys, getDomain } from '../api'; +import { ReuniteApi, getApiKeys, getDomain } from '../api'; import { capitalize } from '../../utils/js-utils'; import { handleReuniteError, retryUntilConditionMet } from './utils'; @@ -68,7 +68,7 @@ export async function handlePushStatus({ try { const apiKey = getApiKeys(domain); - const client = new ReuniteApiClient({ domain, apiKey, version, command: 'push-status' }); + const client = new ReuniteApi({ domain, apiKey, version, command: 'push-status' }); let pushResponse: PushResponse; @@ -169,6 +169,8 @@ export async function handlePushStatus({ } printPushStatusInfo({ orgId, projectId, pushId, startedAt }); + client.reportSunsetWarnings(); + const summary: PushStatusSummary = { preview: pushResponse.status.preview, production: pushResponse.isMainBranch ? pushResponse.status.production : null, diff --git a/packages/cli/src/cms/commands/push.ts b/packages/cli/src/cms/commands/push.ts index bef249c0b4..0d5cee5ac0 100644 --- a/packages/cli/src/cms/commands/push.ts +++ b/packages/cli/src/cms/commands/push.ts @@ -5,7 +5,7 @@ import { pluralize } from '@redocly/openapi-core/lib/utils'; import { green, yellow } from 'colorette'; import { exitWithError, printExecutionTime } from '../../utils/miscellaneous'; import { handlePushStatus } from './push-status'; -import { ReuniteApiClient, getDomain, getApiKeys } from '../api'; +import { ReuniteApi, getDomain, getApiKeys } from '../api'; import { handleReuniteError } from './utils'; import type { OutputFormat } from '@redocly/openapi-core'; @@ -81,12 +81,13 @@ export async function handlePush({ const author = parseCommitAuthor(argv.author); const apiKey = getApiKeys(domain); const filesToUpload = collectFilesToPush(argv.files || argv.apis); + const commandName = 'push' as const; if (!filesToUpload.length) { - return printExecutionTime('push', startedAt, `No files to upload`); + return printExecutionTime(commandName, startedAt, `No files to upload`); } - const client = new ReuniteApiClient({ domain, apiKey, version, command: 'push' }); + const client = new ReuniteApi({ domain, apiKey, version, command: commandName }); const projectDefaultBranch = await client.remotes.getDefaultBranch(orgId, projectId); const remote = await client.remotes.upsert(orgId, projectId, { mountBranchName: projectDefaultBranch, @@ -147,7 +148,7 @@ export async function handlePush({ } verbose && printExecutionTime( - 'push', + commandName, startedAt, `${pluralize( 'file', @@ -155,6 +156,8 @@ export async function handlePush({ )} uploaded to organization ${orgId}, project ${projectId}. Push ID: ${id}.` ); + client.reportSunsetWarnings(); + return { pushId: id, }; From e677c17aabc0022767af8d8e258622e6bdd23ca9 Mon Sep 17 00:00:00 2001 From: Adam Altman Date: Sun, 29 Sep 2024 13:36:45 -0500 Subject: [PATCH 09/14] docs: fix typo in url (#1744) --- docs/commands/push.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/commands/push.md b/docs/commands/push.md index 2074ed9d6e..b58d8a1289 100644 --- a/docs/commands/push.md +++ b/docs/commands/push.md @@ -21,7 +21,7 @@ Have the following values ready to use with the `push` command: - An active organization [API key](https://redocly.com/docs/realm/setup/how-to/api-keys). - [Redocly CLI](../installation.md) installed. -Use the `REDOCLY_AUTHORIZATION` environment variable to set the API key. See the [Manage API keys](https://redocly.com/docs/realm//setup/how-to/api-keys) page in the documentation for details on how to get your API key in Reunite. +Use the `REDOCLY_AUTHORIZATION` environment variable to set the API key. See the [Manage API keys](https://redocly.com/docs/realm/setup/how-to/api-keys) page in the documentation for details on how to get your API key in Reunite. ## Command usage From ee7e7d8d72d5112fbf6dce14cf57df3ee3cab40f Mon Sep 17 00:00:00 2001 From: Dmytro Anansky Date: Mon, 30 Sep 2024 12:17:58 +0300 Subject: [PATCH 10/14] chore: updated redocly/config to v0.12.1 (#1746) --- .changeset/flat-cows-laugh.md | 5 +++++ package-lock.json | 16 ++++++++-------- packages/core/package.json | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 .changeset/flat-cows-laugh.md diff --git a/.changeset/flat-cows-laugh.md b/.changeset/flat-cows-laugh.md new file mode 100644 index 0000000000..33d83e571f --- /dev/null +++ b/.changeset/flat-cows-laugh.md @@ -0,0 +1,5 @@ +--- +"@redocly/openapi-core": patch +--- + +Updated @redocly/config to v0.12.1. diff --git a/package-lock.json b/package-lock.json index dbeb2a3c08..cae1ab2eb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3525,9 +3525,9 @@ "link": true }, "node_modules/@redocly/config": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.11.0.tgz", - "integrity": "sha512-vAc77vCuWsVgLx2LN02P6jqLBhHuot6O1LsSJEAAkWEvXARSGSQVon50QW7jlbCMg9OFTYYYRPN4W6K/YmnM3w==" + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.12.1.tgz", + "integrity": "sha512-RW3rSirfsPdr0uvATijRDU3f55SuZV3m7/ppdTDvGw4IB0cmeZRkFmqTrchxMqWP50Gfg1tpHnjdxUCNo0E2qg==" }, "node_modules/@redocly/openapi-core": { "resolved": "packages/core", @@ -13800,7 +13800,7 @@ "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.11.0", + "@redocly/config": "^0.12.1", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.4", "js-levenshtein": "^1.1.6", @@ -16502,15 +16502,15 @@ } }, "@redocly/config": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.11.0.tgz", - "integrity": "sha512-vAc77vCuWsVgLx2LN02P6jqLBhHuot6O1LsSJEAAkWEvXARSGSQVon50QW7jlbCMg9OFTYYYRPN4W6K/YmnM3w==" + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.12.1.tgz", + "integrity": "sha512-RW3rSirfsPdr0uvATijRDU3f55SuZV3m7/ppdTDvGw4IB0cmeZRkFmqTrchxMqWP50Gfg1tpHnjdxUCNo0E2qg==" }, "@redocly/openapi-core": { "version": "file:packages/core", "requires": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.11.0", + "@redocly/config": "^0.12.1", "@types/js-levenshtein": "^1.1.0", "@types/js-yaml": "^4.0.3", "@types/lodash.isequal": "^4.5.5", diff --git a/packages/core/package.json b/packages/core/package.json index 8bb77a6899..ffae13cdab 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,7 +36,7 @@ ], "dependencies": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.11.0", + "@redocly/config": "^0.12.1", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.4", "js-levenshtein": "^1.1.6", From bdc3cb1d154299d7bc7e9c69ef0454942886e12c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 12:29:10 +0300 Subject: [PATCH 11/14] =?UTF-8?q?chore:=20=F0=9F=94=96=20release=20new=20v?= =?UTF-8?q?ersions=20(#1745)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/flat-cows-laugh.md | 5 ----- .changeset/tiny-boats-check.md | 5 ----- docs/changelog.md | 7 +++++++ package-lock.json | 8 ++++---- packages/cli/CHANGELOG.md | 7 +++++++ packages/cli/package.json | 4 ++-- packages/core/CHANGELOG.md | 6 ++++++ packages/core/package.json | 2 +- 8 files changed, 27 insertions(+), 17 deletions(-) delete mode 100644 .changeset/flat-cows-laugh.md delete mode 100644 .changeset/tiny-boats-check.md diff --git a/.changeset/flat-cows-laugh.md b/.changeset/flat-cows-laugh.md deleted file mode 100644 index 33d83e571f..0000000000 --- a/.changeset/flat-cows-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@redocly/openapi-core": patch ---- - -Updated @redocly/config to v0.12.1. diff --git a/.changeset/tiny-boats-check.md b/.changeset/tiny-boats-check.md deleted file mode 100644 index 8cb64ea58c..0000000000 --- a/.changeset/tiny-boats-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@redocly/cli": patch ---- - -Added a warning message to the `push` and `push-status` commands to notify users about upcoming or ongoing resource deprecation. diff --git a/docs/changelog.md b/docs/changelog.md index 0e6c14eb91..e562b0b350 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,13 @@ toc: +## 1.25.4 (2024-09-30) + +### Patch Changes + +- Added a warning message to the `push` and `push-status` commands to notify users about upcoming or ongoing resource deprecation. +- Updated @redocly/openapi-core to v1.25.4. + ## 1.25.3 (2024-09-18) ### Patch Changes diff --git a/package-lock.json b/package-lock.json index cae1ab2eb5..4cfd8d03d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13739,10 +13739,10 @@ }, "packages/cli": { "name": "@redocly/cli", - "version": "1.25.3", + "version": "1.25.4", "license": "MIT", "dependencies": { - "@redocly/openapi-core": "1.25.3", + "@redocly/openapi-core": "1.25.4", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", @@ -13796,7 +13796,7 @@ }, "packages/core": { "name": "@redocly/openapi-core", - "version": "1.25.3", + "version": "1.25.4", "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", @@ -16460,7 +16460,7 @@ "@redocly/cli": { "version": "file:packages/cli", "requires": { - "@redocly/openapi-core": "1.25.3", + "@redocly/openapi-core": "1.25.4", "@types/configstore": "^5.0.1", "@types/glob": "^8.1.0", "@types/pluralize": "^0.0.29", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 18f4ae4c80..e15971a74e 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # @redocly/cli +## 1.25.4 + +### Patch Changes + +- Added a warning message to the `push` and `push-status` commands to notify users about upcoming or ongoing resource deprecation. +- Updated @redocly/openapi-core to v1.25.4. + ## 1.25.3 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 8e94e87e14..746c7fb979 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/cli", - "version": "1.25.3", + "version": "1.25.4", "description": "", "license": "MIT", "bin": { @@ -36,7 +36,7 @@ "Roman Hotsiy (https://redoc.ly/)" ], "dependencies": { - "@redocly/openapi-core": "1.25.3", + "@redocly/openapi-core": "1.25.4", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e09d57b9bd..08c755e544 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @redocly/openapi-core +## 1.25.4 + +### Patch Changes + +- Updated @redocly/config to v0.12.1. + ## 1.25.3 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index ffae13cdab..78c00c3647 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@redocly/openapi-core", - "version": "1.25.3", + "version": "1.25.4", "description": "", "main": "lib/index.js", "engines": { From 6d2a14194c0ed1a44febf179f6688c7e673be317 Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Thu, 3 Oct 2024 01:49:20 +0000 Subject: [PATCH 12/14] adjusted replace value --- packages/cli/src/utils/miscellaneous.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/utils/miscellaneous.ts b/packages/cli/src/utils/miscellaneous.ts index dd1243c3e6..8826e5c331 100644 --- a/packages/cli/src/utils/miscellaneous.ts +++ b/packages/cli/src/utils/miscellaneous.ts @@ -131,7 +131,7 @@ export function printExecutionTime(commandName: string, startedAt: number, api: export function pathToFilename(path: string, pathSeparator: string) { if (path === '/') { - return 'root'; + return '~root'; } return path .replace(/~1/g, '/') From f63f4000527ab535ef1fb7b13e196fe0518f98f4 Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Thu, 3 Oct 2024 02:01:29 +0000 Subject: [PATCH 13/14] adding root endpoint test --- __tests__/split/root-endpoint/openapi.yaml | 111 +++++++++++++++++++ __tests__/split/root-endpoint/snapshot.js | 119 +++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 __tests__/split/root-endpoint/openapi.yaml create mode 100644 __tests__/split/root-endpoint/snapshot.js diff --git a/__tests__/split/root-endpoint/openapi.yaml b/__tests__/split/root-endpoint/openapi.yaml new file mode 100644 index 0000000000..1af9b9276c --- /dev/null +++ b/__tests__/split/root-endpoint/openapi.yaml @@ -0,0 +1,111 @@ +openapi: '3.0.0' +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /: + get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: A paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pets' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + '201': + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: '#/components/schemas/Pet' + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/__tests__/split/root-endpoint/snapshot.js b/__tests__/split/root-endpoint/snapshot.js new file mode 100644 index 0000000000..656991106f --- /dev/null +++ b/__tests__/split/root-endpoint/snapshot.js @@ -0,0 +1,119 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`E2E split with root endpoint 1`] = ` + +type: object +required: + - id + - name +properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string +type: array +items: + $ref: ./Pet.yaml +type: object +required: + - code + - message +properties: + code: + type: integer + format: int32 + message: + type: string +get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: A paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pets' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + '201': + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +openapi: 3.0.0 +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /: + $ref: paths/pets.yaml + /pets/{petId}: + $ref: paths/pets/{petId}.yaml +🪓 Document: ../../../__tests__/split/root-endpoint/openapi.yaml is successfully split + and all related files are saved to the directory: output + +../../../__tests__/split/root-endpoint/openapi.yaml: split processed in ms + + +`; From 3003f7f8d3d65e40d0f056b2aa5655312e38793c Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Mon, 7 Oct 2024 13:14:43 +0000 Subject: [PATCH 14/14] Added changeset --- .changeset/famous-dolphins-laugh.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/famous-dolphins-laugh.md diff --git a/.changeset/famous-dolphins-laugh.md b/.changeset/famous-dolphins-laugh.md new file mode 100644 index 0000000000..e5ed52429c --- /dev/null +++ b/.changeset/famous-dolphins-laugh.md @@ -0,0 +1,5 @@ +--- +"@redocly/cli": patch +--- + +Adjusted CLI to properly handle root level paths during split operations