Skip to content

Commit

Permalink
Ga json primitive types (#1661)
Browse files Browse the repository at this point in the history
* fix: force swr cache invalidation

* chore: changeset

* fix: reduce the number of calls to the api by tweaking swr revalidate config

* chore: try different swr setup

* feat: handle json primitive types

* feat: render primitive json types

* chore: fix broken link

* fix: regressionvrt errors

* chore: address PR comments

* chore: changeset
  • Loading branch information
gabriele-ct authored May 10, 2023
1 parent 8fa2dbc commit 8759c1e
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 16 deletions.
7 changes: 7 additions & 0 deletions .changeset/many-tomatoes-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@commercetools-docs/gatsby-theme-api-docs': patch
'@commercetools-website/api-docs-smoke-test': patch
'@commercetools-api-specs/test': patch
---

Add support for primitive and generic JSON types in API request and response
15 changes: 15 additions & 0 deletions api-specs/test/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,21 @@ uses:
type: object
example: !include examples/action-success.json

/json-serializable-primitive-type:
put:
description: Use the PUT method to write data to a backend system. Any JSON serializable payload is accepted. The following request example adds a product to a cart. For the response, we recommend to use standard HTTP codes and `application/json` encoded content. The response will be structured [as defined by the `body` property of the action](/). The following response example contains the updated cart information, which includes the added product.
body:
application/json:
type: object
example: !include examples/json-serializable-primitive-object.json
responses:
200:
description: We recommend to use standard HTTP response codes and `application/json` encoded content. The response will look like the response you have declared in your action. As an example we will fetch the cart.
body:
application/json:
type: any
example: !include examples/json-serializable-primitive-raw.json


# /resourceWithHeaders:
# description: Tests use of specific headers.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"raw string"
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import SpacingsStack from '@commercetools-uikit/spacings-stack';
import SpacingsInline from '@commercetools-uikit/spacings-inline';
import { designSystem } from '@commercetools-docs/ui-kit';
import { designSystem, Markdown } from '@commercetools-docs/ui-kit';
import {
useTypeLocations,
locationForType,
Expand All @@ -12,6 +12,7 @@ import renderTypeAsLink from '../../../utils/render-type-as-link';
import ApiTypeByKey from '../../type/type-by-api-key';
import Title from './title';
import ContentType from './highlights';
import { getDescriptionIfPrimitiveType } from '../../type/type';

const RequestRepresentation = (props) => {
const typeLocations = useTypeLocations();
Expand All @@ -21,6 +22,19 @@ const RequestRepresentation = (props) => {
typeLocations
);

let primitiveJSONType;

if (
!requestRepresentationLocation &&
props.contentType &&
props.contentType.includes('application/json')
) {
primitiveJSONType = getDescriptionIfPrimitiveType(
'application/json',
props.apiType
);
}

const ContentTypeRow = styled.div`
display: flex;
align-items: center;
Expand All @@ -46,16 +60,21 @@ const RequestRepresentation = (props) => {
})}
<span>The file to upload</span>
</SpacingsInline>
) : requestRepresentationLocation ? (
) : requestRepresentationLocation || primitiveJSONType ? (
<SpacingsInline alignItems="center">
{renderTypeAsLink(props.apiKey, props.apiType, typeLocations)}
{primitiveJSONType ? (
<Markdown.Em>{primitiveJSONType}</Markdown.Em>
) : (
renderTypeAsLink(props.apiKey, props.apiType, typeLocations)
)}
<span>as</span>
<ContentType>{props.contentType}</ContentType>
</SpacingsInline>
) : (
<SpacingsStack>
<ContentType>{props.contentType}</ContentType>
<ApiTypeByKey
contentType={props.contentType}
apiKey={props.apiKey}
type={props.apiType}
doNotRenderExamples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ const Responses = ({ apiKey, responses, contentType }) => {
apiKey,
response.body.applicationjson.type,
typeLocations,
response.description
response.description,
contentType
)}
{contentType.length > 0 && (
<>
Expand Down
34 changes: 33 additions & 1 deletion packages/gatsby-theme-api-docs/src/components/type/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,44 @@ import Enum from './enum';
import Properties from './properties/properties';
import Examples from './examples';

const contentTypeToPrimitiveMap = {
'application/json': {
number: 'Any JSON "number"',
any: 'Any valid JSON',
object: 'Any JSON "object"',
boolean: 'Any JSON "boolean"',
string: 'Any JSON "string"',
array: 'Any JSON "array"',
},
};

export const getDescriptionIfPrimitiveType = (contentType, type) =>
contentTypeToPrimitiveMap[contentType] &&
contentTypeToPrimitiveMap[contentType][type];

const ApiType = (props) => {
const matchedApiType = props.apiTypes.find((apiType) => {
console.log(props);
let matchedApiType = props.apiTypes.find((apiType) => {
return (
apiType.apiKey === props.apiKey && apiType.displayName === props.type
);
});

if (!matchedApiType) {
if (props.contentType && props.contentType.includes('application/json')) {
const primitiveTypeDescription = getDescriptionIfPrimitiveType(
'application/json',
props.type
);
if (primitiveTypeDescription) {
matchedApiType = {
displayName: props.type,
description: primitiveTypeDescription,
};
}
}
}

if (!matchedApiType) {
return reportError(
`Type with name '${props.type}' not found in '${props.apiKey}' API`
Expand Down Expand Up @@ -92,6 +123,7 @@ ApiType.propTypes = {
]),
doNotRenderExamples: PropTypes.bool,
hideInheritedProperties: PropTypes.bool,
contentType: PropTypes.arrayOf(PropTypes.string),
};

export default ApiType;
38 changes: 27 additions & 11 deletions packages/gatsby-theme-api-docs/src/utils/render-type-as-link.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import React from 'react';
import { Link } from '@commercetools-docs/gatsby-theme-docs';
import { markdownFragmentToReact } from '@commercetools-docs/ui-kit';
import { markdownFragmentToReact, Markdown } from '@commercetools-docs/ui-kit';
import { locationForType } from '../hooks/use-type-locations';
import { getDescriptionIfPrimitiveType } from '../components/type/type';

function renderTypeAsLink(apiKey, type, typeLocations, description) {
function renderTypeAsLink(
apiKey,
type,
typeLocations,
description,
contentType
) {
const typeLocation = locationForType(apiKey, type, typeLocations);

const originalTypeLocation = typeLocation ? typeLocation.url : '';
const originalTypeLocation = typeLocation ? typeLocation.url : undefined;

return originalTypeLocation ? (
<Link href={originalTypeLocation}>{type}</Link>
) : description ? (
markdownFragmentToReact(description)
) : (
type
);
}
let primitiveJsonType;
if (
!originalTypeLocation &&
Array.isArray(contentType) &&
contentType.includes('application/json')
) {
primitiveJsonType = getDescriptionIfPrimitiveType('application/json', type);
}

if (originalTypeLocation) {
return <Link href={originalTypeLocation}>{type}</Link>;
} else if (primitiveJsonType) {
return <Markdown.Em>{primitiveJsonType}</Markdown.Em>;
} else if (description) {
return markdownFragmentToReact(description);
}
return type;
}
export default renderTypeAsLink;
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ import { ApiEndpointsForResource } from "/shortcodes"
# /{projectKey}/resource/namespace-action-with-example

<ApiEndpointsForResource apiKey="test" resource="/{projectKey}/resource/namespace-action-with-example" />

# /{projectKey}/resource/json-serializable-primitive-type

<ApiEndpointsForResource apiKey="test" resource="/{projectKey}/resource/json-serializable-primitive-type" />

0 comments on commit 8759c1e

Please sign in to comment.