From 9ead47c51e6cc838a9b0aa15d00766a68ea626d3 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Tue, 18 Mar 2025 17:37:51 +0200 Subject: [PATCH] docs: add prepare script to generate sidebar (#11894) --- .../workflows/generate-public-references.yml | 5 + www/apps/api-reference/app/algolia/route.ts | 8 +- www/apps/api-reference/app/assets/sitemap.ts | 8 +- .../api-reference/app/base-specs/route.ts | 4 +- .../components/Description/index.tsx | 4 +- .../components/MDXComponents/H2/index.tsx | 29 +- .../Security/Description/index.tsx | 4 +- .../MDXComponents/Security/index.tsx | 4 +- .../components/MDXComponents/index.tsx | 4 +- .../CodeSection/RequestSamples/index.tsx | 4 +- .../CodeSection/Responses/Sample/index.tsx | 6 +- .../Operation/CodeSection/Responses/index.tsx | 4 +- .../Tags/Operation/CodeSection/index.tsx | 4 +- .../DescriptionSection/Parameters/index.tsx | 10 +- .../DescriptionSection/RequestBody/index.tsx | 4 +- .../DescriptionSection/Responses/index.tsx | 4 +- .../DescriptionSection/Security/index.tsx | 4 +- .../Operation/DescriptionSection/index.tsx | 4 +- .../Parameters/Description/index.tsx | 4 +- .../Tags/Operation/Parameters/Name/index.tsx | 8 +- .../Operation/Parameters/Section/index.tsx | 4 +- .../Parameters/Types/Array/index.tsx | 4 +- .../Parameters/Types/Default/index.tsx | 4 +- .../Parameters/Types/Object/index.tsx | 4 +- .../Parameters/Types/OneOf/index.tsx | 6 +- .../Parameters/Types/Union/index.tsx | 4 +- .../Tags/Operation/Parameters/index.tsx | 4 +- .../components/Tags/Operation/index.tsx | 9 +- .../components/Tags/Paths/index.tsx | 9 +- .../components/Tags/Section/Schema/index.tsx | 36 +- .../components/Tags/Section/index.tsx | 10 +- .../api-reference/components/Tags/index.tsx | 4 +- www/apps/api-reference/config/index.ts | 9 +- www/apps/api-reference/eslint.config.mjs | 1 + .../generated/generated-admin-sidebar.mjs | 784 ++++++++++++++++++ .../generated/generated-store-sidebar.mjs | 337 ++++++++ .../api-reference/hooks/use-schema-example.ts | 9 +- www/apps/api-reference/lib/index.ts | 6 +- www/apps/api-reference/next.config.mjs | 5 +- www/apps/api-reference/package.json | 4 +- www/apps/api-reference/providers/area.tsx | 21 +- .../api-reference/providers/base-specs.tsx | 71 +- www/apps/api-reference/providers/sidebar.tsx | 25 +- www/apps/api-reference/scripts/prepare.mjs | 22 + .../api-reference/utils/check-required.ts | 7 +- www/apps/api-reference/utils/dereference.ts | 12 +- .../api-reference/utils/get-paths-of-tag.ts | 12 +- .../api-reference/utils/get-schema-content.ts | 4 +- .../api-reference/utils/get-section-id.ts | 6 - .../utils/get-security-schema-type-name.ts | 4 +- .../utils/get-tag-child-sidebar-items.tsx | 11 +- .../api-reference/utils/merge-all-of-types.ts | 8 +- .../api-reference/utils/read-spec-document.ts | 4 +- www/apps/book/components/EditButton/index.tsx | 8 - www/packages/build-scripts/package.json | 2 + .../build-scripts/src/generate-sidebar.ts | 14 +- .../src/utils/get-api-ref-sidebar-children.ts | 85 ++ .../Sidebar/Item/Category/index.tsx | 19 +- .../components/Sidebar/Item/Link/index.tsx | 4 + .../components/Sidebar/Item/Sidebar/index.tsx | 5 +- .../Sidebar/Item/SubCategory/index.tsx | 5 +- .../docs-ui/src/providers/Sidebar/index.tsx | 146 +++- www/packages/docs-utils/package.json | 1 + www/packages/docs-utils/src/find-title.ts | 19 +- www/packages/docs-utils/src/get-clean-md.ts | 2 +- www/packages/docs-utils/src/index.ts | 1 + www/packages/docs-utils/src/sidebar-utils.ts | 7 + www/packages/types/package.json | 3 + www/packages/types/src/index.ts | 1 + .../types => packages/types/src}/openapi.ts | 2 + www/packages/types/src/sidebar.ts | 5 + www/yarn.lock | 89 +- 72 files changed, 1709 insertions(+), 295 deletions(-) create mode 100644 www/apps/api-reference/generated/generated-admin-sidebar.mjs create mode 100644 www/apps/api-reference/generated/generated-store-sidebar.mjs create mode 100644 www/apps/api-reference/scripts/prepare.mjs delete mode 100644 www/apps/api-reference/utils/get-section-id.ts create mode 100644 www/packages/build-scripts/src/utils/get-api-ref-sidebar-children.ts create mode 100644 www/packages/docs-utils/src/sidebar-utils.ts rename www/{apps/api-reference/types => packages/types/src}/openapi.ts (99%) diff --git a/.github/workflows/generate-public-references.yml b/.github/workflows/generate-public-references.yml index 51e64c8cf8..5ddcef0798 100644 --- a/.github/workflows/generate-public-references.yml +++ b/.github/workflows/generate-public-references.yml @@ -146,6 +146,10 @@ jobs: - name: Generate API Reference run: yarn openapi:generate + - name: Run prep script + run: yarn prep + working-directory: www/apps/api-reference + - name: Create Pull Request uses: peter-evans/create-pull-request@v4 with: @@ -156,6 +160,7 @@ jobs: add-paths: | www/apps/api-reference/specs www/utils/generated/oas-output + www/apps/api-reference/generated branch: "docs/generate-api-ref" branch-suffix: "timestamp" dml: diff --git a/www/apps/api-reference/app/algolia/route.ts b/www/apps/api-reference/app/algolia/route.ts index 94fcf465cd..3c495064b8 100644 --- a/www/apps/api-reference/app/algolia/route.ts +++ b/www/apps/api-reference/app/algolia/route.ts @@ -1,12 +1,12 @@ import OpenAPIParser from "@readme/openapi-parser" import algoliasearch from "algoliasearch" -import type { ExpandedDocument, Operation } from "../../types/openapi" +import type { OpenAPI } from "types" import path from "path" -import getSectionId from "../../utils/get-section-id" import { NextResponse } from "next/server" import { JSDOM } from "jsdom" import getUrl from "../../utils/get-url" import { capitalize } from "docs-ui" +import { getSectionId } from "docs-utils" export async function GET() { const algoliaClient = algoliasearch( @@ -50,7 +50,7 @@ export async function GET() { // find and index tag and operations const baseSpecs = (await OpenAPIParser.parse( path.join(process.cwd(), `specs/${area}/openapi.full.yaml`) - )) as ExpandedDocument + )) as OpenAPI.ExpandedDocument baseSpecs.tags?.map((tag) => { const tagName = getSectionId([tag.name]) @@ -71,7 +71,7 @@ export async function GET() { Object.values(paths).forEach((path) => { Object.values(path).forEach((op) => { - const operation = op as Operation + const operation = op as OpenAPI.Operation const tag = operation.tags?.[0] const operationName = getSectionId([tag || "", operation.operationId]) const url = getUrl(area, operationName) diff --git a/www/apps/api-reference/app/assets/sitemap.ts b/www/apps/api-reference/app/assets/sitemap.ts index 7de6e75f5b..109b44e6ef 100644 --- a/www/apps/api-reference/app/assets/sitemap.ts +++ b/www/apps/api-reference/app/assets/sitemap.ts @@ -1,11 +1,11 @@ import { MetadataRoute } from "next" import OpenAPIParser from "@readme/openapi-parser" import path from "path" -import type { ExpandedDocument, Operation } from "../../types/openapi" +import type { OpenAPI } from "types" import getUrl from "../../utils/get-url" -import getSectionId from "../../utils/get-section-id" import getPathsOfTag from "../../utils/get-paths-of-tag" import { config } from "../../config" +import { getSectionId } from "docs-utils" export default async function sitemap(): Promise { const baseUrl = config.baseUrl @@ -24,7 +24,7 @@ export default async function sitemap(): Promise { for (const area of ["store", "admin"]) { const baseSpecs = (await OpenAPIParser.parse( path.join(process.cwd(), `specs/${area}/openapi.yaml`) - )) as ExpandedDocument + )) as OpenAPI.ExpandedDocument await Promise.all( baseSpecs.tags?.map(async (tag) => { @@ -39,7 +39,7 @@ export default async function sitemap(): Promise { Object.values(paths.paths).forEach((path) => { Object.values(path).forEach((op) => { - const operation = op as Operation + const operation = op as OpenAPI.Operation const operationName = getSectionId([ tag.name, operation.operationId, diff --git a/www/apps/api-reference/app/base-specs/route.ts b/www/apps/api-reference/app/base-specs/route.ts index fb527b93e7..b0942e5820 100644 --- a/www/apps/api-reference/app/base-specs/route.ts +++ b/www/apps/api-reference/app/base-specs/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server" import path from "path" import OpenAPIParser from "@readme/openapi-parser" import getPathsOfTag from "@/utils/get-paths-of-tag" -import type { ExpandedDocument } from "@/types/openapi" +import type { OpenAPI } from "types" export async function GET(request: Request) { const { searchParams } = new URL(request.url) @@ -21,7 +21,7 @@ export async function GET(request: Request) { } const baseSpecs = (await OpenAPIParser.parse( path.join(process.cwd(), "specs", area, "openapi.yaml") - )) as ExpandedDocument + )) as OpenAPI.ExpandedDocument if (expand) { const paths = await getPathsOfTag(expand, area) diff --git a/www/apps/api-reference/components/Description/index.tsx b/www/apps/api-reference/components/Description/index.tsx index 99cbaaaf91..06f0496f49 100644 --- a/www/apps/api-reference/components/Description/index.tsx +++ b/www/apps/api-reference/components/Description/index.tsx @@ -1,11 +1,11 @@ "use server" -import type { OpenAPIV3 } from "openapi-types" +import type { OpenAPI } from "types" import Section from "../Section" import MDXContentServer from "../MDXContent/Server" export type DescriptionProps = { - specs: OpenAPIV3.Document + specs: OpenAPI.OpenAPIV3.Document } const Description = ({ specs }: DescriptionProps) => { diff --git a/www/apps/api-reference/components/MDXComponents/H2/index.tsx b/www/apps/api-reference/components/MDXComponents/H2/index.tsx index 5558dff8c3..ee181b18b5 100644 --- a/www/apps/api-reference/components/MDXComponents/H2/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/H2/index.tsx @@ -1,15 +1,14 @@ "use client" import { useScrollController, useSidebar, H2 as UiH2 } from "docs-ui" +import { getSectionId } from "docs-utils" import { useEffect, useMemo, useRef, useState } from "react" -import getSectionId from "../../../utils/get-section-id" -import { Sidebar } from "types" type H2Props = React.HTMLAttributes const H2 = ({ children, ...props }: H2Props) => { const headingRef = useRef(null) - const { activePath, addItems, removeItems, shownSidebar } = useSidebar() + const { activePath } = useSidebar() const { scrollableElement, scrollToElement } = useScrollController() const [scrolledFirstTime, setScrolledFirstTime] = useState(false) @@ -28,30 +27,6 @@ const H2 = ({ children, ...props }: H2Props) => { setScrolledFirstTime(scrolledFirstTime) }, [scrollableElement, headingRef, id]) - useEffect(() => { - if (!shownSidebar) { - return - } - const items: Sidebar.SidebarItem[] = [ - { - type: "link", - path: `${id}`, - title: children as string, - loaded: true, - }, - ] - addItems(items, { - sidebar_id: shownSidebar.sidebar_id, - }) - - return () => { - removeItems({ - items, - sidebar_id: shownSidebar.sidebar_id, - }) - } - }, [id, shownSidebar?.sidebar_id]) - return ( {children} diff --git a/www/apps/api-reference/components/MDXComponents/Security/Description/index.tsx b/www/apps/api-reference/components/MDXComponents/Security/Description/index.tsx index b5e1bdcf8f..f30fb0c08b 100644 --- a/www/apps/api-reference/components/MDXComponents/Security/Description/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/Security/Description/index.tsx @@ -1,6 +1,6 @@ import type { MDXContentClientProps } from "@/components/MDXContent/Client" import type { MDXContentServerProps } from "@/components/MDXContent/Server" -import type { SecuritySchemeObject } from "@/types/openapi" +import type { OpenAPI } from "types" import getSecuritySchemaTypeName from "@/utils/get-security-schema-type-name" import clsx from "clsx" import { Loading } from "docs-ui" @@ -21,7 +21,7 @@ const MDXContentServer = dynamic( ) as React.FC export type SecurityDescriptionProps = { - securitySchema: SecuritySchemeObject + securitySchema: OpenAPI.SecuritySchemeObject isServer?: boolean } diff --git a/www/apps/api-reference/components/MDXComponents/Security/index.tsx b/www/apps/api-reference/components/MDXComponents/Security/index.tsx index 7d975c7008..41104f900a 100644 --- a/www/apps/api-reference/components/MDXComponents/Security/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/Security/index.tsx @@ -1,5 +1,5 @@ import dynamic from "next/dynamic" -import type { OpenAPIV3 } from "openapi-types" +import type { OpenAPI } from "types" import type { SecurityDescriptionProps } from "./Description" import { Fragment } from "react" @@ -8,7 +8,7 @@ const SecurityDescription = dynamic( ) as React.FC type SecurityProps = { - specs?: OpenAPIV3.Document + specs?: OpenAPI.OpenAPIV3.Document } const Security = ({ specs }: SecurityProps) => { diff --git a/www/apps/api-reference/components/MDXComponents/index.tsx b/www/apps/api-reference/components/MDXComponents/index.tsx index 501fe51716..a39b8c7cda 100644 --- a/www/apps/api-reference/components/MDXComponents/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/index.tsx @@ -1,11 +1,11 @@ import type { MDXComponents } from "mdx/types" import Security from "./Security" -import type { OpenAPIV3 } from "openapi-types" +import type { OpenAPI } from "types" import H2 from "./H2" import { Link, MDXComponents as UiMDXComponents } from "docs-ui" export type ScopeType = { - specs?: OpenAPIV3.Document + specs?: OpenAPI.OpenAPIV3.Document addToSidebar?: boolean } diff --git a/www/apps/api-reference/components/Tags/Operation/CodeSection/RequestSamples/index.tsx b/www/apps/api-reference/components/Tags/Operation/CodeSection/RequestSamples/index.tsx index 58dbf7aa27..791d54e7cc 100644 --- a/www/apps/api-reference/components/Tags/Operation/CodeSection/RequestSamples/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/CodeSection/RequestSamples/index.tsx @@ -1,9 +1,9 @@ -import type { Code } from "@/types/openapi" +import type { OpenAPI } from "types" import { CodeBlock, CodeTab, CodeTabs } from "docs-ui" import slugify from "slugify" export type TagOperationCodeSectionRequestSamplesProps = { - codeSamples: Code[] + codeSamples: OpenAPI.Code[] } const TagOperationCodeSectionRequestSamples = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/Sample/index.tsx b/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/Sample/index.tsx index c6a0c63ef7..76009b19d8 100644 --- a/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/Sample/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/Sample/index.tsx @@ -1,10 +1,10 @@ import { CodeBlock } from "docs-ui" -import type { ExampleObject, ResponseObject } from "@/types/openapi" +import type { OpenAPI } from "types" import { useEffect, useState } from "react" import useSchemaExample from "../../../../../../hooks/use-schema-example" export type TagsOperationCodeSectionResponsesSampleProps = { - response: ResponseObject + response: OpenAPI.ResponseObject } & React.AllHTMLAttributes const TagsOperationCodeSectionResponsesSample = ({ @@ -20,7 +20,7 @@ const TagsOperationCodeSectionResponsesSample = ({ schemaExamples: contentSchema?.examples, }) const [selectedExample, setSelectedExample] = useState< - ExampleObject | undefined + OpenAPI.ExampleObject | undefined >() useEffect(() => { diff --git a/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/index.tsx b/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/index.tsx index 4c076814af..f2f5a9847a 100644 --- a/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/CodeSection/Responses/index.tsx @@ -1,4 +1,4 @@ -import type { Operation } from "@/types/openapi" +import type { OpenAPI } from "types" import dynamic from "next/dynamic" import type { TagsOperationCodeSectionResponsesSampleProps } from "./Sample" import { Badge } from "docs-ui" @@ -9,7 +9,7 @@ const TagsOperationCodeSectionResponsesSample = ) as React.FC type TagsOperationCodeSectionResponsesProps = { - operation: Operation + operation: OpenAPI.Operation } const TagsOperationCodeSectionResponses = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/CodeSection/index.tsx b/www/apps/api-reference/components/Tags/Operation/CodeSection/index.tsx index c13430fd95..a4c75eed7c 100644 --- a/www/apps/api-reference/components/Tags/Operation/CodeSection/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/CodeSection/index.tsx @@ -1,7 +1,7 @@ "use client" import MethodLabel from "@/components/MethodLabel" -import type { Operation } from "@/types/openapi" +import type { OpenAPI } from "types" import TagsOperationCodeSectionResponses from "./Responses" import type { TagOperationCodeSectionRequestSamplesProps } from "./RequestSamples" import dynamic from "next/dynamic" @@ -15,7 +15,7 @@ const TagOperationCodeSectionRequestSamples = ) as React.FC export type TagOperationCodeSectionProps = { - operation: Operation + operation: OpenAPI.Operation method: string endpointPath: string } & React.HTMLAttributes diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Parameters/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Parameters/index.tsx index 5ee1604ccb..e7aae8126b 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Parameters/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Parameters/index.tsx @@ -1,24 +1,24 @@ -import type { Parameter, SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import TagOperationParameters from "../../Parameters" export type TagsOperationDescriptionSectionParametersProps = { - parameters: Parameter[] + parameters: OpenAPI.Parameter[] } const TagsOperationDescriptionSectionParameters = ({ parameters, }: TagsOperationDescriptionSectionParametersProps) => { - const pathParameters: SchemaObject = { + const pathParameters: OpenAPI.SchemaObject = { type: "object", required: [], properties: {}, } - const queryParameters: SchemaObject = { + const queryParameters: OpenAPI.SchemaObject = { type: "object", required: [], properties: {}, } - const headerParameters: SchemaObject = { + const headerParameters: OpenAPI.SchemaObject = { type: "object", required: [], properties: {}, diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/RequestBody/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/RequestBody/index.tsx index a3d3b12526..10dacd2bb8 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/RequestBody/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/RequestBody/index.tsx @@ -1,9 +1,9 @@ -import type { RequestObject } from "@/types/openapi" +import type { OpenAPI } from "types" import TagOperationParameters from "../../Parameters" import { DetailsSummary } from "docs-ui" export type TagsOperationDescriptionSectionRequestProps = { - requestBody: RequestObject + requestBody: OpenAPI.RequestObject } const TagsOperationDescriptionSectionRequest = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Responses/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Responses/index.tsx index fcb376a875..61aa2d41c5 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Responses/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Responses/index.tsx @@ -1,11 +1,11 @@ -import type { ResponsesObject } from "@/types/openapi" +import type { OpenAPI } from "types" import clsx from "clsx" import TagOperationParameters from "../../Parameters" import { Fragment } from "react" import { Badge, Details, DetailsSummary } from "docs-ui" export type TagsOperationDescriptionSectionResponsesProps = { - responses: ResponsesObject + responses: OpenAPI.ResponsesObject } const TagsOperationDescriptionSectionResponses = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Security/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Security/index.tsx index f4b43e15f7..14812636cf 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Security/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Security/index.tsx @@ -1,10 +1,10 @@ import { useBaseSpecs } from "@/providers/base-specs" -import type { OpenAPIV3 } from "openapi-types" +import type { OpenAPI } from "types" import { Card } from "docs-ui" import { useMemo } from "react" export type TagsOperationDescriptionSectionSecurityProps = { - security: OpenAPIV3.SecurityRequirementObject[] + security: OpenAPI.OpenAPIV3.SecurityRequirementObject[] } const TagsOperationDescriptionSectionSecurity = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx index fd855e58b6..ad186040a6 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx @@ -1,6 +1,6 @@ "use client" -import type { Operation } from "@/types/openapi" +import type { OpenAPI } from "types" import type { TagsOperationDescriptionSectionSecurityProps } from "./Security" import type { TagsOperationDescriptionSectionRequestProps } from "./RequestBody" import type { TagsOperationDescriptionSectionResponsesProps } from "./Responses" @@ -33,7 +33,7 @@ const TagsOperationDescriptionSectionWorkflowBadge = ) as React.FC type TagsOperationDescriptionSectionProps = { - operation: Operation + operation: OpenAPI.Operation } const TagsOperationDescriptionSection = ({ operation, diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx index 0a133d7717..b588fa7061 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx @@ -1,5 +1,5 @@ import MDXContentClient from "@/components/MDXContent/Client" -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import clsx from "clsx" import dynamic from "next/dynamic" import { Fragment } from "react" @@ -10,7 +10,7 @@ const InlineCode = dynamic( ) as React.FC type TagOperationParametersDescriptionProps = { - schema: SchemaObject + schema: OpenAPI.SchemaObject } const TagOperationParametersDescription = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx index c42e065301..4eba3f1d22 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx @@ -1,11 +1,11 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import { Badge, ExpandableNotice, FeatureFlagNotice } from "docs-ui" import { Fragment } from "react" export type TagOperationParametersNameProps = { name: string isRequired?: boolean - schema: SchemaObject + schema: OpenAPI.SchemaObject } const TagOperationParametersName = ({ @@ -94,7 +94,7 @@ const TagOperationParametersName = ({ export default TagOperationParametersName -function formatArrayDescription(schema?: SchemaObject) { +function formatArrayDescription(schema?: OpenAPI.SchemaObject) { if (!schema) { return "Array" } @@ -107,7 +107,7 @@ function formatArrayDescription(schema?: SchemaObject) { return `Array of ${type}` } -function formatUnionDescription(arr?: SchemaObject[]) { +function formatUnionDescription(arr?: OpenAPI.SchemaObject[]) { const types = [...new Set(arr?.map((type) => type.type || "object"))] return <>{types.join(" or ")} } diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Section/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Section/index.tsx index 90eee66d32..4f648e62fd 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Section/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Section/index.tsx @@ -1,4 +1,4 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import clsx from "clsx" import type { TagOperationParametersProps } from ".." import dynamic from "next/dynamic" @@ -14,7 +14,7 @@ const TagOperationParameters = dynamic( type TagsOperationParametersSectionProps = { header?: string contentType?: string - schema: SchemaObject + schema: OpenAPI.SchemaObject } const TagsOperationParametersSection = ({ diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Array/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Array/index.tsx index 5f359d07a7..82bf25e002 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Array/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Array/index.tsx @@ -1,4 +1,4 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import dynamic from "next/dynamic" import type { TagOperationParametersDefaultProps } from "../Default" import type { TagOperationParametersProps } from "../.." @@ -22,7 +22,7 @@ const TagOperationParameters = dynamic( export type TagOperationParametersArrayProps = { name: string - schema: SchemaObject + schema: OpenAPI.SchemaObject isRequired?: boolean } diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx index 96b443e0d4..e094cd6680 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx @@ -1,11 +1,11 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import TagOperationParametersDescription from "../../Description" import clsx from "clsx" import TagOperationParametersName from "../../Name" export type TagOperationParametersDefaultProps = { name?: string - schema: SchemaObject + schema: OpenAPI.SchemaObject isRequired?: boolean className?: string expandable?: boolean diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Object/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Object/index.tsx index edc0a7af4a..82b28f3b68 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Object/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Object/index.tsx @@ -1,6 +1,6 @@ "use client" -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import TagOperationParametersDefault from "../Default" import dynamic from "next/dynamic" import type { TagOperationParametersProps } from "../.." @@ -33,7 +33,7 @@ const Details = dynamic( export type TagOperationParametersObjectProps = { name?: string - schema: SchemaObject + schema: OpenAPI.SchemaObject isRequired?: boolean topLevel?: boolean } diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/OneOf/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/OneOf/index.tsx index b5085ad255..3b201eade7 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/OneOf/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/OneOf/index.tsx @@ -1,4 +1,4 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import clsx from "clsx" import dynamic from "next/dynamic" import { useState } from "react" @@ -31,7 +31,7 @@ const TagsOperationParametersNested = ) as React.FC export type TagOperationParamatersOneOfProps = { - schema: SchemaObject + schema: OpenAPI.SchemaObject isRequired?: boolean isNested?: boolean } @@ -43,7 +43,7 @@ const TagOperationParamatersOneOf = ({ }: TagOperationParamatersOneOfProps) => { const [activeTab, setActiveTab] = useState(0) - const getName = (item: SchemaObject): string => { + const getName = (item: OpenAPI.SchemaObject): string => { if (item.title) { return item.title } diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Union/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Union/index.tsx index f3f96f387e..0521e27d88 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Union/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Union/index.tsx @@ -1,4 +1,4 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import dynamic from "next/dynamic" import type { TagOperationParametersDefaultProps } from "../Default" import { TagOperationParametersObjectProps } from "../Object" @@ -22,7 +22,7 @@ const TagOperationParametersDefault = export type TagOperationParametersUnionProps = { name: string - schema: SchemaObject + schema: OpenAPI.SchemaObject isRequired?: boolean topLevel?: boolean } diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/index.tsx index 09b30657b3..a850f9a5b8 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/index.tsx @@ -1,4 +1,4 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" import dynamic from "next/dynamic" import type { TagOperationParametersObjectProps } from "./Types/Object" import type { TagOperationParametersDefaultProps } from "./Types/Default" @@ -41,7 +41,7 @@ const TagOperationParamatersOneOf = dynamic( ) as React.FC export type TagOperationParametersProps = { - schemaObject: SchemaObject + schemaObject: OpenAPI.SchemaObject topLevel?: boolean className?: string isRequired?: boolean diff --git a/www/apps/api-reference/components/Tags/Operation/index.tsx b/www/apps/api-reference/components/Tags/Operation/index.tsx index c25c0c93cd..90bd9edabf 100644 --- a/www/apps/api-reference/components/Tags/Operation/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/index.tsx @@ -1,9 +1,7 @@ "use client" -import type { Operation } from "@/types/openapi" +import type { OpenAPI } from "types" import clsx from "clsx" -import type { OpenAPIV3 } from "openapi-types" -import getSectionId from "@/utils/get-section-id" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import dynamic from "next/dynamic" import { InView } from "react-intersection-observer" @@ -21,15 +19,16 @@ import { useRouter } from "next/navigation" import checkElementInViewport from "../../../utils/check-element-in-viewport" import DividedLoading from "../../DividedLoading" import SectionContainer from "../../Section/Container" +import { getSectionId } from "docs-utils" const TagOperationCodeSection = dynamic( async () => import("./CodeSection") ) as React.FC export type TagOperationProps = { - operation: Operation + operation: OpenAPI.Operation method?: string - tag: OpenAPIV3.TagObject + tag: OpenAPI.OpenAPIV3.TagObject endpointPath: string className?: string } diff --git a/www/apps/api-reference/components/Tags/Paths/index.tsx b/www/apps/api-reference/components/Tags/Paths/index.tsx index f4a0472317..27bdc14531 100644 --- a/www/apps/api-reference/components/Tags/Paths/index.tsx +++ b/www/apps/api-reference/components/Tags/Paths/index.tsx @@ -1,6 +1,6 @@ "use client" -import type { Operation, PathsObject, TagObject } from "@/types/openapi" +import type { OpenAPI } from "types" import { findSidebarItem, useSidebar } from "docs-ui" import { Fragment, Suspense, useEffect } from "react" import dynamic from "next/dynamic" @@ -16,8 +16,8 @@ const TagOperation = dynamic( ) as React.FC export type TagPathsProps = { - tag: TagObject - paths: PathsObject + tag: OpenAPI.TagObject + paths: OpenAPI.PathsObject } & React.HTMLAttributes const TagPaths = ({ tag, className, paths }: TagPathsProps) => { @@ -50,6 +50,7 @@ const TagPaths = ({ tag, className, paths }: TagPathsProps) => { path: "", changeLoaded: true, }, + indexPosition: tag["x-associatedSchema"] ? 1 : 0, }) } } @@ -66,7 +67,7 @@ const TagPaths = ({ tag, className, paths }: TagPathsProps) => { ([method, operation], operationIndex) => ( { - const { addItems, setActivePath, activePath, shownSidebar } = useSidebar() + const { setActivePath, activePath, shownSidebar, updateItems } = useSidebar() const { displayedArea } = useArea() const formattedName = useMemo( () => singular(tagName).replaceAll(" ", ""), @@ -56,34 +56,6 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { return isElmWindow(scrollableElement) ? document.body : scrollableElement }, [isBrowser, scrollableElement]) - useEffect(() => { - if (!shownSidebar) { - return - } - addItems( - [ - { - type: "link", - path: schemaSlug, - title: `${formattedName} Object`, - additionalElms: Schema, - loaded: true, - }, - ], - { - sidebar_id: shownSidebar.sidebar_id, - parent: { - type: "category", - title: tagName, - path: "", - changeLoaded: true, - }, - indexPosition: 0, - } - ) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [formattedName, shownSidebar?.sidebar_id]) - useEffect(() => { if (!isBrowser) { return diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx index 587eecb0f6..0ea3822aae 100644 --- a/www/apps/api-reference/components/Tags/Section/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/index.tsx @@ -1,6 +1,5 @@ "use client" -import getSectionId from "@/utils/get-section-id" import { InView } from "react-intersection-observer" import { useEffect, useMemo, useState } from "react" import { @@ -22,15 +21,16 @@ import SectionDivider from "../../Section/Divider" import clsx from "clsx" import { Feedback, Loading, Link } from "docs-ui" import { usePathname, useRouter } from "next/navigation" -import { PathsObject, SchemaObject, TagObject } from "@/types/openapi" +import { OpenAPI } from "types" import TagSectionSchema from "./Schema" import checkElementInViewport from "../../../utils/check-element-in-viewport" import TagPaths from "../Paths" import useSWR from "swr" import basePathUrl from "../../../utils/base-path-url" +import { getSectionId } from "docs-utils" export type TagSectionProps = { - tag: TagObject + tag: OpenAPI.TagObject } & React.HTMLAttributes const Section = dynamic( @@ -62,7 +62,7 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => { return isElmWindow(scrollableElement) ? document.body : scrollableElement }, [scrollableElement, isBrowser]) const { data: schemaData } = useSWR<{ - schema: SchemaObject + schema: OpenAPI.SchemaObject }>( loadData && tag["x-associatedSchema"] ? basePathUrl( @@ -75,7 +75,7 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => { } ) const { data: pathsData } = useSWR<{ - paths: PathsObject + paths: OpenAPI.PathsObject }>( loadData ? basePathUrl(`/tag?tagName=${slugTagName}&area=${area}`) : null, swrFetcher, diff --git a/www/apps/api-reference/components/Tags/index.tsx b/www/apps/api-reference/components/Tags/index.tsx index 459d49a61f..a1a2002839 100644 --- a/www/apps/api-reference/components/Tags/index.tsx +++ b/www/apps/api-reference/components/Tags/index.tsx @@ -1,4 +1,4 @@ -import { OpenAPIV3 } from "openapi-types" +import { OpenAPI } from "types" import { TagSectionProps } from "./Section" import dynamic from "next/dynamic" import { Suspense } from "react" @@ -8,7 +8,7 @@ const TagSection = dynamic( ) as React.FC type TagsProps = { - tags?: OpenAPIV3.TagObject[] + tags?: OpenAPI.OpenAPIV3.TagObject[] } const Tags = ({ tags }: TagsProps) => { diff --git a/www/apps/api-reference/config/index.ts b/www/apps/api-reference/config/index.ts index ea33d86448..360c4cefe3 100644 --- a/www/apps/api-reference/config/index.ts +++ b/www/apps/api-reference/config/index.ts @@ -12,14 +12,7 @@ export const config: DocsConfig = { { sidebar_id: "api-ref", title: "API Reference", - items: [ - { - type: "link", - title: "Introduction", - path: "introduction", - loaded: true, - }, - ], + items: [], }, ], project: { diff --git a/www/apps/api-reference/eslint.config.mjs b/www/apps/api-reference/eslint.config.mjs index b9455ad4d8..722b100ce3 100644 --- a/www/apps/api-reference/eslint.config.mjs +++ b/www/apps/api-reference/eslint.config.mjs @@ -28,6 +28,7 @@ export default [ "**/node_modules", "**/public", "**/.eslintrc.js", + "**/generated", ], }, ...compat.extends( diff --git a/www/apps/api-reference/generated/generated-admin-sidebar.mjs b/www/apps/api-reference/generated/generated-admin-sidebar.mjs new file mode 100644 index 0000000000..71fdb7f9ea --- /dev/null +++ b/www/apps/api-reference/generated/generated-admin-sidebar.mjs @@ -0,0 +1,784 @@ +const generatedgeneratedAdminSidebarSidebar = { + "sidebar_id": "admin", + "title": "Admin", + "items": [ + { + "type": "link", + "title": "Introduction", + "path": "introduction", + "loaded": true + }, + { + "type": "link", + "title": "Authentication", + "path": "authentication", + "loaded": true + }, + { + "type": "link", + "title": "HTTP Compression", + "path": "http-compression", + "loaded": true + }, + { + "type": "link", + "title": "Select Fields and Relations", + "path": "select-fields-and-relations", + "loaded": true + }, + { + "type": "link", + "title": "Query Parameter Types", + "path": "query-parameter-types", + "loaded": true + }, + { + "type": "link", + "title": "Pagination", + "path": "pagination", + "loaded": true + }, + { + "type": "link", + "title": "Workflows", + "path": "workflows", + "loaded": true + }, + { + "type": "separator" + }, + { + "type": "category", + "title": "Auth", + "children": [], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Api Keys", + "children": [ + { + "type": "link", + "path": "api-keys_apikey_schema", + "title": "ApiKey Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Campaigns", + "children": [ + { + "type": "link", + "path": "campaigns_campaign_schema", + "title": "Campaign Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Claims", + "children": [ + { + "type": "link", + "path": "claims_claim_schema", + "title": "Claim Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Collections", + "children": [ + { + "type": "link", + "path": "collections_collection_schema", + "title": "Collection Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Currencies", + "children": [ + { + "type": "link", + "path": "currencies_currency_schema", + "title": "Currency Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Customer Groups", + "children": [ + { + "type": "link", + "path": "customer-groups_customergroup_schema", + "title": "CustomerGroup Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Customers", + "children": [ + { + "type": "link", + "path": "customers_customer_schema", + "title": "Customer Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Draft Orders", + "children": [ + { + "type": "link", + "path": "draft-orders_draftorder_schema", + "title": "DraftOrder Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Exchanges", + "children": [ + { + "type": "link", + "path": "exchanges_exchange_schema", + "title": "Exchange Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Fulfillment Providers", + "children": [ + { + "type": "link", + "path": "fulfillment-providers_fulfillmentprovider_schema", + "title": "FulfillmentProvider Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Fulfillment Sets", + "children": [ + { + "type": "link", + "path": "fulfillment-sets_fulfillmentset_schema", + "title": "FulfillmentSet Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Fulfillments", + "children": [ + { + "type": "link", + "path": "fulfillments_fulfillment_schema", + "title": "Fulfillment Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Inventory Items", + "children": [ + { + "type": "link", + "path": "inventory-items_inventoryitem_schema", + "title": "InventoryItem Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Invites", + "children": [ + { + "type": "link", + "path": "invites_invite_schema", + "title": "Invite Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Notifications", + "children": [ + { + "type": "link", + "path": "notifications_notification_schema", + "title": "Notification Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Order Edits", + "children": [], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Orders", + "children": [ + { + "type": "link", + "path": "orders_order_schema", + "title": "Order Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Payment Collections", + "children": [ + { + "type": "link", + "path": "payment-collections_paymentcollection_schema", + "title": "PaymentCollection Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Payments", + "children": [ + { + "type": "link", + "path": "payments_payment_schema", + "title": "Payment Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Price Lists", + "children": [ + { + "type": "link", + "path": "price-lists_pricelist_schema", + "title": "PriceList Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Price Preferences", + "children": [ + { + "type": "link", + "path": "price-preferences_pricepreference_schema", + "title": "PricePreference Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Categories", + "children": [ + { + "type": "link", + "path": "product-categories_productcategory_schema", + "title": "ProductCategory Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Tags", + "children": [ + { + "type": "link", + "path": "product-tags_producttag_schema", + "title": "ProductTag Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Types", + "children": [ + { + "type": "link", + "path": "product-types_producttype_schema", + "title": "ProductType Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Variants", + "children": [ + { + "type": "link", + "path": "product-variants_productvariant_schema", + "title": "ProductVariant Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Products", + "children": [ + { + "type": "link", + "path": "products_product_schema", + "title": "Product Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Promotions", + "children": [ + { + "type": "link", + "path": "promotions_promotion_schema", + "title": "Promotion Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Refund Reasons", + "children": [ + { + "type": "link", + "path": "refund-reasons_refundreason_schema", + "title": "RefundReason Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Regions", + "children": [ + { + "type": "link", + "path": "regions_region_schema", + "title": "Region Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Reservations", + "children": [ + { + "type": "link", + "path": "reservations_reservation_schema", + "title": "Reservation Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Return Reasons", + "children": [ + { + "type": "link", + "path": "return-reasons_returnreason_schema", + "title": "ReturnReason Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Returns", + "children": [ + { + "type": "link", + "path": "returns_return_schema", + "title": "Return Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Sales Channels", + "children": [ + { + "type": "link", + "path": "sales-channels_saleschannel_schema", + "title": "SalesChannel Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Shipping Options", + "children": [ + { + "type": "link", + "path": "shipping-options_shippingoption_schema", + "title": "ShippingOption Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Shipping Profiles", + "children": [ + { + "type": "link", + "path": "shipping-profiles_shippingprofile_schema", + "title": "ShippingProfile Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Stock Locations", + "children": [ + { + "type": "link", + "path": "stock-locations_stocklocation_schema", + "title": "StockLocation Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Stores", + "children": [ + { + "type": "link", + "path": "stores_store_schema", + "title": "Store Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Tax Rates", + "children": [ + { + "type": "link", + "path": "tax-rates_taxrate_schema", + "title": "TaxRate Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Tax Regions", + "children": [ + { + "type": "link", + "path": "tax-regions_taxregion_schema", + "title": "TaxRegion Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Uploads", + "children": [], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Users", + "children": [ + { + "type": "link", + "path": "users_user_schema", + "title": "User Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Workflows Executions", + "children": [], + "loaded": false, + "showLoadingIfEmpty": true + } + ], + "custom_autogenerate": "api-ref" +} + +export default generatedgeneratedAdminSidebarSidebar \ No newline at end of file diff --git a/www/apps/api-reference/generated/generated-store-sidebar.mjs b/www/apps/api-reference/generated/generated-store-sidebar.mjs new file mode 100644 index 0000000000..e0e8f3a2e5 --- /dev/null +++ b/www/apps/api-reference/generated/generated-store-sidebar.mjs @@ -0,0 +1,337 @@ +const generatedgeneratedStoreSidebarSidebar = { + "sidebar_id": "store", + "title": "Store", + "items": [ + { + "type": "link", + "title": "Introduction", + "path": "introduction", + "loaded": true + }, + { + "type": "link", + "title": "Authentication", + "path": "authentication", + "loaded": true + }, + { + "type": "link", + "title": "Publishable API Key", + "path": "publishable-api-key", + "loaded": true + }, + { + "type": "link", + "title": "HTTP Compression", + "path": "http-compression", + "loaded": true + }, + { + "type": "link", + "title": "Select Fields and Relations", + "path": "select-fields-and-relations", + "loaded": true + }, + { + "type": "link", + "title": "Query Parameter Types", + "path": "query-parameter-types", + "loaded": true + }, + { + "type": "link", + "title": "Pagination", + "path": "pagination", + "loaded": true + }, + { + "type": "link", + "title": "Workflows", + "path": "workflows", + "loaded": true + }, + { + "type": "separator" + }, + { + "type": "category", + "title": "Auth", + "children": [], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Carts", + "children": [ + { + "type": "link", + "path": "carts_cart_schema", + "title": "Cart Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Collections", + "children": [ + { + "type": "link", + "path": "collections_collection_schema", + "title": "Collection Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Currencies", + "children": [ + { + "type": "link", + "path": "currencies_currency_schema", + "title": "Currency Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Customers", + "children": [ + { + "type": "link", + "path": "customers_customer_schema", + "title": "Customer Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Orders", + "children": [ + { + "type": "link", + "path": "orders_order_schema", + "title": "Order Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Payment Collections", + "children": [ + { + "type": "link", + "path": "payment-collections_paymentcollection_schema", + "title": "PaymentCollection Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Payment Providers", + "children": [ + { + "type": "link", + "path": "payment-providers_paymentprovider_schema", + "title": "PaymentProvider Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Categories", + "children": [ + { + "type": "link", + "path": "product-categories_productcategory_schema", + "title": "ProductCategory Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Tags", + "children": [ + { + "type": "link", + "path": "product-tags_producttag_schema", + "title": "ProductTag Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Product Types", + "children": [ + { + "type": "link", + "path": "product-types_producttype_schema", + "title": "ProductType Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Products", + "children": [ + { + "type": "link", + "path": "products_product_schema", + "title": "Product Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Regions", + "children": [ + { + "type": "link", + "path": "regions_region_schema", + "title": "Region Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Return", + "children": [ + { + "type": "link", + "path": "return_return_schema", + "title": "Return Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Return Reasons", + "children": [ + { + "type": "link", + "path": "return-reasons_returnreason_schema", + "title": "ReturnReason Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + }, + { + "type": "category", + "title": "Shipping Options", + "children": [ + { + "type": "link", + "path": "shipping-options_shippingoption_schema", + "title": "ShippingOption Object", + "loaded": true, + "badge": { + "variant": "neutral", + "text": "Schema" + } + } + ], + "loaded": false, + "showLoadingIfEmpty": true + } + ], + "custom_autogenerate": "api-ref" +} + +export default generatedgeneratedStoreSidebarSidebar \ No newline at end of file diff --git a/www/apps/api-reference/hooks/use-schema-example.ts b/www/apps/api-reference/hooks/use-schema-example.ts index 774b157a02..9c510b06d5 100644 --- a/www/apps/api-reference/hooks/use-schema-example.ts +++ b/www/apps/api-reference/hooks/use-schema-example.ts @@ -1,15 +1,14 @@ "use client" import { useMemo } from "react" -import { ExampleObject, SchemaObject } from "../types/openapi" +import { OpenAPI } from "types" import type { JSONSchema7 } from "json-schema" import stringify from "json-stringify-pretty-compact" import { sample } from "openapi-sampler" -import { OpenAPIV3 } from "openapi-types" type Options = { - schema?: SchemaObject - schemaExamples?: OpenAPIV3.ExampleObject + schema?: OpenAPI.SchemaObject + schemaExamples?: OpenAPI.OpenAPIV3.ExampleObject schemaExample?: any options?: { skipNonRequired?: boolean @@ -24,7 +23,7 @@ const useSchemaExample = ({ }: Options) => { const { skipNonRequired = true } = options const examples = useMemo(() => { - const tempExamples: ExampleObject[] = [] + const tempExamples: OpenAPI.ExampleObject[] = [] if (!schema) { return tempExamples diff --git a/www/apps/api-reference/lib/index.ts b/www/apps/api-reference/lib/index.ts index b8dc4aa565..384e9a416d 100644 --- a/www/apps/api-reference/lib/index.ts +++ b/www/apps/api-reference/lib/index.ts @@ -1,10 +1,10 @@ "use server" -import { Area, ExpandedDocument } from "../types/openapi" +import { OpenAPI } from "types" const URL = `${process.env.NEXT_PUBLIC_BASE_URL}${process.env.NEXT_PUBLIC_BASE_PATH}` -export async function getBaseSpecs(area: Area) { +export async function getBaseSpecs(area: OpenAPI.Area) { try { const res = await fetch(`${URL}/base-specs?area=${area}`, { next: { @@ -13,7 +13,7 @@ export async function getBaseSpecs(area: Area) { }, }).then(async (res) => res.json()) - return res as ExpandedDocument + return res as OpenAPI.ExpandedDocument } catch (e) { console.error(e) } diff --git a/www/apps/api-reference/next.config.mjs b/www/apps/api-reference/next.config.mjs index feb425b200..b58c767e1f 100644 --- a/www/apps/api-reference/next.config.mjs +++ b/www/apps/api-reference/next.config.mjs @@ -18,7 +18,10 @@ const nextConfig = { return config }, - transpilePackages: ["docs-ui"], + transpilePackages: ["docs-ui", "docs-utils"], + experimental: { + optimizePackageImports: ["docs-utils"], + }, async redirects() { return [ { diff --git a/www/apps/api-reference/package.json b/www/apps/api-reference/package.json index 3e5549eee2..a8cfb05d1d 100644 --- a/www/apps/api-reference/package.json +++ b/www/apps/api-reference/package.json @@ -10,7 +10,8 @@ "build:prod": "NEXT_PUBLIC_ENV=production next build", "start": "next start", "start:monorepo": "yarn start -p 3000", - "lint": "next lint --fix" + "lint": "next lint --fix", + "prep": "node ./scripts/prepare.mjs" }, "dependencies": { "@mdx-js/loader": "^3.1.0", @@ -31,7 +32,6 @@ "next": "15.0.4", "next-mdx-remote": "5.0.0", "openapi-sampler": "^1.3.1", - "openapi-types": "^12.1.3", "pluralize": "^8.0.0", "postcss": "8.4.27", "prism-react-renderer": "2.4.0", diff --git a/www/apps/api-reference/providers/area.tsx b/www/apps/api-reference/providers/area.tsx index 84ad5cbb01..198a67d624 100644 --- a/www/apps/api-reference/providers/area.tsx +++ b/www/apps/api-reference/providers/area.tsx @@ -1,27 +1,30 @@ "use client" -import type { Area } from "@/types/openapi" -import { capitalize, usePrevious, useSearch } from "docs-ui" +import type { OpenAPI } from "types" +import { capitalize, usePrevious, useSearch, useSidebar } from "docs-ui" import { createContext, useContext, useEffect, useMemo, useState } from "react" +import { usePathname } from "next/navigation" type AreaContextType = { - area: Area - prevArea: Area | undefined + area: OpenAPI.Area + prevArea: OpenAPI.Area | undefined displayedArea: string - setArea: (value: Area) => void + setArea: (value: OpenAPI.Area) => void } const AreaContext = createContext(null) type AreaProviderProps = { - area: Area + area: OpenAPI.Area children: React.ReactNode } const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => { - const [area, setArea] = useState(passedArea) + const [area, setArea] = useState(passedArea) const prevArea = usePrevious(area) const { defaultFilters, setDefaultFilters } = useSearch() + const { setActivePath } = useSidebar() + const pathname = usePathname() const displayedArea = useMemo(() => { return capitalize(area) @@ -33,6 +36,10 @@ const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => { } }, [area, defaultFilters, setDefaultFilters]) + useEffect(() => { + setActivePath(null) + }, [pathname]) + return ( SecuritySchemeObject | null + baseSpecs: OpenAPI.ExpandedDocument | undefined + getSecuritySchema: ( + securityName: string + ) => OpenAPI.SecuritySchemeObject | null } const BaseSpecsContext = createContext(null) type BaseSpecsProviderProps = { - baseSpecs: ExpandedDocument | undefined + baseSpecs: OpenAPI.ExpandedDocument | undefined children?: ReactNode } const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => { const router = useRouter() - const { activePath, addItems, setActivePath, resetItems, shownSidebar } = + const { activePath, setActivePath, resetItems, shownSidebar, updateItems } = useSidebar() const getSecuritySchema = ( securityName: string - ): SecuritySchemeObject | null => { + ): OpenAPI.SecuritySchemeObject | null => { if ( baseSpecs?.components?.securitySchemes && Object.prototype.hasOwnProperty.call( @@ -44,16 +46,12 @@ const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => { return null } - const itemsToAdd = useMemo(() => { + const itemsToUpdate = useMemo(() => { if (!baseSpecs) { return [] } - const itemsToAdd: Sidebar.SidebarItem[] = [ - { - type: "separator", - }, - ] + const itemsToUpdate: UpdateActionType["items"] = [] baseSpecs.tags?.forEach((tag) => { const tagPathName = getSectionId([tag.name.toLowerCase()]) @@ -62,37 +60,44 @@ const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => { Object.hasOwn(baseSpecs.expandedTags, tagPathName) ? getTagChildSidebarItems(baseSpecs.expandedTags[tagPathName]) : [] - itemsToAdd.push({ - type: "category", - title: tag.name, - children: childItems, - loaded: childItems.length > 0, - showLoadingIfEmpty: true, - onOpen: () => { - if (location.hash !== tagPathName) { - router.push(`#${tagPathName}`, { - scroll: false, - }) - } - if (activePath !== tagPathName) { - setActivePath(tagPathName) - } + itemsToUpdate.push({ + existingItem: { + type: "category", + title: tag.name, + }, + newItem: { + children: childItems, + loaded: childItems.length > 0, + onOpen: () => { + if (location.hash !== tagPathName) { + router.push(`#${tagPathName}`, { + scroll: false, + }) + } + if (activePath !== tagPathName) { + setActivePath(tagPathName) + } + }, + }, + options: { + setChildrenBehavior: "merge", }, }) }) - return itemsToAdd + return itemsToUpdate }, [baseSpecs]) useEffect(() => { - if (!itemsToAdd.length || !shownSidebar) { + if (!itemsToUpdate.length || !shownSidebar) { return } - addItems(itemsToAdd, { + updateItems({ sidebar_id: shownSidebar.sidebar_id, + items: itemsToUpdate, }) - }, [itemsToAdd, shownSidebar?.sidebar_id]) + }, [itemsToUpdate, shownSidebar?.sidebar_id]) useEffect(() => { return () => { diff --git a/www/apps/api-reference/providers/sidebar.tsx b/www/apps/api-reference/providers/sidebar.tsx index 6a4bb4de9f..42319d26fb 100644 --- a/www/apps/api-reference/providers/sidebar.tsx +++ b/www/apps/api-reference/providers/sidebar.tsx @@ -5,6 +5,9 @@ import { usePageLoading, useScrollController, } from "docs-ui" +import { usePathname } from "next/navigation" +import { Sidebar } from "types" +import { useCallback, useEffect, useState } from "react" import { config } from "../config" type SidebarProviderProps = { @@ -14,6 +17,26 @@ type SidebarProviderProps = { const SidebarProvider = ({ children }: SidebarProviderProps) => { const { isLoading, setIsLoading } = usePageLoading() const { scrollableElement } = useScrollController() + const [sidebar, setSidebar] = useState() + const path = usePathname() + + const loadSidebar = useCallback(async () => { + if (path.startsWith("/store")) { + return (await import("../generated/generated-store-sidebar.mjs")) + .default as Sidebar.Sidebar + } + + return (await import("../generated/generated-admin-sidebar.mjs")) + .default as Sidebar.Sidebar + }, [path]) + + useEffect(() => { + loadSidebar() + .then(setSidebar) + .catch((error) => { + console.error("Error loading sidebar:", error) + }) + }, [loadSidebar]) return ( { shouldHandleHashChange={true} shouldHandlePathChange={false} scrollableElement={scrollableElement} - sidebars={config.sidebars} + sidebars={sidebar ? [sidebar] : config.sidebars} persistCategoryState={false} disableActiveTransition={false} isSidebarStatic={false} diff --git a/www/apps/api-reference/scripts/prepare.mjs b/www/apps/api-reference/scripts/prepare.mjs new file mode 100644 index 0000000000..9d6f496faf --- /dev/null +++ b/www/apps/api-reference/scripts/prepare.mjs @@ -0,0 +1,22 @@ +import { generateSplitSidebars } from "build-scripts" + +async function main() { + await generateSplitSidebars({ + sidebars: [ + { + sidebar_id: "store", + title: "Store", + items: [], + custom_autogenerate: "api-ref", + }, + { + sidebar_id: "admin", + title: "Admin", + items: [], + custom_autogenerate: "api-ref", + }, + ], + }) +} + +void main() diff --git a/www/apps/api-reference/utils/check-required.ts b/www/apps/api-reference/utils/check-required.ts index 999e553027..ed26fa3606 100644 --- a/www/apps/api-reference/utils/check-required.ts +++ b/www/apps/api-reference/utils/check-required.ts @@ -1,5 +1,8 @@ -import type { SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" -export default function checkRequired(schema: SchemaObject, property?: string) { +export default function checkRequired( + schema: OpenAPI.SchemaObject, + property?: string +) { return property !== undefined && schema.required?.includes(property) } diff --git a/www/apps/api-reference/utils/dereference.ts b/www/apps/api-reference/utils/dereference.ts index a96b0c9204..5dcef89b1e 100644 --- a/www/apps/api-reference/utils/dereference.ts +++ b/www/apps/api-reference/utils/dereference.ts @@ -1,19 +1,19 @@ -import { Document, ParsedPathItemObject, SchemaObject } from "@/types/openapi" +import { OpenAPI } from "types" import OpenAPIParser from "@readme/openapi-parser" type Options = { basePath: string - paths?: ParsedPathItemObject[] - schemas?: SchemaObject[] + paths?: OpenAPI.ParsedPathItemObject[] + schemas?: OpenAPI.SchemaObject[] } export default async function dereference({ basePath, paths, schemas, -}: Options): Promise { +}: Options): Promise { // dereference the references in the paths - let document: Document = { + let document: OpenAPI.Document = { paths: {}, // These attributes are only for validation purposes openapi: "3.0.0", @@ -56,7 +56,7 @@ export default async function dereference({ dereference: { circular: "ignore", }, - })) as unknown as Document + })) as unknown as OpenAPI.Document return document } diff --git a/www/apps/api-reference/utils/get-paths-of-tag.ts b/www/apps/api-reference/utils/get-paths-of-tag.ts index 89f940f330..23cd7da47d 100644 --- a/www/apps/api-reference/utils/get-paths-of-tag.ts +++ b/www/apps/api-reference/utils/get-paths-of-tag.ts @@ -1,28 +1,26 @@ import path from "path" import { promises as fs } from "fs" -import type { OpenAPIV3 } from "openapi-types" -import type { Operation, Document, ParsedPathItemObject } from "@/types/openapi" +import type { OpenAPI } from "types" import readSpecDocument from "./read-spec-document" -import getSectionId from "./get-section-id" import dereference from "./dereference" import { unstable_cache } from "next/cache" -import { oasFileToPath } from "docs-utils" +import { getSectionId, oasFileToPath } from "docs-utils" async function getPathsOfTag_( tagName: string, area: string -): Promise { +): Promise { // get path files const basePath = path.join(process.cwd(), "specs", `${area}/paths`) const files = await fs.readdir(basePath) // read the path documents - let documents: ParsedPathItemObject[] = await Promise.all( + let documents: OpenAPI.ParsedPathItemObject[] = await Promise.all( files.map(async (file) => { const fileContent = (await readSpecDocument( path.join(basePath, file) - )) as OpenAPIV3.PathItemObject + )) as OpenAPI.OpenAPIV3.PathItemObject return { ...fileContent, diff --git a/www/apps/api-reference/utils/get-schema-content.ts b/www/apps/api-reference/utils/get-schema-content.ts index b261762a6c..620d811f4d 100644 --- a/www/apps/api-reference/utils/get-schema-content.ts +++ b/www/apps/api-reference/utils/get-schema-content.ts @@ -1,12 +1,12 @@ import { promises as fs } from "fs" import { parseDocument } from "yaml" -import { SchemaObject } from "../types/openapi" +import { OpenAPI } from "types" import dereference from "./dereference" import { unstable_cache } from "next/cache" async function getSchemaContent_(schemaPath: string, baseSchemasPath: string) { const schemaContent = await fs.readFile(schemaPath, "utf-8") - const schema = parseDocument(schemaContent).toJS() as SchemaObject + const schema = parseDocument(schemaContent).toJS() as OpenAPI.SchemaObject // resolve references in schema const dereferencedDocument = await dereference({ diff --git a/www/apps/api-reference/utils/get-section-id.ts b/www/apps/api-reference/utils/get-section-id.ts deleted file mode 100644 index 11b422fb8c..0000000000 --- a/www/apps/api-reference/utils/get-section-id.ts +++ /dev/null @@ -1,6 +0,0 @@ -import slugify from "slugify" - -export default function getSectionId(path: string[]) { - path = path.map((p) => slugify(p.trim().toLowerCase())) - return path.join("_") -} diff --git a/www/apps/api-reference/utils/get-security-schema-type-name.ts b/www/apps/api-reference/utils/get-security-schema-type-name.ts index 3953f6a204..458ba27051 100644 --- a/www/apps/api-reference/utils/get-security-schema-type-name.ts +++ b/www/apps/api-reference/utils/get-security-schema-type-name.ts @@ -1,7 +1,7 @@ -import { OpenAPIV3 } from "openapi-types" +import { OpenAPI } from "types" export default function getSecuritySchemaTypeName( - securitySchema: OpenAPIV3.SecuritySchemeObject + securitySchema: OpenAPI.OpenAPIV3.SecuritySchemeObject ) { switch (securitySchema.type) { case "apiKey": diff --git a/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx b/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx index b5e4f15a5d..a73db267de 100644 --- a/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx +++ b/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx @@ -1,22 +1,21 @@ -import type { Operation, PathsObject } from "@/types/openapi" -import type { OpenAPIV3 } from "openapi-types" +import type { OpenAPI } from "types" import dynamic from "next/dynamic" import type { MethodLabelProps } from "@/components/MethodLabel" -import getSectionId from "./get-section-id" import { Sidebar } from "types" +import { getSectionId } from "docs-utils" const MethodLabel = dynamic( async () => import("../components/MethodLabel") ) as React.FC export default function getTagChildSidebarItems( - paths: PathsObject + paths: OpenAPI.PathsObject ): Sidebar.SidebarItem[] { const items: Sidebar.SidebarItem[] = [] Object.entries(paths).forEach(([, operations]) => { Object.entries(operations).map(([method, operation]) => { - const definedOperation = operation as Operation - const definedMethod = method as OpenAPIV3.HttpMethods + const definedOperation = operation as OpenAPI.Operation + const definedMethod = method as OpenAPI.OpenAPIV3.HttpMethods items.push({ type: "link", path: getSectionId([ diff --git a/www/apps/api-reference/utils/merge-all-of-types.ts b/www/apps/api-reference/utils/merge-all-of-types.ts index 057bbedf43..e9a79487b9 100644 --- a/www/apps/api-reference/utils/merge-all-of-types.ts +++ b/www/apps/api-reference/utils/merge-all-of-types.ts @@ -1,14 +1,14 @@ -import type { PropertiesObject, SchemaObject } from "@/types/openapi" +import type { OpenAPI } from "types" export default function mergeAllOfTypes( - allOfSchema: SchemaObject -): SchemaObject { + allOfSchema: OpenAPI.SchemaObject +): OpenAPI.SchemaObject { if (!allOfSchema.allOf) { // return whatever the schema is return allOfSchema } // merge objects' properties in this var - let properties: PropertiesObject = {} + let properties: OpenAPI.PropertiesObject = {} let foundObjects = false allOfSchema.allOf.forEach((item) => { diff --git a/www/apps/api-reference/utils/read-spec-document.ts b/www/apps/api-reference/utils/read-spec-document.ts index e7fd8f679e..fbb833ac86 100644 --- a/www/apps/api-reference/utils/read-spec-document.ts +++ b/www/apps/api-reference/utils/read-spec-document.ts @@ -1,8 +1,8 @@ import { promises as fs } from "fs" -import { OpenAPIV3 } from "openapi-types" +import { OpenAPI } from "types" import { parseDocument } from "yaml" export default async function readSpecDocument(filePath: string) { const fileContent = await fs.readFile(filePath, "utf-8") - return parseDocument(fileContent).toJS() as OpenAPIV3.PathItemObject + return parseDocument(fileContent).toJS() as OpenAPI.OpenAPIV3.PathItemObject } diff --git a/www/apps/book/components/EditButton/index.tsx b/www/apps/book/components/EditButton/index.tsx index 159b0a1e63..ff6c2ee428 100644 --- a/www/apps/book/components/EditButton/index.tsx +++ b/www/apps/book/components/EditButton/index.tsx @@ -8,14 +8,6 @@ const EditButton = () => { const pathname = usePathname() const [editDate, setEditDate] = useState() - // const editDate = useMemo( - // () => - // (generatedEditDates as Record)[ - // `app${pathname.replace(/\/$/, "")}/page.mdx` - // ], - // [pathname] - // ) - const loadEditDate = useCallback(async () => { const generatedEditDates = (await import("../../generated/edit-dates.mjs")) .generatedEditDates diff --git a/www/packages/build-scripts/package.json b/www/packages/build-scripts/package.json index 7e3b80b918..f3309fd6ea 100644 --- a/www/packages/build-scripts/package.json +++ b/www/packages/build-scripts/package.json @@ -28,8 +28,10 @@ "watch": "tsc --watch" }, "dependencies": { + "@readme/openapi-parser": "^3.0.1", "docs-utils": "*", "fdir": "^6.4.3", + "pluralize": "^8.0.0", "slugify": "^1.6.6", "tags": "*", "yaml": "^2.7.0" diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index e770ca25f1..8fffce672d 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -7,6 +7,7 @@ import numberSidebarItems from "./utils/number-sidebar-items.js" import { sortSidebarItems } from "./utils/sidebar-sorting.js" import { Sidebar } from "types" import { validateSidebarUniqueIds } from "./utils/validate-sidebar-unique-ids.js" +import getApiRefSidebarChildren from "./utils/get-api-ref-sidebar-children.js" export type ItemsToAdd = Sidebar.SidebarItem & { sidebar_position?: number @@ -17,8 +18,12 @@ export type GenerateSidebarOptions = { writeToFile?: boolean } -const customGenerators: Record Promise> = { +const customGenerators: Record< + string, + (sidebar?: Sidebar.RawSidebar) => Promise +> = { "core-flows": getCoreFlowsRefSidebarChildren, + "api-ref": getApiRefSidebarChildren, } function sortItems(itemA: ItemsToAdd, itemB: ItemsToAdd): number { @@ -241,9 +246,14 @@ export async function generateSidebar( validateSidebarUniqueIds(sidebars) for (const sidebarItem of sidebars) { + const hasCustomAutogenerator = + sidebarItem.custom_autogenerate && + Object.hasOwn(customGenerators, sidebarItem.custom_autogenerate) normalizedSidebars.push({ ...sidebarItem, - items: await checkItems(sidebarItem.items, restOptions), + items: !hasCustomAutogenerator + ? await checkItems(sidebarItem.items, restOptions) + : await customGenerators[sidebarItem.custom_autogenerate!](sidebarItem), }) } diff --git a/www/packages/build-scripts/src/utils/get-api-ref-sidebar-children.ts b/www/packages/build-scripts/src/utils/get-api-ref-sidebar-children.ts new file mode 100644 index 0000000000..3422354e15 --- /dev/null +++ b/www/packages/build-scripts/src/utils/get-api-ref-sidebar-children.ts @@ -0,0 +1,85 @@ +import { OpenAPI, Sidebar } from "types" +import { ItemsToAdd } from "../index.js" +import path from "path" +import { findAllPageHeadings, getSectionId } from "docs-utils" +import { readFile } from "fs/promises" +import { parse } from "@readme/openapi-parser" +import pkg from "pluralize" + +const { singular } = pkg + +export default async function getApiRefSidebarChildren( + sidebar?: Sidebar.RawSidebar +): Promise { + if (!sidebar) { + return [] + } + + const projPath = path.resolve() + const area = sidebar.sidebar_id + const items: ItemsToAdd[] = [ + { + type: "link", + title: "Introduction", + path: "introduction", + loaded: true, + }, + ] + + // get sidebar items from markdown files + const markdownPath = path.join(projPath, "markdown", `${area}.mdx`) + const headings = findAllPageHeadings({ + content: await readFile(markdownPath, "utf-8"), + level: 2, + }) + + headings.forEach((heading) => { + items.push({ + type: "link", + title: heading, + path: getSectionId([heading]), + loaded: true, + }) + }) + + // read base specs + const baseSpecs = (await parse( + path.join(projPath, "specs", area, "openapi.yaml") + )) as OpenAPI.ExpandedDocument + + if (baseSpecs.tags?.length) { + items.push({ + type: "separator", + }) + } + + // add tags to sidebar + baseSpecs.tags?.forEach((tag: OpenAPI.TagObject) => { + const item: ItemsToAdd = { + type: "category", + title: tag.name, + children: [], + loaded: false, + showLoadingIfEmpty: true, + } + + if (tag["x-associatedSchema"]) { + const formattedName = singular(tag.name).replaceAll(" ", "") + const schemaSlug = getSectionId([tag.name, formattedName, "schema"]) + item.children!.push({ + type: "link", + path: schemaSlug, + title: `${formattedName} Object`, + loaded: true, + badge: { + variant: "neutral", + text: "Schema", + }, + }) + } + + items.push(item) + }) + + return items +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx index 3575d57013..d4192796a1 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useMemo, useState } from "react" import { Sidebar } from "types" -import { Loading, SidebarItem, useSidebar } from "../../../.." +import { Badge, Loading, SidebarItem, useSidebar } from "../../../.." import clsx from "clsx" import { MinusMini, PlusMini } from "@medusajs/icons" @@ -106,6 +106,9 @@ export const SidebarItemCategory = ({ {item.title} {item.additionalElms} + {item.badge && ( + {item.badge.text} + )} {!item.additionalElms && ( <> {open && } @@ -123,13 +126,6 @@ export const SidebarItemCategory = ({ !open && "overflow-hidden m-0 h-0" )} > - {showLoading && ( - - )} {item.children?.map((childItem, index) => ( ))} + {showLoading && ( + + )} )} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx index e0c688e090..069207f274 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx @@ -5,6 +5,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react" import { Sidebar } from "types" import { + Badge, checkSidebarItemVisibility, SidebarItem, useMobile, @@ -147,6 +148,9 @@ export const SidebarItemLink = ({ {item.title} {item.additionalElms} + {item.badge && ( + {item.badge.text} + )} {hasChildren && ( diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/Sidebar/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/Sidebar/index.tsx index 60ced0c3ff..130c625af6 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/Sidebar/index.tsx @@ -4,7 +4,7 @@ import React, { useMemo } from "react" import { Sidebar } from "types" -import { useSidebar } from "../../../.." +import { Badge, useSidebar } from "../../../.." import clsx from "clsx" import Link from "next/link" @@ -56,6 +56,9 @@ export const SidebarItemSidebar = ({ {item.title} {item.additionalElms} + {item.badge && ( + {item.badge.text} + )} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx index 31e22cedf5..a6b7ba76a0 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx @@ -4,7 +4,7 @@ import React, { useMemo, useRef } from "react" import { Sidebar } from "types" -import { SidebarItem } from "../../../.." +import { Badge, SidebarItem } from "../../../.." import clsx from "clsx" export type SidebarItemSubCategoryProps = { @@ -53,6 +53,9 @@ export const SidebarItemSubCategory = ({ {item.title} {item.additionalElms} + {item.badge && ( + {item.badge.text} + )} {hasChildren && ( diff --git a/www/packages/docs-ui/src/providers/Sidebar/index.tsx b/www/packages/docs-ui/src/providers/Sidebar/index.tsx index cd6875734b..efac6cbf2f 100644 --- a/www/packages/docs-ui/src/providers/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/providers/Sidebar/index.tsx @@ -21,6 +21,7 @@ import { useSiteConfig } from "../SiteConifg" import { useIsBrowser } from "../BrowserProvider" import { getScrolledTop } from "../../utils" import { usePathname, useRouter } from "next/navigation" +import { SidebarItemCategory, SidebarItemSidebar } from "types/dist/sidebar" export type SidebarActionOptions = { sidebar_id: string @@ -53,6 +54,24 @@ export type SidebarStyleOptions = { disableActiveTransition?: boolean } +export type UpdateSidebarItemTypes = + | Partial> + | Partial< + Pick + > + | Partial> + +export type UpdateActionType = { + sidebar_id: string + items: { + existingItem: Sidebar.SidebarItem + newItem: UpdateSidebarItemTypes + options?: { + setChildrenBehavior: "replace" | "merge" + } + }[] +} + export type SidebarContextType = { sidebars: Sidebar.Sidebar[] /** @@ -75,6 +94,7 @@ export type SidebarContextType = { items: Sidebar.SidebarItem[], options?: SidebarActionOptions ) => void + updateItems: (options: UpdateActionType) => void removeItems: (options: { items: Sidebar.SidebarItem[] sidebar_id: string @@ -125,7 +145,7 @@ export const SidebarContext = createContext(null) export type ActionType = | { - type: "add" | "update" + type: "add" | "update-child" items: Sidebar.SidebarItem[] options?: SidebarActionOptions } @@ -138,32 +158,73 @@ export type ActionType = items: Sidebar.SidebarItem[] sidebar_id: string } + | ({ + type: "update" + } & UpdateActionType) export const reducer = ( state: Sidebar.Sidebar[], actionData: ActionType ): Sidebar.Sidebar[] => { - if (actionData.type === "replace") { - return actionData.sidebars - } - if (actionData.type === "remove") { - const { sidebar_id, items: itemsToRemove } = actionData - return state.map((sidebar) => { - if (sidebar.sidebar_id === sidebar_id) { - return { - ...sidebar, - items: sidebar.items.filter((item) => { - return !itemsToRemove.some((itemToRemove) => - areSidebarItemsEqual({ - itemA: item, - itemB: itemToRemove, - }) - ) - }), + switch (actionData.type) { + case "replace": + return actionData.sidebars + case "remove": { + const { sidebar_id, items: itemsToRemove } = actionData + return state.map((sidebar) => { + if (sidebar.sidebar_id === sidebar_id) { + return { + ...sidebar, + items: sidebar.items.filter((item) => { + return !itemsToRemove.some((itemToRemove) => + areSidebarItemsEqual({ + itemA: item, + itemB: itemToRemove, + }) + ) + }), + } } - } - return sidebar - }) + return sidebar + }) + } + case "update": + return state.map((sidebar) => { + if (sidebar.sidebar_id === actionData.sidebar_id) { + return { + ...sidebar, + items: sidebar.items.map((item) => { + const itemToUpdate = actionData.items.find((i) => + areSidebarItemsEqual({ + itemA: item, + itemB: i.existingItem, + }) + ) + if (itemToUpdate) { + const updatedItem = { + ...item, + ...itemToUpdate.newItem, + } as Sidebar.SidebarItem + + if ("children" in updatedItem) { + updatedItem.children = + itemToUpdate.options?.setChildrenBehavior === "merge" + ? [ + ...((item as Sidebar.InteractiveSidebarItem) + .children || []), + ...(updatedItem.children || []), + ] + : updatedItem.children + } + + return updatedItem + } + return item + }), + } + } + return sidebar + }) } const { type, options } = actionData @@ -207,7 +268,7 @@ export const reducer = ( }, ...state.slice(sidebarIndex + 1), ] - case "update": + case "update-child": // find item index return [ ...state.slice(0, sidebarIndex), @@ -406,12 +467,20 @@ export const SidebarProvider = ({ options?: SidebarActionOptions ) => { dispatch({ - type: options?.parent ? "update" : "add", + type: options?.parent ? "update-child" : "add", items: newItems, options, }) } + const updateItems = ({ sidebar_id, items }: UpdateActionType) => { + dispatch({ + type: "update", + items, + sidebar_id, + }) + } + const removeItems = ({ items, sidebar_id, @@ -452,30 +521,32 @@ export const SidebarProvider = ({ } }, [shouldHandleHashChange]) + const handleScroll = useCallback(() => { + const scrolledTop = getScrolledTop(resolvedScrollableElement) + // account for navbar height + if (scrolledTop >= 0 && scrolledTop <= 56) { + const firstChild = getFirstLinkChild(activeMainSidebar.items) + + if (firstChild) { + setActivePath(firstChild.path) + router.push(`#${firstChild.path}`, { + scroll: false, + }) + } + } + }, [activeMainSidebar, resolvedScrollableElement]) + useEffect(() => { if (!shouldHandleHashChange || !resolvedScrollableElement) { return } - const handleScroll = () => { - if (getScrolledTop(resolvedScrollableElement) === 0) { - const firstChild = getFirstLinkChild(activeMainSidebar.items) - - if (firstChild) { - setActivePath(firstChild.path) - router.push(`#${firstChild.path}`, { - scroll: false, - }) - } - } - } - resolvedScrollableElement.addEventListener("scroll", handleScroll) return () => { resolvedScrollableElement.removeEventListener("scroll", handleScroll) } - }, [shouldHandleHashChange, resolvedScrollableElement]) + }, [shouldHandleHashChange, resolvedScrollableElement, handleScroll]) useEffect(() => { if (!shouldHandleHashChange || !isBrowser) { @@ -635,6 +706,7 @@ export const SidebarProvider = ({ setActivePath, isItemActive, addItems, + updateItems, removeItems, mobileSidebarOpen, setMobileSidebarOpen, diff --git a/www/packages/docs-utils/package.json b/www/packages/docs-utils/package.json index 2784a99221..4a843203e5 100644 --- a/www/packages/docs-utils/package.json +++ b/www/packages/docs-utils/package.json @@ -34,6 +34,7 @@ "remark-mdx": "^3.1.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", + "slugify": "^1.6.6", "to-vfile": "^8.0.0", "unified": "^11.0.4", "vfile-matter": "^5.0.0" diff --git a/www/packages/docs-utils/src/find-title.ts b/www/packages/docs-utils/src/find-title.ts index 7dc849e327..02d10f6d63 100644 --- a/www/packages/docs-utils/src/find-title.ts +++ b/www/packages/docs-utils/src/find-title.ts @@ -8,14 +8,27 @@ export function findMetadataTitle(content: string): string | undefined { return headingMatch?.groups?.title } -const HEADING_REGEX = /# (?.*)/ - export function findPageHeading(content: string): string | undefined { - const headingMatch = HEADING_REGEX.exec(content) + const headingMatch = /# (?<title>.*)/.exec(content) return headingMatch?.groups?.title } +export function findAllPageHeadings({ + content, + level = 1, +}: { + content: string + level?: number +}): string[] { + const regex = new RegExp( + `^${"#".repeat(level)}(?!#) (?<title>.*?)(?:\n|$)`, + "gm" + ) + const matches = [...content.matchAll(regex)] + return matches.map((match) => match.groups?.title).filter(Boolean) as string[] +} + export function findPageTitle(filePath: string): string | undefined { const content = readFileSync(filePath, "utf-8") diff --git a/www/packages/docs-utils/src/get-clean-md.ts b/www/packages/docs-utils/src/get-clean-md.ts index b7e971b9e9..8175c6fbe4 100644 --- a/www/packages/docs-utils/src/get-clean-md.ts +++ b/www/packages/docs-utils/src/get-clean-md.ts @@ -1,7 +1,6 @@ import remarkMdx from "remark-mdx" import remarkParse from "remark-parse" import remarkStringify from "remark-stringify" -import { read } from "to-vfile" import { FrontMatter, UnistNode, UnistNodeWithData, UnistTree } from "types" import { Plugin, Transformer, unified } from "unified" import { SKIP } from "unist-util-visit" @@ -172,6 +171,7 @@ export const getCleanMd = async ({ parserOptions, type = "file", }: GetCleanMdOptions): Promise<string> => { + const { read } = await import("to-vfile") if (type === "file" && !file.endsWith(".md") && !file.endsWith(".mdx")) { return "" } diff --git a/www/packages/docs-utils/src/index.ts b/www/packages/docs-utils/src/index.ts index b5e180537e..891f3fe8a5 100644 --- a/www/packages/docs-utils/src/index.ts +++ b/www/packages/docs-utils/src/index.ts @@ -6,3 +6,4 @@ export * from "./get-file-slug-sync.js" export * from "./get-file-slug.js" export * from "./get-front-matter.js" export * from "./oas-file-to-path.js" +export * from "./sidebar-utils.js" diff --git a/www/packages/docs-utils/src/sidebar-utils.ts b/www/packages/docs-utils/src/sidebar-utils.ts new file mode 100644 index 0000000000..ef0ba11898 --- /dev/null +++ b/www/packages/docs-utils/src/sidebar-utils.ts @@ -0,0 +1,7 @@ +import pkg from "slugify" +const { default: slugify } = pkg + +export function getSectionId(path: string[]) { + path = path.map((p) => slugify(p.trim().toLowerCase())) + return path.join("_") +} diff --git a/www/packages/types/package.json b/www/packages/types/package.json index b3ddd422c2..356e6b1d06 100644 --- a/www/packages/types/package.json +++ b/www/packages/types/package.json @@ -40,5 +40,8 @@ }, "engines": { "node": ">=18.17.0" + }, + "dependencies": { + "openapi-types": "^12.1.3" } } diff --git a/www/packages/types/src/index.ts b/www/packages/types/src/index.ts index 0e8dc05ae9..785c5ba930 100644 --- a/www/packages/types/src/index.ts +++ b/www/packages/types/src/index.ts @@ -5,6 +5,7 @@ export * from "./frontmatter.js" export * from "./general.js" export * from "./menu.js" export * from "./navigation.js" +export * as OpenAPI from "./openapi.js" export * from "./remark-rehype.js" export * from "./navigation-dropdown.js" export * as Sidebar from "./sidebar.js" diff --git a/www/apps/api-reference/types/openapi.ts b/www/packages/types/src/openapi.ts similarity index 99% rename from www/apps/api-reference/types/openapi.ts rename to www/packages/types/src/openapi.ts index da0933ae00..21ff1079d3 100644 --- a/www/apps/api-reference/types/openapi.ts +++ b/www/packages/types/src/openapi.ts @@ -1,5 +1,7 @@ import type { OpenAPIV3 } from "openapi-types" +export type { OpenAPIV3 } + export type Area = "admin" | "store" export type Code = { diff --git a/www/packages/types/src/sidebar.ts b/www/packages/types/src/sidebar.ts index 948354be35..39caef54ab 100644 --- a/www/packages/types/src/sidebar.ts +++ b/www/packages/types/src/sidebar.ts @@ -9,6 +9,10 @@ export type SidebarItemCommon = { children?: SidebarItem[] loaded?: boolean additionalElms?: React.ReactNode + badge?: { + variant: "purple" | "orange" | "green" | "blue" | "red" | "neutral" + text: string + } chapterTitle?: string childSidebarTitle?: string hideChildren?: boolean @@ -88,6 +92,7 @@ export type RawSidebarItem = SidebarItem & { export type RawSidebar = Omit<Sidebar, "items"> & { items: RawSidebarItem[] + custom_autogenerate?: string } export type PersistedSidebarCategoryState = { diff --git a/www/yarn.lock b/www/yarn.lock index 2513b62813..011b64575b 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -267,6 +267,17 @@ __metadata: languageName: node linkType: hard +"@apidevtools/json-schema-ref-parser@npm:^11.9.2": + version: 11.9.3 + resolution: "@apidevtools/json-schema-ref-parser@npm:11.9.3" + dependencies: + "@jsdevtools/ono": ^7.1.3 + "@types/json-schema": ^7.0.15 + js-yaml: ^4.1.0 + checksum: 5745813b3d964279f387677b7a903ba6634cdeaf879ff3a331a694392cbc923763f398506df190be114f2574b8b570baab3e367c2194bb35f50147ff6cf27d7a + languageName: node + linkType: hard + "@apidevtools/openapi-schemas@npm:^2.1.0": version: 2.1.0 resolution: "@apidevtools/openapi-schemas@npm:2.1.0" @@ -291,6 +302,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.22.5": + version: 7.26.2 + resolution: "@babel/code-frame@npm:7.26.2" + dependencies: + "@babel/helper-validator-identifier": ^7.25.9 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: 7d79621a6849183c415486af99b1a20b84737e8c11cd55b6544f688c51ce1fd710e6d869c3dd21232023da272a79b91efb3e83b5bc2dc65c1187c5fcd1b72ea8 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" @@ -442,6 +464,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-validator-identifier@npm:7.25.9" + checksum: 4fc6f830177b7b7e887ad3277ddb3b91d81e6c4a24151540d9d1023e8dc6b1c0505f0f0628ae653601eb4388a8db45c1c14b2c07a9173837aef7e4116456259d + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helper-validator-option@npm:7.23.5" @@ -489,6 +518,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.22.5": + version: 7.26.10 + resolution: "@babel/runtime@npm:7.26.10" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: 6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745 + languageName: node + linkType: hard + "@babel/template@npm:^7.22.15, @babel/template@npm:^7.23.9": version: 7.23.9 resolution: "@babel/template@npm:7.23.9" @@ -4941,6 +4979,22 @@ __metadata: languageName: node linkType: hard +"@readme/better-ajv-errors@npm:^2.3.2": + version: 2.3.2 + resolution: "@readme/better-ajv-errors@npm:2.3.2" + dependencies: + "@babel/code-frame": ^7.22.5 + "@babel/runtime": ^7.22.5 + "@humanwhocodes/momoa": ^2.0.3 + jsonpointer: ^5.0.0 + leven: ^3.1.0 + picocolors: ^1.1.1 + peerDependencies: + ajv: 4.11.8 - 8 + checksum: 0c16c686a5663e557321cb04f1ff26699b7f69cb38e47f8f7e78310178131d2423328201b74816f63a427dc814ba74d711f879e1b63581c8a82f9bbaacdad5f1 + languageName: node + linkType: hard + "@readme/json-schema-ref-parser@npm:^1.2.0": version: 1.2.1 resolution: "@readme/json-schema-ref-parser@npm:1.2.1" @@ -4971,6 +5025,29 @@ __metadata: languageName: node linkType: hard +"@readme/openapi-parser@npm:^3.0.1": + version: 3.0.1 + resolution: "@readme/openapi-parser@npm:3.0.1" + dependencies: + "@apidevtools/json-schema-ref-parser": ^11.9.2 + "@readme/better-ajv-errors": ^2.3.2 + "@readme/openapi-schemas": ^3.1.0 + "@types/json-schema": ^7.0.15 + ajv: ^8.12.0 + ajv-draft-04: ^1.0.0 + peerDependencies: + openapi-types: ">=7" + checksum: 447360bfc1f49b217569f76d084f508d6353463a80069ccf877115da7cd5d1ffcaba637bc1353154239c6bdf18cd5a3efb374d13495eb3254b6bc5afec20da74 + languageName: node + linkType: hard + +"@readme/openapi-schemas@npm:^3.1.0": + version: 3.1.0 + resolution: "@readme/openapi-schemas@npm:3.1.0" + checksum: 88d28d181b463b296c98bc288f2fc8975c302ec488edd1018ce8843c3eedbf3bb423ced934c6fd09bce4a0203fe9ea050bf2b3fa39a1bf665e41f87224dd71c5 + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -5907,7 +5984,6 @@ __metadata: next: 15.0.4 next-mdx-remote: 5.0.0 openapi-sampler: ^1.3.1 - openapi-types: ^12.1.3 pluralize: ^8.0.0 postcss: 8.4.27 prism-react-renderer: 2.4.0 @@ -6306,9 +6382,11 @@ __metadata: version: 0.0.0-use.local resolution: "build-scripts@workspace:packages/build-scripts" dependencies: + "@readme/openapi-parser": ^3.0.1 "@types/node": ^20.11.20 docs-utils: "*" fdir: ^6.4.3 + pluralize: ^8.0.0 rimraf: ^5.0.5 slugify: ^1.6.6 tags: "*" @@ -7573,6 +7651,7 @@ __metadata: remark-parse: ^11.0.0 remark-stringify: ^11.0.0 rimraf: ^5.0.5 + slugify: ^1.6.6 to-vfile: ^8.0.0 tsconfig: "*" types: "*" @@ -12818,6 +12897,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -15387,6 +15473,7 @@ turbo@latest: dependencies: "@medusajs/icons": 2.6.0 "@types/node": ^20.11.20 + openapi-types: ^12.1.3 rimraf: ^5.0.5 tsconfig: "*" typescript: ^5.3.3