From 569b185b8c63b4875018af1d6186068cfea2fa04 Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sat, 10 Aug 2024 10:06:36 -0400 Subject: [PATCH 01/13] add validation around selectable environments for playground settings --- .../src/ApiReferenceNodeConverter.ts | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts index 6a8a780c839..9f899f33c05 100644 --- a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts +++ b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts @@ -654,18 +654,37 @@ export class ApiReferenceNodeConverter { playgroundSettings?: docsYml.RawSchemas.PlaygroundSettings ): FernNavigation.PlaygroundSettings | undefined { if (playgroundSettings) { + const maybeApiSpecificationEnvironments = this.workspace.definition.rootApiFile.contents.environments; + if (!maybeApiSpecificationEnvironments) { + this.taskContext.logger.error( + "Cannot specify playground environments if there are no environments supplied in the API specification." + ); + } else { + const validEnvironmentIds = Object.keys(maybeApiSpecificationEnvironments); + playgroundSettings.environments?.forEach((environment) => { + if (!validEnvironmentIds.includes(environment)) { + this.taskContext.logger.error( + `Invalid environment id supplied in playground settings: ${environment}` + ); + } + }); + } + return { environments: - playgroundSettings.environments && - playgroundSettings.environments.map((environmentId) => FernNavigation.EnvironmentId(environmentId)), + playgroundSettings.environments && playgroundSettings.environments.length > 0 + ? playgroundSettings.environments.map((environmentId) => + FernNavigation.EnvironmentId(environmentId) + ) + : undefined, button: - playgroundSettings.button && playgroundSettings.button.href + playgroundSettings.button != null && playgroundSettings.button.href ? { href: FernNavigation.Url(playgroundSettings.button.href) } : undefined }; - } else { - return undefined; } + + return; } private mergeEndpointPairs(children: FernNavigation.ApiPackageChild[]): FernNavigation.ApiPackageChild[] { From 71f63f05e3692ecaebd7ea1f58ee3d4b4fc56f7a Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sat, 10 Aug 2024 10:12:54 -0400 Subject: [PATCH 02/13] add explicit not null check --- packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts index 9f899f33c05..9d563ec07dd 100644 --- a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts +++ b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts @@ -672,7 +672,7 @@ export class ApiReferenceNodeConverter { return { environments: - playgroundSettings.environments && playgroundSettings.environments.length > 0 + playgroundSettings.environments != null && playgroundSettings.environments.length > 0 ? playgroundSettings.environments.map((environmentId) => FernNavigation.EnvironmentId(environmentId) ) From 387c7ec726ba7847f5f86af6730d0e8bc9d47e3b Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sun, 11 Aug 2024 23:13:24 -0400 Subject: [PATCH 03/13] move to rule --- .../src/ApiReferenceNodeConverter.ts | 16 -------- .../src/docsAst/DocsConfigFileAstVisitor.ts | 7 +++- .../src/docsAst/visitDocsConfigFileAst.ts | 26 +++++++++---- .../yaml/docs-validator/src/getAllRules.ts | 4 +- .../playground-environments-exist/index.ts | 1 + .../playground-environments-exist.ts | 38 +++++++++++++++++++ 6 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/index.ts create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts diff --git a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts index 9d563ec07dd..64710bf2c50 100644 --- a/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts +++ b/packages/cli/docs-resolver/src/ApiReferenceNodeConverter.ts @@ -654,22 +654,6 @@ export class ApiReferenceNodeConverter { playgroundSettings?: docsYml.RawSchemas.PlaygroundSettings ): FernNavigation.PlaygroundSettings | undefined { if (playgroundSettings) { - const maybeApiSpecificationEnvironments = this.workspace.definition.rootApiFile.contents.environments; - if (!maybeApiSpecificationEnvironments) { - this.taskContext.logger.error( - "Cannot specify playground environments if there are no environments supplied in the API specification." - ); - } else { - const validEnvironmentIds = Object.keys(maybeApiSpecificationEnvironments); - playgroundSettings.environments?.forEach((environment) => { - if (!validEnvironmentIds.includes(environment)) { - this.taskContext.logger.error( - `Invalid environment id supplied in playground settings: ${environment}` - ); - } - }); - } - return { environments: playgroundSettings.environments != null && playgroundSettings.environments.length > 0 diff --git a/packages/cli/yaml/docs-validator/src/docsAst/DocsConfigFileAstVisitor.ts b/packages/cli/yaml/docs-validator/src/docsAst/DocsConfigFileAstVisitor.ts index ffbca9d0c8e..5c86e02a6c6 100644 --- a/packages/cli/yaml/docs-validator/src/docsAst/DocsConfigFileAstVisitor.ts +++ b/packages/cli/yaml/docs-validator/src/docsAst/DocsConfigFileAstVisitor.ts @@ -1,5 +1,6 @@ import { docsYml } from "@fern-api/configuration"; import { AbsoluteFilePath } from "@fern-api/fs-utils"; +import { TaskContext } from "@fern-api/task-context"; import { AbstractAPIWorkspace } from "@fern-api/workspace-loader"; import { NodePath } from "@fern-api/yaml-schema"; @@ -16,7 +17,11 @@ export interface DocsConfigFileAstNodeTypes { }; markdownPage: { title: string; content: string; absoluteFilepath: AbsoluteFilePath }; versionFile: { path: string; content: unknown }; - apiSection: { config: docsYml.RawSchemas.ApiReferenceConfiguration; workspace: AbstractAPIWorkspace }; + apiSection: { + config: docsYml.RawSchemas.ApiReferenceConfiguration; + workspace: AbstractAPIWorkspace; + context: TaskContext; + }; } export type DocsConfigFileAstNodeVisitor> = ( diff --git a/packages/cli/yaml/docs-validator/src/docsAst/visitDocsConfigFileAst.ts b/packages/cli/yaml/docs-validator/src/docsAst/visitDocsConfigFileAst.ts index 05e6bf0266a..a5c6349611f 100644 --- a/packages/cli/yaml/docs-validator/src/docsAst/visitDocsConfigFileAst.ts +++ b/packages/cli/yaml/docs-validator/src/docsAst/visitDocsConfigFileAst.ts @@ -184,7 +184,8 @@ export async function visitDocsConfigFileYamlAst( visitor, nodePath: ["navigation"], absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }); } @@ -270,7 +271,8 @@ export async function visitDocsConfigFileYamlAst( visitor, nodePath: ["navigation"], absoluteFilepathToConfiguration: absoluteFilepath, - loadAPIWorkspace + loadAPIWorkspace, + context }); } }) @@ -307,13 +309,15 @@ async function visitNavigation({ visitor, nodePath, absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }: { navigation: docsYml.RawSchemas.NavigationConfig; visitor: Partial; nodePath: NodePath; absoluteFilepathToConfiguration: AbsoluteFilePath; loadAPIWorkspace: APIWorkspaceLoader; + context: TaskContext; }): Promise { if (navigationConfigIsTabbed(navigation)) { await Promise.all( @@ -326,7 +330,8 @@ async function visitNavigation({ visitor, nodePath: [...nodePath, `${tabIdx}`, "layout", `${itemIdx}`], absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }); }) ); @@ -341,7 +346,8 @@ async function visitNavigation({ visitor, nodePath: [...nodePath, `${itemIdx}`], absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }); }) ); @@ -353,13 +359,15 @@ async function visitNavigationItem({ visitor, nodePath, absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }: { navigationItem: docsYml.RawSchemas.NavigationItem; visitor: Partial; nodePath: NodePath; absoluteFilepathToConfiguration: AbsoluteFilePath; loadAPIWorkspace: APIWorkspaceLoader; + context: TaskContext; }): Promise { if (navigationItemIsPage(navigationItem)) { await visitFilepath({ @@ -391,7 +399,8 @@ async function visitNavigationItem({ visitor, nodePath: [...nodePath, "section", "contents", `${itemIdx}`], absoluteFilepathToConfiguration, - loadAPIWorkspace + loadAPIWorkspace, + context }); }) ); @@ -403,7 +412,8 @@ async function visitNavigationItem({ await visitor.apiSection?.( { config: navigationItem, - workspace + workspace, + context }, [...nodePath, "api"] ); diff --git a/packages/cli/yaml/docs-validator/src/getAllRules.ts b/packages/cli/yaml/docs-validator/src/getAllRules.ts index 335b0906a38..d08334cc295 100644 --- a/packages/cli/yaml/docs-validator/src/getAllRules.ts +++ b/packages/cli/yaml/docs-validator/src/getAllRules.ts @@ -2,6 +2,7 @@ import { Rule } from "./Rule"; import { AccentColorContrastRule } from "./rules/accent-color-contrast"; import { FilepathsExistRule } from "./rules/filepaths-exist"; import { OnlyVersionedNavigation } from "./rules/only-versioned-navigation"; +import { PlaygroundEnvironmentsExistRule } from "./rules/playground-environments-exist"; import { ValidFileTypes } from "./rules/valid-file-types"; import { ValidMarkdownRule } from "./rules/valid-markdown"; import { ValidMarkdownLinks } from "./rules/valid-markdown-link"; @@ -15,6 +16,7 @@ export function getAllRules(): Rule[] { ValidateVersionFileRule, AccentColorContrastRule, ValidMarkdownLinks, - ValidFileTypes + ValidFileTypes, + PlaygroundEnvironmentsExistRule ]; } diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/index.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/index.ts new file mode 100644 index 00000000000..a18ecbcbc69 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/index.ts @@ -0,0 +1 @@ +export { PlaygroundEnvironmentsExistRule } from "./playground-environments-exist"; diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts new file mode 100644 index 00000000000..99434b43615 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -0,0 +1,38 @@ +import { Rule, RuleViolation } from "../../Rule"; + +export const PlaygroundEnvironmentsExistRule: Rule = { + name: "environments-exist", + create: () => { + return { + apiSection: async ({ workspace, context, config }) => { + const maybeApiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile + .contents.environments; + const apiSectionPlaygroundEnvironmentIds = config.playground?.environments; + if (!maybeApiSpecificationEnvironments) { + if (apiSectionPlaygroundEnvironmentIds && apiSectionPlaygroundEnvironmentIds.length > 0) { + return [ + { + severity: "error", + message: `Cannot specify playground environments if there are no environments supplied in the API specification.` + } + ]; + } + } else { + const availableEnvironmentIds = new Set(Object.keys(maybeApiSpecificationEnvironments)); + const violations: RuleViolation[] = []; + apiSectionPlaygroundEnvironmentIds?.forEach((environmentId) => { + if (!availableEnvironmentIds.has(environmentId)) { + violations.push({ + severity: "error", + message: `Invalid environment id supplied in playground settings: ${environmentId}` + }); + } + }); + return violations; + } + + return []; + } + }; + } +}; From 8fc91c23195ba60b963312a721d4634827996124 Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sun, 11 Aug 2024 23:27:26 -0400 Subject: [PATCH 04/13] beat linter --- .../playground-environments-exist.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index 99434b43615..d2fc3419b1e 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -1,7 +1,7 @@ import { Rule, RuleViolation } from "../../Rule"; export const PlaygroundEnvironmentsExistRule: Rule = { - name: "environments-exist", + name: "playground-environments-exist", create: () => { return { apiSection: async ({ workspace, context, config }) => { @@ -13,7 +13,8 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return [ { severity: "error", - message: `Cannot specify playground environments if there are no environments supplied in the API specification.` + message: + "Cannot specify playground environments if there are no environments supplied in the API specification." } ]; } From 834f08da2a40dddc61192ecd9dad0d01638343bb Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sun, 11 Aug 2024 23:32:27 -0400 Subject: [PATCH 05/13] simplify conditions --- .../playground-environments-exist.ts | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index d2fc3419b1e..280173fbe99 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -2,38 +2,32 @@ import { Rule, RuleViolation } from "../../Rule"; export const PlaygroundEnvironmentsExistRule: Rule = { name: "playground-environments-exist", - create: () => { - return { - apiSection: async ({ workspace, context, config }) => { - const maybeApiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile - .contents.environments; - const apiSectionPlaygroundEnvironmentIds = config.playground?.environments; - if (!maybeApiSpecificationEnvironments) { - if (apiSectionPlaygroundEnvironmentIds && apiSectionPlaygroundEnvironmentIds.length > 0) { - return [ - { - severity: "error", - message: - "Cannot specify playground environments if there are no environments supplied in the API specification." - } - ]; - } - } else { - const availableEnvironmentIds = new Set(Object.keys(maybeApiSpecificationEnvironments)); - const violations: RuleViolation[] = []; - apiSectionPlaygroundEnvironmentIds?.forEach((environmentId) => { - if (!availableEnvironmentIds.has(environmentId)) { - violations.push({ - severity: "error", - message: `Invalid environment id supplied in playground settings: ${environmentId}` - }); + create: () => ({ + apiSection: async ({ workspace, context, config }) => { + const apiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile.contents.environments; + const playgroundEnvironmentIds = config.playground?.environments || []; + + if (!apiSpecificationEnvironments) { + if (playgroundEnvironmentIds.length > 0) { + return [ + { + severity: "error", + message: "Cannot specify playground environments if there are no environments supplied in the API specification." } - }); - return violations; + ]; } - return []; } - }; - } -}; + + const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments)); + const violations = playgroundEnvironmentIds + .filter(id => !availableEnvironmentIds.has(id)) + .map(id => ({ + severity: "error", + message: `Invalid environment id supplied in playground settings: ${id}` + })); + + return violations; + } + }) +}; \ No newline at end of file From 715427d8b600058352cdcd450084343bc3c98087 Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sun, 11 Aug 2024 23:41:17 -0400 Subject: [PATCH 06/13] type violations array --- .../playground-environments-exist.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index 280173fbe99..3d0fb09577a 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -20,7 +20,7 @@ export const PlaygroundEnvironmentsExistRule: Rule = { } const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments)); - const violations = playgroundEnvironmentIds + const violations: RuleViolation[] = playgroundEnvironmentIds .filter(id => !availableEnvironmentIds.has(id)) .map(id => ({ severity: "error", From 057366c2418fa4a1a0f0a96dd82ce22b9d12fdca Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Sun, 11 Aug 2024 23:46:38 -0400 Subject: [PATCH 07/13] prettier --- .../playground-environments-exist.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index 3d0fb09577a..ad0b8400ab2 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -4,7 +4,8 @@ export const PlaygroundEnvironmentsExistRule: Rule = { name: "playground-environments-exist", create: () => ({ apiSection: async ({ workspace, context, config }) => { - const apiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile.contents.environments; + const apiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile.contents + .environments; const playgroundEnvironmentIds = config.playground?.environments || []; if (!apiSpecificationEnvironments) { @@ -12,7 +13,8 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return [ { severity: "error", - message: "Cannot specify playground environments if there are no environments supplied in the API specification." + message: + "Cannot specify playground environments if there are no environments supplied in the API specification." } ]; } @@ -21,8 +23,8 @@ export const PlaygroundEnvironmentsExistRule: Rule = { const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments)); const violations: RuleViolation[] = playgroundEnvironmentIds - .filter(id => !availableEnvironmentIds.has(id)) - .map(id => ({ + .filter((id) => !availableEnvironmentIds.has(id)) + .map((id) => ({ severity: "error", message: `Invalid environment id supplied in playground settings: ${id}` })); @@ -30,4 +32,4 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return violations; } }) -}; \ No newline at end of file +}; From 5f0a02c48ae1b96cb1e585e89316334902b10aa3 Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Mon, 12 Aug 2024 09:56:47 -0400 Subject: [PATCH 08/13] change error messages --- .../playground-environments-exist.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index ad0b8400ab2..b9db76c09c8 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -14,7 +14,7 @@ export const PlaygroundEnvironmentsExistRule: Rule = { { severity: "error", message: - "Cannot specify playground environments if there are no environments supplied in the API specification." + `${playgroundEnvironmentIds.join(", ")} are not valid environments` } ]; } @@ -26,7 +26,7 @@ export const PlaygroundEnvironmentsExistRule: Rule = { .filter((id) => !availableEnvironmentIds.has(id)) .map((id) => ({ severity: "error", - message: `Invalid environment id supplied in playground settings: ${id}` + message: `${invalidEnvironmentIds.join(", ")} are not valid environments. Choose from ${availableEnvironmentIds.join(", ")}` })); return violations; From a40f9a764fc081f99922a6e8516bb27f91b4592b Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Mon, 12 Aug 2024 14:08:58 -0400 Subject: [PATCH 09/13] prettier --- .../playground-environments-exist.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index b9db76c09c8..33eba2e3759 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -13,8 +13,7 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return [ { severity: "error", - message: - `${playgroundEnvironmentIds.join(", ")} are not valid environments` + message: `${playgroundEnvironmentIds.join(", ")} are not valid environments` } ]; } @@ -22,14 +21,17 @@ export const PlaygroundEnvironmentsExistRule: Rule = { } const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments)); - const violations: RuleViolation[] = playgroundEnvironmentIds - .filter((id) => !availableEnvironmentIds.has(id)) - .map((id) => ({ - severity: "error", - message: `${invalidEnvironmentIds.join(", ")} are not valid environments. Choose from ${availableEnvironmentIds.join(", ")}` - })); - - return violations; + const violatingIds = playgroundEnvironmentIds.filter((id) => !availableEnvironmentIds.has(id)); + return violatingIds.length > 0 + ? [ + { + severity: "error", + message: `${violatingIds.join(", ")} are not valid environments. Choose from ${Array.from( + availableEnvironmentIds + ).join(", ")}` + } + ] + : []; } }) }; From d99e1806f6ccb55988458239ffe8602051b1f2d1 Mon Sep 17 00:00:00 2001 From: dsinghvi Date: Mon, 12 Aug 2024 15:16:23 -0400 Subject: [PATCH 10/13] (followup): add test for playground environments validation --- packages/cli/project-loader/src/index.ts | 3 +- .../cli/project-loader/src/loadProject.ts | 51 ++++++++++------ packages/cli/yaml/docs-validator/package.json | 2 + ...playground-environments-exist.test.ts.snap | 31 ++++++++++ .../fern/definition/api.yml | 3 + .../fern/definition/imdb.yml | 60 +++++++++++++++++++ .../no-environments-in-api/fern/docs.yml | 11 ++++ .../fern/fern.config.json | 4 ++ .../fern/generators.yml | 9 +++ .../fern/definition/api.yml | 6 ++ .../fern/definition/imdb.yml | 60 +++++++++++++++++++ .../wrong-environments-in-docs/fern/docs.yml | 11 ++++ .../fern/fern.config.json | 4 ++ .../fern/generators.yml | 9 +++ .../playground-environments-exist.test.ts | 33 ++++++++++ .../src/testing-utils/getViolationsForRule.ts | 45 ++++++++++++++ .../cli/yaml/docs-validator/tsconfig.json | 1 + pnpm-lock.yaml | 19 ++++++ 18 files changed, 343 insertions(+), 19 deletions(-) create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/api.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/imdb.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/docs.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/fern.config.json create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/generators.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/api.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/imdb.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/docs.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/fern.config.json create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/generators.yml create mode 100644 packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/playground-environments-exist.test.ts create mode 100644 packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts diff --git a/packages/cli/project-loader/src/index.ts b/packages/cli/project-loader/src/index.ts index ba732c17f7d..6c63fac3ca7 100644 --- a/packages/cli/project-loader/src/index.ts +++ b/packages/cli/project-loader/src/index.ts @@ -1,2 +1,3 @@ -export { loadApis, loadProject } from "./loadProject"; +export { loadApis, loadProject, loadProjectFromDirectory } from "./loadProject"; export { type Project } from "./Project"; + diff --git a/packages/cli/project-loader/src/loadProject.ts b/packages/cli/project-loader/src/loadProject.ts index 5ae870b5ebf..2dfba11f1b8 100644 --- a/packages/cli/project-loader/src/loadProject.ts +++ b/packages/cli/project-loader/src/loadProject.ts @@ -2,10 +2,10 @@ import { APIS_DIRECTORY, ASYNCAPI_DIRECTORY, DEFINITION_DIRECTORY, - fernConfigJson, FERN_DIRECTORY, - generatorsYml, + fernConfigJson, GENERATORS_CONFIGURATION_FILENAME, + generatorsYml, getFernDirectory, OPENAPI_DIRECTORY } from "@fern-api/configuration"; @@ -35,33 +35,48 @@ export declare namespace loadProject { nameOverride?: string; sdkLanguage?: generatorsYml.GenerationLanguage; } + + export interface LoadProjectFromDirectoryArgs extends Args { + absolutePathToFernDirectory: AbsoluteFilePath; + } } -export async function loadProject({ - cliName, - cliVersion, - commandLineApiWorkspace, - defaultToAllApiWorkspaces, - context, - nameOverride -}: loadProject.Args): Promise { +export async function loadProject({ context, nameOverride, ...args }: loadProject.Args): Promise { const fernDirectory = await getFernDirectory(nameOverride); if (fernDirectory == null) { return context.failAndThrow(`Directory "${nameOverride ?? FERN_DIRECTORY}" not found.`); } + return await loadProjectFromDirectory({ + absolutePathToFernDirectory: fernDirectory, + context, + nameOverride, + ...args + }); +} + +export async function loadProjectFromDirectory({ + absolutePathToFernDirectory, + cliName, + cliVersion, + commandLineApiWorkspace, + defaultToAllApiWorkspaces, + context +}: loadProject.LoadProjectFromDirectoryArgs): Promise { let apiWorkspaces: APIWorkspace[] = []; if ( - (await doesPathExist(join(fernDirectory, RelativeFilePath.of(APIS_DIRECTORY)))) || - doesPathExist(join(fernDirectory, RelativeFilePath.of(DEFINITION_DIRECTORY))) || - doesPathExist(join(fernDirectory, RelativeFilePath.of(GENERATORS_CONFIGURATION_FILENAME))) || - doesPathExist(join(fernDirectory, RelativeFilePath.of(OPENAPI_DIRECTORY))) || - doesPathExist(join(fernDirectory, RelativeFilePath.of(ASYNCAPI_DIRECTORY))) + (await doesPathExist(join(absolutePathToFernDirectory, RelativeFilePath.of(APIS_DIRECTORY)))) || + (await doesPathExist(join(absolutePathToFernDirectory, RelativeFilePath.of(DEFINITION_DIRECTORY)))) || + (await doesPathExist( + join(absolutePathToFernDirectory, RelativeFilePath.of(GENERATORS_CONFIGURATION_FILENAME)) + )) || + (await doesPathExist(join(absolutePathToFernDirectory, RelativeFilePath.of(OPENAPI_DIRECTORY)))) || + (await doesPathExist(join(absolutePathToFernDirectory, RelativeFilePath.of(ASYNCAPI_DIRECTORY)))) ) { apiWorkspaces = await loadApis({ cliName, - fernDirectory, + fernDirectory: absolutePathToFernDirectory, cliVersion, context, commandLineApiWorkspace, @@ -70,9 +85,9 @@ export async function loadProject({ } return { - config: await fernConfigJson.loadProjectConfig({ directory: fernDirectory, context }), + config: await fernConfigJson.loadProjectConfig({ directory: absolutePathToFernDirectory, context }), apiWorkspaces, - docsWorkspaces: await loadDocsWorkspace({ fernDirectory, context }), + docsWorkspaces: await loadDocsWorkspace({ fernDirectory: absolutePathToFernDirectory, context }), loadAPIWorkspace: (name: string | undefined): APIWorkspace | undefined => { if (name == null) { return apiWorkspaces[0]; diff --git a/packages/cli/yaml/docs-validator/package.json b/packages/cli/yaml/docs-validator/package.json index 73018a6bfca..35adc75a8ce 100644 --- a/packages/cli/yaml/docs-validator/package.json +++ b/packages/cli/yaml/docs-validator/package.json @@ -32,6 +32,7 @@ "@fern-api/docs-markdown-utils": "workspace:*", "@fern-api/fs-utils": "workspace:*", "@fern-api/logger": "workspace:*", + "@fern-api/project-loader": "workspace:*", "@fern-api/task-context": "workspace:*", "@fern-api/workspace-loader": "workspace:*", "@fern-api/yaml-schema": "workspace:*", @@ -43,6 +44,7 @@ "rehype-katex": "^7.0.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", + "strip-ansi": "^7.1.0", "tinycolor2": "^1.6.0", "zod": "^3.22.3" }, diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap new file mode 100644 index 00000000000..35f8eb29892 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap @@ -0,0 +1,31 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`playground-environments-exist > no environments in api definition 1`] = ` +[ + { + "message": "Staging are not valid environments", + "nodePath": [ + "navigation", + "0", + "api", + ], + "relativeFilepath": "docs.yml", + "severity": "error", + }, +] +`; + +exports[`playground-environments-exist > non existent environment specified 1`] = ` +[ + { + "message": "Staging are not valid environments. Choose from Production, Dev", + "nodePath": [ + "navigation", + "0", + "api", + ], + "relativeFilepath": "docs.yml", + "severity": "error", + }, +] +`; diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/api.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/api.yml new file mode 100644 index 00000000000..79c79c049a4 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/api.yml @@ -0,0 +1,3 @@ +name: api +error-discrimination: + strategy: status-code diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/imdb.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/imdb.yml new file mode 100644 index 00000000000..e101041c5d8 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/definition/imdb.yml @@ -0,0 +1,60 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +service: + auth: false + base-path: /movies + endpoints: + createMovie: + docs: Add a movie to the database + method: POST + path: /create-movie + request: CreateMovieRequest + response: MovieId + + getMovie: + docs: Retrieve a movie from the database based on the ID + method: GET + path: /{id} + path-parameters: + id: MovieId + response: Movie + errors: + - MovieDoesNotExistError + examples: + # Success response + - path-parameters: + id: tt0111161 + response: + body: + id: tt0111161 + title: The Shawshank Redemption + rating: 9.3 + # Error response + - path-parameters: + id: tt1234 + response: + error: MovieDoesNotExistError + body: tt1234 + +types: + MovieId: + type: string + docs: The unique identifier for a Movie in the database + + Movie: + properties: + id: MovieId + title: string + rating: + type: double + docs: The rating scale out of ten stars + + CreateMovieRequest: + properties: + title: string + rating: double + +errors: + MovieDoesNotExistError: + status-code: 404 + type: MovieId diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/docs.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/docs.yml new file mode 100644 index 00000000000..286638d4735 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/docs.yml @@ -0,0 +1,11 @@ +instances: + - url: https://fern.docs.buildwithfern.com +title: Fern | Documentation +navigation: + - api: API Reference + playground: + environments: + - Staging +colors: + accentPrimary: '#ffffff' + background: '#000000' diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/fern.config.json b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/fern.config.json new file mode 100644 index 00000000000..38233178d2f --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "fern", + "version": "0.37.16" +} \ No newline at end of file diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/generators.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/generators.yml new file mode 100644 index 00000000000..c8ae78dfffa --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/no-environments-in-api/fern/generators.yml @@ -0,0 +1,9 @@ +default-group: local +groups: + local: + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.9.5 + output: + location: local-file-system + path: ../sdks/typescript diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/api.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/api.yml new file mode 100644 index 00000000000..575b72decd6 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/api.yml @@ -0,0 +1,6 @@ +name: api +environments: + Production: prod.com + Dev: dev.com +error-discrimination: + strategy: status-code diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/imdb.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/imdb.yml new file mode 100644 index 00000000000..e101041c5d8 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/definition/imdb.yml @@ -0,0 +1,60 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +service: + auth: false + base-path: /movies + endpoints: + createMovie: + docs: Add a movie to the database + method: POST + path: /create-movie + request: CreateMovieRequest + response: MovieId + + getMovie: + docs: Retrieve a movie from the database based on the ID + method: GET + path: /{id} + path-parameters: + id: MovieId + response: Movie + errors: + - MovieDoesNotExistError + examples: + # Success response + - path-parameters: + id: tt0111161 + response: + body: + id: tt0111161 + title: The Shawshank Redemption + rating: 9.3 + # Error response + - path-parameters: + id: tt1234 + response: + error: MovieDoesNotExistError + body: tt1234 + +types: + MovieId: + type: string + docs: The unique identifier for a Movie in the database + + Movie: + properties: + id: MovieId + title: string + rating: + type: double + docs: The rating scale out of ten stars + + CreateMovieRequest: + properties: + title: string + rating: double + +errors: + MovieDoesNotExistError: + status-code: 404 + type: MovieId diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/docs.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/docs.yml new file mode 100644 index 00000000000..286638d4735 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/docs.yml @@ -0,0 +1,11 @@ +instances: + - url: https://fern.docs.buildwithfern.com +title: Fern | Documentation +navigation: + - api: API Reference + playground: + environments: + - Staging +colors: + accentPrimary: '#ffffff' + background: '#000000' diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/fern.config.json b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/fern.config.json new file mode 100644 index 00000000000..38233178d2f --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "fern", + "version": "0.37.16" +} \ No newline at end of file diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/generators.yml b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/generators.yml new file mode 100644 index 00000000000..c8ae78dfffa --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/fixtures/wrong-environments-in-docs/fern/generators.yml @@ -0,0 +1,9 @@ +default-group: local +groups: + local: + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.9.5 + output: + location: local-file-system + path: ../sdks/typescript diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/playground-environments-exist.test.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/playground-environments-exist.test.ts new file mode 100644 index 00000000000..9cc0efe4dac --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/playground-environments-exist.test.ts @@ -0,0 +1,33 @@ +import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils"; +import { getViolationsForRule } from "../../../testing-utils/getViolationsForRule"; +import { PlaygroundEnvironmentsExistRule } from "../playground-environments-exist"; + +describe("playground-environments-exist", () => { + it("no environments in api definition", async () => { + const violations = await getViolationsForRule({ + rule: PlaygroundEnvironmentsExistRule, + absolutePathToFernDirectory: join( + AbsoluteFilePath.of(__dirname), + RelativeFilePath.of("fixtures"), + RelativeFilePath.of("no-environments-in-api"), + RelativeFilePath.of("fern") + ) + }); + + expect(violations).toMatchSnapshot(); + }); + + it("non existent environment specified", async () => { + const violations = await getViolationsForRule({ + rule: PlaygroundEnvironmentsExistRule, + absolutePathToFernDirectory: join( + AbsoluteFilePath.of(__dirname), + RelativeFilePath.of("fixtures"), + RelativeFilePath.of("wrong-environments-in-docs"), + RelativeFilePath.of("fern") + ) + }); + + expect(violations).toMatchSnapshot(); + }); +}); diff --git a/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts new file mode 100644 index 00000000000..e4c096c19f9 --- /dev/null +++ b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts @@ -0,0 +1,45 @@ +import { AbsoluteFilePath } from "@fern-api/fs-utils"; +import { loadProjectFromDirectory } from "@fern-api/project-loader"; +import { createMockTaskContext } from "@fern-api/task-context"; +import stripAnsi from "strip-ansi"; +import { Rule } from "../Rule"; +import { runRulesOnDocsWorkspace } from "../validateDocsWorkspace"; +import { ValidationViolation } from "../ValidationViolation"; + +export declare namespace getViolationsForRule { + export interface Args { + rule: Rule; + absolutePathToFernDirectory: AbsoluteFilePath; + } +} + +export async function getViolationsForRule({ + rule, + absolutePathToFernDirectory +}: getViolationsForRule.Args): Promise { + const context = createMockTaskContext(); + const project = await loadProjectFromDirectory({ + absolutePathToFernDirectory, + context, + cliVersion: "0.0.0", + defaultToAllApiWorkspaces: true, + commandLineApiWorkspace: undefined, + cliName: "fern" + }); + + if (project.docsWorkspaces == null) { + throw new Error("Expected docs workspace to be present, but found none"); + } + + const violations = await runRulesOnDocsWorkspace({ + workspace: project.docsWorkspaces, + context: context, + rules: [rule], + loadApiWorkspace: project.loadAPIWorkspace, + }); + + return violations.map((violation) => ({ + ...violation, + message: stripAnsi(violation.message) + })); +} diff --git a/packages/cli/yaml/docs-validator/tsconfig.json b/packages/cli/yaml/docs-validator/tsconfig.json index 1a26f58599b..c9c7bb4d42e 100644 --- a/packages/cli/yaml/docs-validator/tsconfig.json +++ b/packages/cli/yaml/docs-validator/tsconfig.json @@ -10,6 +10,7 @@ { "path": "../../logger" }, { "path": "../../task-context" }, { "path": "../../workspace-loader" }, + { "path": "../../project-loader" }, { "path": "../yaml-schema" } ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb2c6427e98..87862ad2822 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3177,6 +3177,19 @@ importers: specifier: 4.6.4 version: 4.6.4 + packages/cli/cli/dist/dev: {} + + packages/cli/cli/dist/local: + devDependencies: + globals: + specifier: link:@types/vitest/globals + version: link:@types/vitest/globals + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@18.7.18)(jsdom@20.0.3)(sass@1.72.0)(terser@5.31.5) + + packages/cli/cli/dist/prod: {} + packages/cli/configuration: dependencies: '@fern-api/core-utils': @@ -4866,6 +4879,9 @@ importers: '@fern-api/logger': specifier: workspace:* version: link:../../logger + '@fern-api/project-loader': + specifier: workspace:* + version: link:../../project-loader '@fern-api/task-context': specifier: workspace:* version: link:../../task-context @@ -4899,6 +4915,9 @@ importers: remark-math: specifier: ^6.0.0 version: 6.0.0 + strip-ansi: + specifier: ^7.1.0 + version: 7.1.0 tinycolor2: specifier: ^1.6.0 version: 1.6.0 From 132cd267e0a489eed74cddd8d7adf5d53332b600 Mon Sep 17 00:00:00 2001 From: dsinghvi Date: Mon, 12 Aug 2024 15:42:36 -0400 Subject: [PATCH 11/13] update fix --- packages/cli/project-loader/src/index.ts | 1 - ...playground-environments-exist.test.ts.snap | 4 +- .../playground-environments-exist.ts | 59 +++++++++++-------- .../src/testing-utils/getViolationsForRule.ts | 2 +- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/packages/cli/project-loader/src/index.ts b/packages/cli/project-loader/src/index.ts index 6c63fac3ca7..15bd6a44545 100644 --- a/packages/cli/project-loader/src/index.ts +++ b/packages/cli/project-loader/src/index.ts @@ -1,3 +1,2 @@ export { loadApis, loadProject, loadProjectFromDirectory } from "./loadProject"; export { type Project } from "./Project"; - diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap index 35f8eb29892..fad5e845378 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/__test__/__snapshots__/playground-environments-exist.test.ts.snap @@ -3,7 +3,7 @@ exports[`playground-environments-exist > no environments in api definition 1`] = ` [ { - "message": "Staging are not valid environments", + "message": "The API does not contain the Staging environment. ", "nodePath": [ "navigation", "0", @@ -18,7 +18,7 @@ exports[`playground-environments-exist > no environments in api definition 1`] = exports[`playground-environments-exist > non existent environment specified 1`] = ` [ { - "message": "Staging are not valid environments. Choose from Production, Dev", + "message": "The API does not contain the Staging environment. Existing enviroments include Production, Dev.", "nodePath": [ "navigation", "0", diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index 33eba2e3759..eaa87805749 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -1,4 +1,4 @@ -import { Rule, RuleViolation } from "../../Rule"; +import { Rule } from "../../Rule"; export const PlaygroundEnvironmentsExistRule: Rule = { name: "playground-environments-exist", @@ -6,32 +6,45 @@ export const PlaygroundEnvironmentsExistRule: Rule = { apiSection: async ({ workspace, context, config }) => { const apiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile.contents .environments; - const playgroundEnvironmentIds = config.playground?.environments || []; + + const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments ?? {})); + const playgroundEnvironmentIds = config.playground?.environments; - if (!apiSpecificationEnvironments) { - if (playgroundEnvironmentIds.length > 0) { - return [ - { - severity: "error", - message: `${playgroundEnvironmentIds.join(", ")} are not valid environments` - } - ]; - } + if (playgroundEnvironmentIds == null || playgroundEnvironmentIds.length == null) { + return []; + } + + const nonExistentEnviromentIds = playgroundEnvironmentIds.filter((id) => !availableEnvironmentIds.has(id)); + + if (nonExistentEnviromentIds.length == 0) { return []; } - const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments)); - const violatingIds = playgroundEnvironmentIds.filter((id) => !availableEnvironmentIds.has(id)); - return violatingIds.length > 0 - ? [ - { - severity: "error", - message: `${violatingIds.join(", ")} are not valid environments. Choose from ${Array.from( - availableEnvironmentIds - ).join(", ")}` - } - ] - : []; + if (nonExistentEnviromentIds.length === 1 ) { + return [ + { + severity: "error", + message: `The API does not contain the ${nonExistentEnviromentIds[0]} environment. ${getExistingEnviromentIds(Array.from(availableEnvironmentIds)) || ""}` + } + ]; + } + + return [ + { + severity: "error", + message: `The API does not contain the following enviroments: ${nonExistentEnviromentIds.join(", ")}. ${getExistingEnviromentIds(Array.from(availableEnvironmentIds)) || ""}` + } + ]; } }) }; + +function getExistingEnviromentIds(availableEnvironmentIds: string[]): string | undefined { + if (availableEnvironmentIds.length === 0) { + return undefined; + } + if (availableEnvironmentIds.length === 1 && availableEnvironmentIds[0] != null) { + return `The only configured environment is ${availableEnvironmentIds[0]}`; + } + return `Existing enviroments include ${availableEnvironmentIds.join(", ")}.` +} diff --git a/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts index e4c096c19f9..01fca602716 100644 --- a/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts +++ b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts @@ -35,7 +35,7 @@ export async function getViolationsForRule({ workspace: project.docsWorkspaces, context: context, rules: [rule], - loadApiWorkspace: project.loadAPIWorkspace, + loadApiWorkspace: project.loadAPIWorkspace }); return violations.map((violation) => ({ From 8b2e4d8748b2da7c19a033f375b2e0562f663d1f Mon Sep 17 00:00:00 2001 From: dsinghvi Date: Mon, 12 Aug 2024 15:49:35 -0400 Subject: [PATCH 12/13] fix ci --- .../playground-environments-exist.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts index eaa87805749..a78ad906b1e 100644 --- a/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts +++ b/packages/cli/yaml/docs-validator/src/rules/playground-environments-exist/playground-environments-exist.ts @@ -6,7 +6,7 @@ export const PlaygroundEnvironmentsExistRule: Rule = { apiSection: async ({ workspace, context, config }) => { const apiSpecificationEnvironments = (await workspace.getDefinition({ context })).rootApiFile.contents .environments; - + const availableEnvironmentIds = new Set(Object.keys(apiSpecificationEnvironments ?? {})); const playgroundEnvironmentIds = config.playground?.environments; @@ -20,11 +20,13 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return []; } - if (nonExistentEnviromentIds.length === 1 ) { + if (nonExistentEnviromentIds.length === 1) { return [ { severity: "error", - message: `The API does not contain the ${nonExistentEnviromentIds[0]} environment. ${getExistingEnviromentIds(Array.from(availableEnvironmentIds)) || ""}` + message: `The API does not contain the ${nonExistentEnviromentIds[0]} environment. ${ + getExistingEnviromentIds(Array.from(availableEnvironmentIds)) ?? "" + }` } ]; } @@ -32,7 +34,9 @@ export const PlaygroundEnvironmentsExistRule: Rule = { return [ { severity: "error", - message: `The API does not contain the following enviroments: ${nonExistentEnviromentIds.join(", ")}. ${getExistingEnviromentIds(Array.from(availableEnvironmentIds)) || ""}` + message: `The API does not contain the following enviroments: ${nonExistentEnviromentIds.join( + ", " + )}. ${getExistingEnviromentIds(Array.from(availableEnvironmentIds)) ?? ""}` } ]; } @@ -46,5 +50,5 @@ function getExistingEnviromentIds(availableEnvironmentIds: string[]): string | u if (availableEnvironmentIds.length === 1 && availableEnvironmentIds[0] != null) { return `The only configured environment is ${availableEnvironmentIds[0]}`; } - return `Existing enviroments include ${availableEnvironmentIds.join(", ")}.` + return `Existing enviroments include ${availableEnvironmentIds.join(", ")}.`; } From 5d9148d08a4bcdfcc05de62bfe619e7d4d37c723 Mon Sep 17 00:00:00 2001 From: dsinghvi Date: Mon, 12 Aug 2024 15:52:48 -0400 Subject: [PATCH 13/13] == to === --- .../docs-validator/src/testing-utils/getViolationsForRule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts index 01fca602716..7522c3e0eb8 100644 --- a/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts +++ b/packages/cli/yaml/docs-validator/src/testing-utils/getViolationsForRule.ts @@ -33,7 +33,7 @@ export async function getViolationsForRule({ const violations = await runRulesOnDocsWorkspace({ workspace: project.docsWorkspaces, - context: context, + context, rules: [rule], loadApiWorkspace: project.loadAPIWorkspace });