docs: general fixes and improvements (#7918)

* docs improvements and changes

* updated module definition

* modules + dml changes

* fix build

* fix vale error

* fix lint errors

* fixes to stripe docs

* fix condition

* fix condition

* fix module defintion

* fix checkout

* disable UI action

* change oas preview action

* flatten provider module options

* fix lint errors

* add module link docs

* pr comments fixes

* fix vale error

* change node engine version

* links -> linkable

* add note about database name

* small fixes

* link fixes

* fix response code in api reference

* added migrations step
This commit is contained in:
Shahed Nasser
2024-07-04 17:26:03 +03:00
committed by GitHub
parent 32982e708a
commit 964927b597
149 changed files with 1676 additions and 3008 deletions
@@ -17,130 +17,128 @@ type ApiRunnerProps = {
bodyData?: Record<string, unknown>
}
export const ApiRunner = ({
apiMethod,
apiUrl,
pathData,
bodyData,
queryData,
}: ApiRunnerProps) => {
// assemble api testing options
const [apiTestingOptions, setApiTestingOptions] = useState<ApiTestingOptions>(
{
method: apiMethod,
url: apiUrl,
pathData,
bodyData,
queryData,
}
)
const [isRunning, setIsRunning] = useState(false)
const [ran, setRan] = useState(false)
const hasData = (data?: Record<string, unknown>): boolean =>
data !== undefined && Object.keys(data).length > 0
// TODO change to be based on whether auth/data needed
const manualTestTrigger = useMemo(
() =>
hasData(apiTestingOptions.pathData) ||
hasData(apiTestingOptions.queryData) ||
hasData(apiTestingOptions.bodyData),
[apiTestingOptions]
)
const [responseLogs, setResponseLogs] = useState<string[]>([])
const [responseCode, setResponseCode] = useState<string | undefined>()
const pushMessage = (...message: string[]) =>
setResponseLogs((prev) => [...prev, ...message])
const { runRequest } = useRequestRunner({
pushLog: pushMessage,
onFinish: (_message, statusCode) => {
setIsRunning(false)
setResponseCode(statusCode)
},
replaceLog: (message) => setResponseLogs([message]),
})
export const ApiRunner = React.forwardRef<HTMLDivElement, ApiRunnerProps>(
function ApiRunner(
{ apiMethod, apiUrl, pathData, bodyData, queryData }: ApiRunnerProps,
ref
) {
// assemble api testing options
const [apiTestingOptions, setApiTestingOptions] =
useState<ApiTestingOptions>({
method: apiMethod,
url: apiUrl,
pathData,
bodyData,
queryData,
})
const [isRunning, setIsRunning] = useState(false)
const [ran, setRan] = useState(false)
const hasData = (data?: Record<string, unknown>): boolean =>
data !== undefined && Object.keys(data).length > 0
// TODO change to be based on whether auth/data needed
const manualTestTrigger = useMemo(
() =>
hasData(apiTestingOptions.pathData) ||
hasData(apiTestingOptions.queryData) ||
hasData(apiTestingOptions.bodyData),
[apiTestingOptions]
)
const [responseLogs, setResponseLogs] = useState<string[]>([])
const [responseCode, setResponseCode] = useState<string | undefined>()
const pushMessage = (...message: string[]) =>
setResponseLogs((prev) => [...prev, ...message])
const { runRequest } = useRequestRunner({
pushLog: pushMessage,
onFinish: (_message, statusCode) => {
setIsRunning(false)
setResponseCode(statusCode)
},
replaceLog: (message) => setResponseLogs([message]),
})
useEffect(() => {
if (!isRunning && !manualTestTrigger && !ran) {
setIsRunning(true)
}
}, [apiTestingOptions, manualTestTrigger, isRunning, ran])
useEffect(() => {
if (!isRunning && !manualTestTrigger && !ran) {
setIsRunning(true)
}
}, [apiTestingOptions, manualTestTrigger, isRunning, ran])
useEffect(() => {
if (isRunning && !ran) {
setRan(true)
setResponseLogs(["Sending request..."])
runRequest(apiTestingOptions)
}
}, [isRunning, ran])
useEffect(() => {
if (isRunning && !ran) {
setRan(true)
setResponseLogs(["Sending request..."])
runRequest(apiTestingOptions)
}
}, [isRunning, ran])
return (
<>
{manualTestTrigger && (
<Card className="font-base mb-docs_1" contentClassName="gap-docs_0.5">
{apiTestingOptions.pathData && (
<ApiRunnerParamInputs
data={apiTestingOptions.pathData}
title="Path Parameters"
baseObjPath="pathData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
{apiTestingOptions.bodyData && (
<ApiRunnerParamInputs
data={apiTestingOptions.bodyData}
title="Request Body Parameters"
baseObjPath="bodyData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
{apiTestingOptions.queryData && (
<ApiRunnerParamInputs
data={apiTestingOptions.queryData}
title="Request Query Parameters"
baseObjPath="queryData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
<Button
onClick={() => {
setIsRunning(true)
setRan(false)
}}
>
Send Request
</Button>
</Card>
)}
{(isRunning || ran) && (
<CodeBlock
source={responseLogs.join("\n")}
lang="json"
title="Testing Result"
collapsed={true}
blockStyle="subtle"
noReport={true}
badgeLabel={responseCode}
badgeColor={
!responseCode
? undefined
: responseCode.startsWith("2")
? "green"
: "red"
}
/>
)}
</>
)
}
return (
<div ref={ref}>
{manualTestTrigger && (
<Card className="font-base mb-docs_1" contentClassName="gap-docs_0.5">
{apiTestingOptions.pathData && (
<ApiRunnerParamInputs
data={apiTestingOptions.pathData}
title="Path Parameters"
baseObjPath="pathData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
{apiTestingOptions.bodyData && (
<ApiRunnerParamInputs
data={apiTestingOptions.bodyData}
title="Request Body Parameters"
baseObjPath="bodyData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
{apiTestingOptions.queryData && (
<ApiRunnerParamInputs
data={apiTestingOptions.queryData}
title="Request Query Parameters"
baseObjPath="queryData"
setValue={
setApiTestingOptions as React.Dispatch<
React.SetStateAction<unknown>
>
}
/>
)}
<Button
onClick={() => {
setIsRunning(true)
setRan(false)
}}
>
Send Request
</Button>
</Card>
)}
{(isRunning || ran) && (
<CodeBlock
source={responseLogs.join("\n")}
lang="json"
title="Testing Result"
collapsed={true}
blockStyle="subtle"
noReport={true}
badgeLabel={responseCode}
badgeColor={
!responseCode
? undefined
: responseCode.startsWith("2")
? "green"
: "red"
}
/>
)}
</div>
)
}
)
@@ -78,6 +78,7 @@ export const CodeBlock = ({
const [showTesting, setShowTesting] = useState(false)
const codeContainerRef = useRef<HTMLDivElement>(null)
const codeRef = useRef<HTMLElement>(null)
const apiRunnerRef = useRef<HTMLDivElement>(null)
const [scrollable, setScrollable] = useState(false)
const hasInnerCodeBlock = useMemo(
() => hasTabs || title.length > 0,
@@ -399,6 +400,7 @@ export const CodeBlock = ({
enter: "animate-fadeIn animate-fastest",
exit: "animate-fadeOut animate-fastest",
}}
nodeRef={apiRunnerRef}
>
<ApiRunner
apiMethod={rest.testApiMethod!}
@@ -406,6 +408,7 @@ export const CodeBlock = ({
pathData={rest.testPathParams}
bodyData={rest.testBodyParams}
queryData={rest.testQueryParams}
ref={apiRunnerRef}
/>
</CSSTransition>
)}
@@ -48,12 +48,23 @@ export const useRequestRunner = ({
replaceLog ? replaceLog(stringifiedData) : pushLog(stringifiedData)
})
.catch((error) => {
pushLog(
`An error ocurred: ${JSON.stringify(error, undefined, 2)}`,
`\nThis could be a CORS error. You can resolve it by adding\nthe docs' URLto your CORS configurations:\n`,
`STORE_CORS=http://localhost:8000,https://docs.medusajs.com`,
`ADMIN_CORS=http://localhost:7001,https://docs.medusajs.com`
)
pushLog(`\nAn error ocurred: ${JSON.stringify(error, undefined, 2)}`)
if (responseCode === "404") {
pushLog(
`\nPossible Solutions:\n`,
`- If this is a custom API route, make sure you added it at the correct path.`,
`- If this API route accepts any parameters, such as an ID, make sure it exists\nin the Medusa application.`
)
return
}
if (!responseCode.length) {
pushLog(
`\nThis could be a CORS error. You can resolve it by adding\nthe docs' URLto your CORS configurations:\n`,
`STORE_CORS=http://localhost:8000,https://docs.medusajs.com`,
`ADMIN_CORS=http://localhost:7001,https://docs.medusajs.com`
)
}
})
.finally(() => onFinish(`Finished running request.`, responseCode))
}
@@ -30,6 +30,9 @@ export function useTabs<T extends BaseTabType>({ tabs, group }: TabProps<T>) {
const scrollPosition = useRef<number>(0)
const changeSelectedTab = (tab: T) => {
if (tab.value === selectedTab?.value) {
return
}
scrollPosition.current = window.scrollY
setSelectedTab(tab)
localStorage.setItem(storageKey, tab.value)
@@ -50,18 +50,23 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
const getFirstChild = (
item: SidebarItemType
): SidebarItemType | undefined => {
): SidebarItemWithParent | undefined => {
const children = getChildrenWithPages(item)
if (!children?.length) {
return undefined
}
return children[0].path ? children[0] : getFirstChild(children[0])
return children[0].path
? {
...children[0],
parent: item,
}
: getFirstChild(children[0])
}
const getChildrenWithPages = (
item: SidebarItemType
): SidebarItemType[] | undefined => {
): SidebarItemWithParent[] | undefined => {
return item.children?.filter(
(childItem) =>
childItem.path !== undefined || getChildrenWithPages(childItem)?.length