From b862f1bbb543b2f147f7a02c14fa6116c0a64d02 Mon Sep 17 00:00:00 2001 From: Daniel Kuznetsov Date: Mon, 17 Jun 2024 19:57:51 +0200 Subject: [PATCH 1/2] feat: omit parameters marked with `x-hidden` from resulting markdown --- src/@types/oasVendorExtensions.d.ts | 13 ++ .../hidden/endpointParameters.test.ts.snap | 147 ++++++++++++++++++ .../hidden/objectProps.test.ts.snap | 102 ++++++++++++ .../hidden/endpointParameters.test.ts | 94 +++++++++++ src/__tests__/hidden/objectProps.test.ts | 44 ++++++ src/includer/models.ts | 3 + src/includer/ui/endpoint.ts | 18 +-- .../ui/presentationUtils/partitionParams.ts | 0 .../prepareRenderableParameterList.ts | 27 ++++ tsconfig.json | 1 - tsconfig.test.json | 4 +- 11 files changed, 438 insertions(+), 15 deletions(-) create mode 100644 src/@types/oasVendorExtensions.d.ts create mode 100644 src/__snapshots__/hidden/endpointParameters.test.ts.snap create mode 100644 src/__snapshots__/hidden/objectProps.test.ts.snap create mode 100644 src/__tests__/hidden/endpointParameters.test.ts create mode 100644 src/__tests__/hidden/objectProps.test.ts delete mode 100644 src/includer/ui/presentationUtils/partitionParams.ts create mode 100644 src/includer/ui/presentationUtils/prepareRenderableParameterList.ts diff --git a/src/@types/oasVendorExtensions.d.ts b/src/@types/oasVendorExtensions.d.ts new file mode 100644 index 0000000..036e0b9 --- /dev/null +++ b/src/@types/oasVendorExtensions.d.ts @@ -0,0 +1,13 @@ +import 'openapi-types'; + +declare module 'openapi-types' { + namespace OpenAPIV3 { + interface BaseSchemaObject { + 'x-hidden'?: boolean; + } + + interface ParameterBaseObject { + 'x-hidden'?: boolean; + } + } +} diff --git a/src/__snapshots__/hidden/endpointParameters.test.ts.snap b/src/__snapshots__/hidden/endpointParameters.test.ts.snap new file mode 100644 index 0000000..55059b1 --- /dev/null +++ b/src/__snapshots__/hidden/endpointParameters.test.ts.snap @@ -0,0 +1,147 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Endpoint parameter tables should be omitted if all of their respective parameters are marked with \`x-hidden\` 1`] = ` +"
+ +# HiddenEndpointParameters + +## Request + +
+ +
+ +
+ +POST {.openapi__method} +\`\`\` +http://localhost:8080/test +\`\`\` + + + +
+ +Generated server url + +
+ +
+ +### Cookies + +#||| + **Name** +| + **Description** +|| + +|| + accessToken +| + **Type:** string + +Access token +|||# + +## Responses + +
+ +## 204 No Content + +
+ +### Body + +{% cut "application/json" %} + + +\`\`\`json +{} +\`\`\` + + +{% endcut %} + + +
+ +
+ + +
" +`; + +exports[`Endpoint parameter tables should not include parameters marked with \`x-hidden\` in the spec 1`] = ` +"
+ +# HiddenEndpointParameters + +## Request + +
+ +
+ +
+ +POST {.openapi__method} +\`\`\` +http://localhost:8080/test +\`\`\` + + + +
+ +Generated server url + +
+ +
+ +### Query parameters + +#||| + **Name** +| + **Description** +|| + +|| + name +| + **Type:** string + +Name for the requested star +|||# + +## Responses + +
+ +## 204 No Content + +
+ +### Body + +{% cut "application/json" %} + + +\`\`\`json +{} +\`\`\` + + +{% endcut %} + + +
+ +
+ + +
" +`; diff --git a/src/__snapshots__/hidden/objectProps.test.ts.snap b/src/__snapshots__/hidden/objectProps.test.ts.snap new file mode 100644 index 0000000..5703c2e --- /dev/null +++ b/src/__snapshots__/hidden/objectProps.test.ts.snap @@ -0,0 +1,102 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Properties in object schemas marked with \`x-hidden\` should not be rendered in the resulting markdown 1`] = ` +"
+ +# HiddenObjectProperties + +## Request + +
+ +
+ +
+ +POST {.openapi__method} +\`\`\` +http://localhost:8080/test +\`\`\` + + + +
+ +Generated server url + +
+ +
+ +
+ +### Body + +{% cut "application/json" %} + + +\`\`\`json +{ + "luminosityClass": "string", + "name": "string" +} +\`\`\` + + +{% endcut %} + + +#||| + **Name** +| + **Description** +|| + +|| + luminosityClass +| + **Type:** string + +Morgan-Keenan luminosity class for this star + +|| + +|| + name +| + **Type:** string + +Name of this star + +|||# + +
+ +## Responses + +
+ +## 204 No Content + +
+ +### Body + +{% cut "application/json" %} + + +\`\`\`json +{} +\`\`\` + + +{% endcut %} + + +
+ +
+ + +
" +`; diff --git a/src/__tests__/hidden/endpointParameters.test.ts b/src/__tests__/hidden/endpointParameters.test.ts new file mode 100644 index 0000000..4ef52d3 --- /dev/null +++ b/src/__tests__/hidden/endpointParameters.test.ts @@ -0,0 +1,94 @@ +import {DocumentBuilder, run} from '../__helpers__/run'; + +const mockDocumentName = 'HiddenEndpointParameters'; + +describe('Endpoint parameter tables', () => { + it('should not include parameters marked with `x-hidden` in the spec', async () => { + const spec = new DocumentBuilder(mockDocumentName) + .parameter({ + in: 'query', + name: 'name', + description: 'Name for the requested star', + schema: { + type: 'string', + }, + }) + .parameter({ + in: 'query', + name: 'id', + description: 'Internal ID for the requested star', + schema: { + type: 'string', + format: 'uuid', + }, + 'x-hidden': true, + }) + .parameter({ + in: 'query', + name: 'catalogueCCDM', + description: 'CCDM designation for the requested star', + schema: { + type: 'string', + }, + 'x-hidden': true, + }) + .response(204, {}) + .build(); + + const fs = await run(spec); + + const page = fs.match(mockDocumentName); + + expect(page).toMatchSnapshot(); + }); + + it('should be omitted if all of their respective parameters are marked with `x-hidden`', async () => { + const spec = new DocumentBuilder(mockDocumentName) + .parameter({ + in: 'query', + name: 'name', + description: 'Name for the requested star', + schema: { + type: 'string', + }, + 'x-hidden': true, + }) + .parameter({ + in: 'query', + name: 'id', + description: 'Internal ID for the requested star', + schema: { + type: 'string', + format: 'uuid', + }, + 'x-hidden': true, + }) + .parameter({ + in: 'query', + name: 'catalogueCCDM', + description: 'CCDM designation for the requested star', + schema: { + type: 'string', + }, + 'x-hidden': true, + }) + // "Query parameters" table should not be rendered; however, not all cookie params are optional + // so we expect this one to be rendered. + .parameter({ + in: 'cookie', + name: 'accessToken', + description: 'Access token', + schema: { + type: 'string', + }, + }) + .response(204, {}) + .build(); + + const fs = await run(spec); + + const page = fs.match(mockDocumentName); + + expect(page).toMatchSnapshot(); + }); +}); diff --git a/src/__tests__/hidden/objectProps.test.ts b/src/__tests__/hidden/objectProps.test.ts new file mode 100644 index 0000000..9e2498b --- /dev/null +++ b/src/__tests__/hidden/objectProps.test.ts @@ -0,0 +1,44 @@ +import {DocumentBuilder, run} from '../__helpers__/run'; + +const mockDocumentName = 'HiddenObjectProperties'; + +describe('Properties in object schemas marked with `x-hidden`', () => { + it('should not be rendered in the resulting markdown', async () => { + const spec = new DocumentBuilder(mockDocumentName) + .component('StarDto', { + type: 'object', + properties: { + id: { + description: 'Internal ID for this star', + type: 'string', + format: 'uuid', + 'x-hidden': true, + }, + luminosityClass: { + description: 'Morgan-Keenan luminosity class for this star', + type: 'string', + }, + name: { + description: 'Name of this star', + type: 'string', + }, + catalogueDesignationCCDM: { + description: 'CCDM catalogue designation for this star', + type: 'string', + 'x-hidden': true, + }, + }, + }) + .request({ + schema: DocumentBuilder.ref('StarDto'), + }) + .response(204, {}) + .build(); + + const fs = await run(spec); + + const page = fs.match(mockDocumentName); + + expect(page).toMatchSnapshot(); + }); +}); diff --git a/src/includer/models.ts b/src/includer/models.ts index 6b5be0e..9f91c23 100644 --- a/src/includer/models.ts +++ b/src/includer/models.ts @@ -220,6 +220,9 @@ export type Parameter = { example?: Primitive; default?: Primitive; schema: OpenJSONSchema; + + // vendor extensions + 'x-hidden'?: boolean; }; export type Responses = Response[]; diff --git a/src/includer/ui/endpoint.ts b/src/includer/ui/endpoint.ts index 6562f0d..0dc21fd 100644 --- a/src/includer/ui/endpoint.ts +++ b/src/includer/ui/endpoint.ts @@ -52,7 +52,7 @@ import { tabs, title, } from './common'; -import {getOrderedPropList} from './presentationUtils/orderedProps/getOrderedPropList'; +import {prepareRenderableParameterList} from './presentationUtils/prepareRenderableParameterList'; function endpoint(data: Endpoint, sandboxPlugin: {host?: string; tabName?: string} | undefined) { // try to remember, which tables we are already printed on page @@ -198,19 +198,13 @@ function parameters(pagePrintedRefs: Set, params?: Parameters) { partitionedParameters[parameterSource as In] ?? [], ] as const, ) + .map( + ([parameterSource, parameterList]) => + [parameterSource, prepareRenderableParameterList(parameterList)] as const, + ) .filter(([, parameterList]) => parameterList.length) .reduce((contentAccumulator, [parameterSource, parameterList]) => { - const wellOrderedParameters = getOrderedPropList({ - propList: parameterList, - iteratee: ({name, required}) => ({ - name, - // required can actually be `undefined` in runtime - isRequired: Boolean(required), - }), - }); - - const {contentRows, additionalRefs} = - getParameterSourceTableContents(wellOrderedParameters); + const {contentRows, additionalRefs} = getParameterSourceTableContents(parameterList); const tableHeading = sections[parameterSource]; diff --git a/src/includer/ui/presentationUtils/partitionParams.ts b/src/includer/ui/presentationUtils/partitionParams.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/includer/ui/presentationUtils/prepareRenderableParameterList.ts b/src/includer/ui/presentationUtils/prepareRenderableParameterList.ts new file mode 100644 index 0000000..f178eda --- /dev/null +++ b/src/includer/ui/presentationUtils/prepareRenderableParameterList.ts @@ -0,0 +1,27 @@ +import {Parameter} from '../../models'; +import {getOrderedPropList} from './orderedProps/getOrderedPropList'; + +const shouldRenderParameter = (parameter: Parameter) => !parameter['x-hidden']; + +/** + * Get ordered & filtered parameter list, mostly ready for table rendering. + * Excludes parameters that should be hidden, applies lexicographic sort & hoists required ones to the top + * of the list. + * @param {ReadonlyArray} rawParamsFromSingleSource Raw parameter list of a single parameter source + * (path, query, etc.) + * @returns {ReadonlyArray} Well-ordered parameter list with hidden ones filtered out. + */ +export const prepareRenderableParameterList = ( + rawParamsFromSingleSource: readonly Parameter[], +): readonly Parameter[] => { + const filteredParams = rawParamsFromSingleSource.filter(shouldRenderParameter); + + return getOrderedPropList({ + propList: filteredParams, + iteratee: ({name, required}) => ({ + name, + // required can actually be `undefined` in runtime + isRequired: Boolean(required), + }), + }); +}; diff --git a/tsconfig.json b/tsconfig.json index d6fd529..c91511c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,6 @@ "declaration": true }, "include": ["src"], - "exclude": ["src/__tests__"], "ts-node": { "esm": true, "transpileOnly": true diff --git a/tsconfig.test.json b/tsconfig.test.json index 763bd7a..7c476d8 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", - "include": ["src/__tests__"], + "include": ["src/__tests__", "src/@types"], "exclude": [] -} \ No newline at end of file +} From 47065d3fa17514f62c7d2a69ca1fd9a750f44ac0 Mon Sep 17 00:00:00 2001 From: Daniel Kuznetsov Date: Wed, 19 Jun 2024 17:47:24 +0200 Subject: [PATCH 2/2] fix: exclude `__tests__` from mainline TS build --- .eslintrc.js | 2 +- src/__tests__/tsconfig.json | 5 +++++ tsconfig.json | 4 +++- tsconfig.test.json | 5 ----- 4 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 src/__tests__/tsconfig.json delete mode 100644 tsconfig.test.json diff --git a/.eslintrc.js b/.eslintrc.js index c4a3591..8ac4f3e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,7 +7,7 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module', - project: ['./tsconfig.test.json', './tsconfig.json'], + project: ['./src/__tests__/tsconfig.json', './tsconfig.json'], tsconfigRootDir: __dirname, }, }, diff --git a/src/__tests__/tsconfig.json b/src/__tests__/tsconfig.json new file mode 100644 index 0000000..3235b58 --- /dev/null +++ b/src/__tests__/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.json", + "include": [".", "../@types"], + "exclude": [] +} diff --git a/tsconfig.json b/tsconfig.json index c91511c..edc22e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,9 +3,11 @@ "compilerOptions": { "target": "ES6", "jsx": "react", - "declaration": true + "declaration": true, + "baseUrl": "." }, "include": ["src"], + "exclude": ["src/__tests__"], "ts-node": { "esm": true, "transpileOnly": true diff --git a/tsconfig.test.json b/tsconfig.test.json deleted file mode 100644 index 7c476d8..0000000 --- a/tsconfig.test.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/__tests__", "src/@types"], - "exclude": [] -}