DOP-3505: Redoc CLI ingests version data from json file (#15)

This commit is contained in:
mmeigs 2023-02-16 14:17:47 -05:00 committed by GitHub
parent 2d61688fcc
commit da330e9178
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 136 additions and 20 deletions

View File

@ -40,6 +40,35 @@ With `node` installed, run by doing the following:
node <path/to/redoc/cli/index.js> build <path/to/spec/file/or/url> --options=<path/to/options.json> --output=<path/to/custom/output/file/name.html>
```
#### Versioned Options in the CLI
If wanting to add versioning support in your build, you must create a JSON file with the following data structure (replace example values with any mock values):
```
{
"active": {
"apiVersion": "2.0",
"resourceVersion": "2023-02-14"
},
"rootUrl": "https://mongodb.com/docs/atlas/reference/api-resources-spec/v2",
"resourceVersions": ["2022-09-09", "2022-10-18", "2023-02-14"]
}
```
After doing so, run the build much the same as above but with the following option added:
Note: the path to the version data option JSON file should be referenced in relation to the `redoc/cli` directory
```
--options.versionData=<path/to/mock/data/file.json/from/cli/directory>
```
Such as:
Note: this is referencing a JSON file in the root directory
```
node <path/to/redoc/cli/index.js> build <path/to/spec/file/or/url> --options.versionData=../version-data.json
```
### Releasing
The Redoc React component and the Redoc CLI have 2 separate release processes. Because the Redoc CLI pulls its version of Redoc from GitHub, build artifacts are included in the version tag being installed.

View File

@ -27,4 +27,29 @@ describe('build', () => {
expect(result).toContain('Found .redocly.yaml and using features.openapi options');
expect(result).toContain('bundled successfully');
});
it('should ingest version data from json file', () => {
const pathToTestData = '__test__/data/version-data.json';
const r = spawnSync(
'ts-node',
[
'../../../index.ts',
'build',
' ../../../../demo/openapi.yaml',
'--output=redoc-test.html',
`--options.versionData=${pathToTestData}`,
],
{
cwd: __dirname,
shell: true,
},
);
const out = r.stdout.toString('utf-8');
const err = r.stderr.toString('utf-8');
const result = `${out}\n${err}`;
expect(result).toContain(`Found ${pathToTestData} and using version data.`);
expect(result).toContain('bundled successfully');
});
});

View File

@ -0,0 +1,8 @@
{
"active": {
"apiVersion": "2.0",
"resourceVersion": "2023-02-14"
},
"rootUrl": "https://mongodb.com/docs/atlas/reference/api-resources-spec/v2",
"resourceVersions": ["2022-09-09", "2022-10-18", "2028-02-14"]
}

View File

@ -439,6 +439,22 @@ function handleError(error: Error) {
function getObjectOrJSON(options) {
switch (typeof options) {
case 'object':
if (options?.versionData) {
const { versionData: versionPath } = options;
const versionFilePath = resolve(__dirname, versionPath);
try {
if (existsSync(versionFilePath) && lstatSync(versionFilePath).isFile()) {
const versionData = JSON.parse(readFileSync(versionFilePath, 'utf-8'));
options.versionData = versionData;
console.log(`Found ${versionPath} and using version data.`);
}
} catch (e) {
console.log(
`Encountered error:\n\n${versionPath}\n\nis not a file with a valid JSON object.`,
);
handleError(e);
}
}
return options;
case 'string':
try {

View File

@ -4,7 +4,7 @@ describe('Menu', () => {
});
it('should have valid items count', () => {
cy.get('.menu-content').find('li').should('have.length', 35);
cy.get('.menu-content').find('li').not('[role="option"]').should('have.length', 35);
});
it('should have a back button', () => {

View File

@ -21,6 +21,7 @@ import {
import { SearchBox } from '../SearchBox/SearchBox';
import { StoreProvider } from '../StoreBuilder';
import { VersionSelector } from '../VersionSelector';
export interface RedocProps {
store: AppStore;
@ -69,6 +70,9 @@ export class Redoc extends React.Component<RedocProps> {
/>
)) ||
null}
{options.versionData && typeof options.versionData == 'object' && (
<VersionSelector {...options.versionData} />
)}
<SideMenu menu={menu} />
</StickyResponsiveSidebar>
<ApiContentWrap className="api-content">

View File

@ -9,6 +9,7 @@ import {
StyledMenuList,
StyledDisplay,
StyledDropdown,
StyledSelected,
} from './styled.elements';
import { Option } from './Option';
import { VersionSelectorProps } from './types';
@ -42,9 +43,7 @@ const VersionSelectorComponent = ({
{description && <StyledDescription>{description}</StyledDescription>}
<StyledButton onClick={() => setOpen(!open)}>
<StyledDisplay>
<div>
<div>{resourceVersions[selectedIdx]}</div>
</div>
<StyledSelected>{resourceVersions[selectedIdx]}</StyledSelected>
<ArrowIcon open={open} />
</StyledDisplay>
</StyledButton>

View File

@ -10,7 +10,7 @@ const transitionDuration = {
slower: 300,
} as const;
export const ArrowIcon = styled(ArrowSvg)`
export const ArrowIcon = styled(ArrowSvg)<{ open: boolean }>`
position: absolute;
pointer-events: none;
z-index: 1;
@ -101,12 +101,17 @@ export const StyledMenuList = styled.ul`
`;
export const StyledDisplay = styled.div`
width: 100%;
display: grid;
grid-template-columns: 1fr 16px;
gap: 6px;
padding: 0 4px 0 12px;
`;
export const StyledSelected = styled.div`
display: flex;
`;
export const disabledOptionStyle = css`
cursor: not-allowed;
color: ${palette.gray.base};

View File

@ -354,6 +354,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/packSize",
@ -687,6 +688,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/type",
@ -1007,6 +1009,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog",
@ -1389,6 +1392,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Cat/properties/type",
@ -1734,6 +1738,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Cat/properties/packSize",
@ -2050,6 +2055,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Cat",
@ -2391,6 +2397,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Pet",
@ -2762,6 +2769,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/packSize",
@ -3095,6 +3103,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/type",
@ -3415,6 +3424,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
},
"unstable_ignoreMimeParameters": false,
"untrustedSpec": false,
"versionData": undefined,
},
"pattern": undefined,
"pointer": "#/components/schemas/Dog",

View File

@ -17,12 +17,12 @@ exports[`VersionSelector should correctly render VersionSelector 1`] = `
class="sc-hKFxyN hYrDYQ"
>
<div
class="sc-iCoGMd fgtoGu"
class="sc-iCoGMd gojxeT"
>
<div>
<div>
2023-01-01
</div>
<div
class="sc-fujyAs hQJiDC"
>
2023-01-01
</div>
<svg
fill="none"
@ -44,7 +44,7 @@ exports[`VersionSelector should correctly render VersionSelector 1`] = `
</div>
<div
aria-labelledby="View a different version of documentation."
class="sc-jrsJWt ofjNY"
class="sc-kEqXSa litKaz"
role="listbox"
tabindex="-1"
>
@ -54,44 +54,44 @@ exports[`VersionSelector should correctly render VersionSelector 1`] = `
>
<li
aria-selected="false"
class="sc-fujyAs iIVhNL"
class="sc-pNWdM glxGCd"
role="option"
tabindex="0"
>
<span
class="sc-kEqXSa cBTyJc"
class="sc-iqAclL dXUzZL"
/>
<span
class="sc-pNWdM irvinq"
class="sc-jrsJWt hDLwjI"
>
2021-09-09
</span>
</li>
<li
aria-selected="false"
class="sc-fujyAs iIVhNL"
class="sc-pNWdM glxGCd"
role="option"
tabindex="0"
>
<span
class="sc-kEqXSa cBTyJc"
class="sc-iqAclL dXUzZL"
/>
<span
class="sc-pNWdM irvinq"
class="sc-jrsJWt hDLwjI"
>
2022-10-18
</span>
</li>
<li
aria-selected="true"
class="sc-fujyAs Ywdfd"
class="sc-pNWdM jlRKTH"
role="option"
selected=""
tabindex="0"
>
<svg
aria-label="Checkmark Icon"
class="sc-iqAclL ejyrfD"
class="sc-crzoAE gdYtkZ"
height="16"
role="img"
viewBox="0 0 16 16"
@ -105,7 +105,7 @@ exports[`VersionSelector should correctly render VersionSelector 1`] = `
/>
</svg>
<span
class="sc-pNWdM irvinq"
class="sc-jrsJWt hDLwjI"
>
2023-01-01
</span>

View File

@ -61,6 +61,16 @@ export interface RedocRawOptions {
backNavigationPath?: string;
ignoreIncompatibleTypes?: boolean | string;
siteTitle?: string;
versionData?: string;
}
export interface VersionData {
active: {
apiVersion: string;
resourceVersion: string;
};
rootUrl: string;
resourceVersions: string[];
}
export function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean {
@ -269,6 +279,7 @@ export class RedocNormalizedOptions {
backNavigationPath?: string;
ignoreIncompatibleTypes: boolean;
siteTitle?: string;
versionData?: string | VersionData;
constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) {
raw = { ...defaults, ...raw };
@ -351,5 +362,6 @@ export class RedocNormalizedOptions {
this.backNavigationPath = raw.backNavigationPath;
this.ignoreIncompatibleTypes = argValueToBoolean(raw.ignoreIncompatibleTypes);
this.siteTitle = raw.siteTitle;
this.versionData = raw.versionData;
}
}

8
version-data.json Normal file
View File

@ -0,0 +1,8 @@
{
"active": {
"apiVersion": "2.0",
"resourceVersion": "2023-02-14"
},
"rootUrl": "https://mongodb.com/docs/atlas/reference/api-resources-spec/v2",
"resourceVersions": ["2022-09-09", "2022-10-18", "2023-02-14"]
}