diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml deleted file mode 100644 index 94f745ea..00000000 --- a/.github/workflows/check-links.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Check Links - -on: - # Run monday mornings - schedule: - - cron: '0 10 * * MON' - workflow_dispatch: -jobs: - check-links: - name: Check links - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - site: - - name: Fern Docs - url: "buildwithfern.com/learn" - steps: - - name: Install link checker - run: pip install linkchecker - - name: Create config - run: echo -e "[csv]\nseparator=,\n[filtering]\nignore=\n\texample.com\n\tus.i.posthog.com\n\tdocs.stack-auth.com\n\t/_vercel/(speed-)?insights/\n\tc.vialoops.com/CL0\n[output]\nignoreerrors=\n ^http ^403 Forbidden" > lcconfig - - name: Check ${{ matrix.site.name }} Links - run: | - set +e - cat lcconfig - linkchecker https://${{ matrix.site.url }} --check-extern --no-status --no-warnings --threads 25 --config lcconfig -F csv/utf-8/link_report.csv - - if [ $? -ne 0 ]; then - echo "Bad links found. Please see report." - else - echo "Check completed. No issues found." - exit 0 - fi - - echo "Scan done, generating summary" - - started=false - shouldfail=false - while read p; do - # skip comments (top and bottom) - if [[ $p == \#* ]]; then - continue - fi - # make sure first line after comments is skipped - if [[ "$started" = false ]]; then - started=true - continue - fi - - IFS=',' read -r -a array <<< "$p" - - ret=$(curl -I -s "${array[0]}" -o /dev/null -w "%{http_code}\n") - if [[ $ret == 200 ]]; then - echo "Site now seems to be working, we should continue here" - continue - else - echo "There is still an issue with ${array[0]}" - fi - - shouldfail=true - - if [[ ${array[10]} == '' ]]; then - echo "::error::URL: ${array[0]} on page: ${array[1]} is returning a ${array[3]}" - else - echo "::error::URL: ${array[0]} linked from '${array[10]}' on page: ${array[1]} is returning a ${array[3]}" - fi - - done < link_report.csv - - if [[ "$shouldfail" = false ]]; then - exit 0 - fi - - exit 1 - - - name: Upload report - if: failure() - uses: actions/upload-artifact@v4 - with: - name: Report - ${{ matrix.site.name }} - path: link_report.csv \ No newline at end of file diff --git a/.github/workflows/update-versions.yml b/.github/workflows/update-versions.yml index f56f6f1c..b981a5c7 100644 --- a/.github/workflows/update-versions.yml +++ b/.github/workflows/update-versions.yml @@ -26,8 +26,6 @@ jobs: run: curl -s "https://registry.hub.docker.com/v2/repositories/fernapi/fern-ruby-sdk/tags" | jq -r -j '[.results[] | select(.name != "latest")] | .[0].name' > fern/snippets/version-number-ruby.mdx - name: update-ts-version run: curl -s "https://registry.hub.docker.com/v2/repositories/fernapi/fern-typescript-sdk/tags" | jq -r -j '[.results[] | select(.name != "latest")] | .[0].name' > fern/snippets/version-number-ts.mdx - - name: update-swift-version - run: curl -s "https://registry.hub.docker.com/v2/repositories/fernapi/fern-swift-sdk/tags" | jq -r -j '[.results[] | select(.name != "latest")] | .[0].name' > fern/snippets/version-number-swift.mdx - name: create PR id: cpr uses: peter-evans/create-pull-request@v7 diff --git a/README.md b/README.md index 1ec1bc66..97b8c246 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,6 @@ Keep the following principles in mind: - **Use [Fern’s documentation components](https://buildwithfern.com/learn/docs/writing-content/components/overview)** whenever you can. - **When editing an existing page** - Match the existing heading structure, tone, and level of detail to ensure your changes integrate as seamlessly as possible. - **Use diagrams when it makes sense** – Show, don't tell! Use [Mermaid](https://buildwithfern.com/learn/docs/writing-content/markdown#diagrams), a Markdown-like diagramming syntax, to illustrate a workflow. -- [**Use sentence case**](https://developers.google.com/style/capitalization) for page and section headings. > "Break any of these rules sooner than say anything outright barbarous." > diff --git a/fern/apis/fai/definition/analytics.yml b/fern/apis/fai/definition/analytics.yml new file mode 100644 index 00000000..f5421400 --- /dev/null +++ b/fern/apis/fai/definition/analytics.yml @@ -0,0 +1,82 @@ +docs: FAI Analytics API + +imports: + commons: ./commons.yml + +service: + auth: false + base-path: /analytics + endpoints: + getHistogramAnalytics: + docs: Retrieve the usage histogram analytics for a given period + path: /histogram/{domain} + method: GET + audiences: + - internal + path-parameters: + domain: string + request: + name: GetHistogramAnalyticsRequest + query-parameters: + start_date: + type: optional + docs: The start date of the period to retrieve analytics for + end_date: + type: optional + docs: The end date of the period to retrieve analytics for + groupBy: + type: GroupBy + docs: The field to group the analytics by + response: HistogramAnalytics + errors: + - commons.BadRequestError + - commons.InternalError + getInsights: + docs: Retrieve the insights for a given period + path: /insights/{domain} + method: GET + audiences: + - internal + path-parameters: + domain: string + request: + name: GetInsightsRequest + query-parameters: + start_date: + type: optional + docs: The start date of the period to retrieve analytics for + end_date: + type: optional + docs: The end date of the period to retrieve analytics for + response: Insights + errors: + - commons.BadRequestError + - commons.InternalError + +types: + GroupBy: + enum: + - "DAY" + - "WEEK" + - "MONTH" + + HistogramAnalytics: + properties: + bars: list + + HistogramAnalyticsBar: + properties: + label: string + queryCount: integer + conversationCount: integer + + Insights: + properties: + insights: list + + Insight: + properties: + insightText: string + numberOfQueries: integer + examples: list + \ No newline at end of file diff --git a/fern/apis/fai/definition/api.yml b/fern/apis/fai/definition/api.yml new file mode 100644 index 00000000..e5b7ac2c --- /dev/null +++ b/fern/apis/fai/definition/api.yml @@ -0,0 +1,8 @@ +name: fai +auth: bearer +default-environment: Prod +environments: + Prod: https://fai.buildwithfern.com +error-discrimination: + strategy: property + property-name: error \ No newline at end of file diff --git a/fern/apis/fai/definition/chat.yml b/fern/apis/fai/definition/chat.yml new file mode 100644 index 00000000..34be3491 --- /dev/null +++ b/fern/apis/fai/definition/chat.yml @@ -0,0 +1,37 @@ +docs: FAI Chat API + +imports: + commons: ./commons.yml + +service: + auth: false + base-path: /chat + endpoints: + chatCompletion: + docs: Create a docs chat completion for a given domain + path: /{domain} + method: POST + audiences: + - customers + path-parameters: + domain: string + request: + name: ChatCompletionRequest + body: + properties: + model: optional + system_prompt: optional + messages: list + response: ChatCompletionResponse + errors: + - commons.BadRequestError + - commons.InternalError + +types: + ChatCompletionResponse: + type: list + + ChatTurn: + properties: + role: string + content: string diff --git a/fern/apis/fai/definition/commons.yml b/fern/apis/fai/definition/commons.yml new file mode 100644 index 00000000..62d895dc --- /dev/null +++ b/fern/apis/fai/definition/commons.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json +errors: + BadRequestError: + status-code: 400 + type: string + + InternalError: + status-code: 401 + type: string diff --git a/fern/apis/fai/definition/conversations.yml b/fern/apis/fai/definition/conversations.yml new file mode 100644 index 00000000..96e98bdf --- /dev/null +++ b/fern/apis/fai/definition/conversations.yml @@ -0,0 +1,44 @@ +docs: FAI Conversations API + +imports: + commons: ./commons.yml + +service: + auth: false + base-path: /conversations + endpoints: + getConversation: + docs: Retrieve a complete conversation by conversation id + path: /{domain}/{conversation_id} + method: GET + audiences: + - customers + path-parameters: + domain: string + conversation_id: string + response: Conversation + errors: + - commons.BadRequestError + - commons.InternalError + +types: + Conversation: + properties: + conversation_id: string + created_at: datetime + turns: list + + Conversations: + type: list + + ConversationSource: + default: CHAT + enum: + - CHAT + - MCP + + ConversationTurn: + properties: + role: string + text: string + created_at: datetime \ No newline at end of file diff --git a/fern/apis/fai/definition/index.yml b/fern/apis/fai/definition/index.yml new file mode 100644 index 00000000..748f47f2 --- /dev/null +++ b/fern/apis/fai/definition/index.yml @@ -0,0 +1,111 @@ +docs: FAI Index API + +imports: + commons: ./commons.yml + +service: + auth: false + base-path: /index + endpoints: + indexDocument: + docs: Index a document for a given domain + path: /{domain} + method: POST + audiences: + - customers + path-parameters: + domain: string + request: + name: IndexRequest + body: + properties: + index_name: + type: optional + default: custom + docs: The name of the index to which the document will be added + document_id: + type: string + docs: A unique identifier for the document + context: + type: list + docs: The context of the document, as a list of strings, that will be indexed. + document: + type: string + docs: The content of the document that will be returned in the tool response + errors: + - commons.BadRequestError + - commons.InternalError + + getDocument: + docs: Get a document for a given domain + path: /{domain} + method: GET + path-parameters: + domain: string + request: + name: GetRequest + query-parameters: + document_id: + type: string + docs: The unique identifier of the document to get + errors: + - commons.BadRequestError + - commons.InternalError + + updateDocument: + docs: Update a document for a given domain + path: /{domain}/update + method: POST + audiences: + - customers + path-parameters: + domain: string + request: + name: UpdateRequest + query-parameters: + document_id: + type: string + docs: The unique identifier of the document to update + is_active: + type: boolean + docs: Whether the document is active + context: + type: list + docs: The context of the document, as a list of strings, that will be indexed. + document: + type: string + docs: The content of the document that will be returned in the tool response. If not provided, the document will be removed from the index. + response: ContextResponse + errors: + - commons.BadRequestError + - commons.InternalError + + syncToQueryIndex: + docs: Sync an index with the query index + path: /{domain}/sync + method: POST + audiences: + - internal + path-parameters: + domain: string + request: + name: SyncIndexRequest + query-parameters: + index_name: + type: string + docs: The name of the index to sync + errors: + - commons.BadRequestError + - commons.InternalError + +types: + ContextResponse: + properties: + document_id: string + domain: string + context_id: string + context: list + document: string + is_active: boolean + created_at: datetime + updated_at: datetime \ No newline at end of file diff --git a/fern/apis/fai/definition/queries.yml b/fern/apis/fai/definition/queries.yml new file mode 100644 index 00000000..da8bd7da --- /dev/null +++ b/fern/apis/fai/definition/queries.yml @@ -0,0 +1,78 @@ +docs: FAI Queries API + +imports: + commons: ./commons.yml + conversations: ./conversations.yml + +service: + auth: false + base-path: / + endpoints: + createQuery: + docs: Log a new query to the FAI DB + path: /queries + method: POST + audiences: + - internal + request: + name: CreateQueryRequest + body: + properties: + query_id: string + conversation_id: string + domain: string + text: string + role: string + source: string + created_at: datetime + time_to_first_token: + type: optional + docs: Time in seconds until first token was received. Only specified for Assistant responses. + errors: + - commons.BadRequestError + - commons.InternalError + + getRecentQueries: + docs: Retrieve all paginated recent queries + path: /queries/{domain} + method: GET + audiences: + - internal + path-parameters: + domain: + type: string + docs: The domain to retrieve queries for + request: + name: GetRecentQueriesRequest + query-parameters: + page: optional + limit: optional + cutoff_time: optional + include_assistant: optional + start_date: + type: optional + docs: The start date of the period to retrieve analytics for + end_date: + type: optional + docs: The end date of the period to retrieve analytics for + response: QueryPage + errors: + - commons.BadRequestError + - commons.InternalError + +types: + Query: + properties: + query_id: string + conversation_id: string + domain: string + text: string + role: string + source: string + created_at: datetime + time_to_first_token: optional + + QueryPage: + properties: + queries: list + total: integer \ No newline at end of file diff --git a/fern/apis/fai/generators.yml b/fern/apis/fai/generators.yml index f1c05946..016ecd93 100644 --- a/fern/apis/fai/generators.yml +++ b/fern/apis/fai/generators.yml @@ -1,6 +1,9 @@ +<<<<<<< HEAD +======= api: specs: - openapi: ./openapi.json +>>>>>>> origin/main default-group: local groups: diff --git a/fern/assets/styles.css b/fern/assets/styles.css index 84d687d3..4b8b25ba 100644 --- a/fern/assets/styles.css +++ b/fern/assets/styles.css @@ -372,46 +372,6 @@ a[href*="changelog"] svg { .sdks-homepage { position: relative; - .changelog-button { - display: flex; - padding: 0.25rem 0.5rem; - align-items: center; - justify-content: center; - border-radius: 0.5rem; - transition: background-color 0.15s ease-in-out; - position: relative; - height: 2rem; - text-decoration: none !important; - - img { - flex-shrink: 0; - width: 16px; - height: 16px; - position: relative; - } - - div { - font-size: 1rem; - white-space: nowrap; - max-width: 0; - opacity: 0; - overflow: hidden; - transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); - width: 0; - } - - &:hover { - gap: 0.25rem; - background-color: var(--grayscale-a3); - - div { - max-width: 200px; - opacity: 1; - width: fit-content; - } - } - } - .dashed-pattern-left { position: absolute; left: -4rem; @@ -557,6 +517,11 @@ a[href*="changelog"] svg { min-height: 100vh; position: relative; + /* Hide all anchor links on the homepage */ + [data-radix-popper-content-wrapper]:has(span[id^="radix-"]) { + display: none !important; + } + .dashed-pattern-left { position: absolute; left: -1rem; @@ -648,7 +613,7 @@ a[href*="changelog"] svg { .card-header { display: flex; flex-direction: column; - gap: 0.25rem; + /* gap: 0.25rem; */ } .card-title { @@ -676,7 +641,7 @@ a[href*="changelog"] svg { } .card-description { - font-size: 1rem; + font-size: 0.875rem; color: var(--grayscale-10); } @@ -770,6 +735,14 @@ a[href*="changelog"] svg { align-items: flex-start; } + .community-card-header { + display: flex; + align-items: center; + gap: 0.5rem; + flex-direction: column; + align-items: flex-start; + } + .community-card-title { font-size: 1rem; font-weight: bold; @@ -831,15 +804,17 @@ a[href*="changelog"] svg { /* Responsive Design - Mobile First */ @media (max-width: 640px) { .main-content { - padding: 2rem 1rem; + padding: 2rem 0rem; } .dashed-pattern-left { left: 0px; + display: none; } .dashed-pattern-right { right: 0px; + display: none; } .hero-section { @@ -857,27 +832,27 @@ a[href*="changelog"] svg { } .sdks-card { - padding: 1rem; + padding: 2rem 1rem; } .docs-card { - padding: 1rem; + padding: 2rem 1rem; border-left: none; grid-column: 1; grid-row: auto; } .ai-search-card { - padding: 1rem; + padding: 2rem 1rem; } .card-title { font-size: 1.375rem; } - .card-description { + /* .card-description { font-size: 1.0625rem; - } + } */ .language-icons { flex-wrap: wrap; @@ -917,7 +892,7 @@ a[href*="changelog"] svg { } .community-section { - padding: 2rem 1.5rem; + padding: 2rem 1rem; } .community-grid { @@ -928,15 +903,15 @@ a[href*="changelog"] svg { .community-card { border-radius: 0.5rem; transition: all 0.2s ease; + } - &:hover { - border-color: var(--grayscale-6); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - } + .community-card-header { + flex-direction: row; + align-items: center; } .help-section { - padding: 2rem 1.5rem; + padding: 2rem 1rem; } .help-buttons { @@ -996,12 +971,35 @@ a[href*="changelog"] svg { will-change: transform; /* Ensure click events can reach the canvas */ pointer-events: auto; + min-height: 104px; } .sdk-rive:hover { transform: translateY(-3px) !important; } +.docs-rive { + min-height: 213px; +} + +.ask-fern-rive { + min-height: 114px; +} + +@media (max-width: 640px) { + .sdk-rive { + min-height: inherit; + } + + .docs-rive { + min-height: inherit; + } + + .ask-fern-rive { + min-height: inherit; + } +} + /* Ensure the canvas can receive clicks and is properly layered */ .rive-container { width: 100%; diff --git a/fern/docs.yml b/fern/docs.yml index 0442b9c6..81c0430b 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -57,31 +57,31 @@ products: slug: api-definitions - display-name: OpenAPI - path: ./products/api-def/openapi-def.yml + path: ./products/api-def/api-def.yml icon: fa-regular fa-book image: ./images/product-switcher/openapi-definition-light.png slug: openapi-definition - display-name: AsyncAPI - path: ./products/api-def/asyncapi-def.yml + path: ./products/api-def/api-def.yml icon: fa-regular fa-bolt image: ./images/product-switcher/asyncapi-light.png slug: asyncapi-definition - display-name: OpenRPC - path: ./products/api-def/openrpc-def.yml + path: ./products/api-def/api-def.yml icon: fa-regular fa-code image: ./images/product-switcher/openrpc-light.png slug: openrpc-definition - display-name: gRPC - path: ./products/api-def/grpc-def.yml + path: ./products/api-def/api-def.yml icon: fa-regular fa-plug image: ./images/product-switcher/grpc-light.png slug: grpc-definition - display-name: Fern Definition - path: ./products/api-def/ferndef-def.yml + path: ./products/api-def/api-def.yml icon: fa-regular fa-seedling image: ./images/product-switcher/fern-definition-light.png slug: fern-definition @@ -240,9 +240,6 @@ redirects: - source: /learn/sdks/fern-folder destination: /learn/sdks/overview/quickstart permanent: true - - source: /learn/sdks/overview/github - destination: /learn/sdks/overview/project-structure - permanent: true - source: /learn/sdks/introduction/customer-showcase destination: /learn/sdks/customer-showcase permanent: true @@ -328,7 +325,7 @@ redirects: destination: https://buildwithfern.com/customers permanent: true - source: /learn/docs/getting-started/global-configuration - destination: /learn/docs/configuration/what-is-docs-yml + destination: /learn/docs/customization/what-is-docs-yml permanent: true - source: /learn/docs/getting-started/development destination: /learn/docs/preview-publish/previewing-changes-locally @@ -381,7 +378,7 @@ redirects: destination: /learn/docs/customization/custom-css-js permanent: true - source: /learn/docs/building-and-customizing-your-docs/custom-domain - destination: /learn/docs/preview-publish/setting-up-your-domain + destination: /learn/docs/getting-started/setting-up-your-domain permanent: true - source: /learn/docs/building-and-customizing-your-docs/rbac destination: /learn/docs/authentication/rbac @@ -414,9 +411,6 @@ redirects: - source: /learn/docs/content/visual-editor destination: /learn/docs/writing-content/visual-editor permanent: true - - source: /learn/docs/writing-content/code-blocks - destination: /learn/docs/writing-content/components/code-blocks - permanent: true - source: /learn/docs/getting-started/changelog/:slug* destination: /learn/docs/changelog/:slug* @@ -434,9 +428,6 @@ redirects: - source: /learn/user-feedback destination: /learn/docs/user-feedback permanent: true - - source: /learn/docs/customization/what-is-docs-yml - destination: /learn/docs/configuration/what-is-docs-yml - permanent: true # ============================================================================ # CLI & API REFERENCE REDIRECTS @@ -485,52 +476,43 @@ redirects: # API DEFINITION REDIRECTS # ============================================================================ - # # API Definition OpenAPI specific redirects first + # API Definition OpenAPI specific redirects first - source: /learn/api-definition/openapi/endpoints/:slug* - destination: /learn/api-definitions/openapi/endpoints/:slug* + destination: /learn/openapi-definition/endpoints/:slug* permanent: true - source: /learn/api-definition/openapi/extensions/:slug* - destination: /learn/api-definitions/openapi/extensions/:slug* + destination: /learn/openapi-definition/extensions/:slug* permanent: true - source: /learn/api-definition/openapi/frameworks/:slug* - destination: /learn/api-definitions/openapi/frameworks/:slug* + destination: /learn/openapi-definition/frameworks/:slug* permanent: true - source: /learn/api-definition/openapi/:slug* - destination: /learn/api-definitions/openapi/:slug* + destination: /learn/openapi-definition/:slug* permanent: true - source: /learn/openapi-definition/extensions/webhooks - destination: /learn/api-definitions/openapi/endpoints/webhooks - permanent: true - - source: /learn/api-definitions/openapi/overlay-customizations - destination: /learn/api-definitions/overview/overrides - permanent: true - - source: /learn/api-definitions/asyncapi/overlay-customizations - destination: /learn/api-definitions/overview/overrides - permanent: true - - source: /learn/api-definitions/openrpc/overlay-customizations - destination: /learn/api-definitions/overview/overrides - permanent: true - - source: /learn/api-definitions/grpc/overlay-customizations - destination: /learn/api-definitions/overview/overrides + destination: /learn/openapi-definition/endpoints/webhooks permanent: true # API Definition Fern specific redirects first - source: /learn/api-definition/fern/endpoints/:slug* - destination: /learn/api-definitions/ferndef/endpoints/:slug* + destination: /learn/fern-definition/endpoints/:slug* permanent: true - source: /learn/api-definition/fern/api-yml/:slug* - destination: /learn/api-definitions/ferndef/api-yml/:slug* + destination: /learn/fern-definition/api-yml/:slug* permanent: true - source: /learn/api-definition/fern/:slug* - destination: /learn/api-definitions/ferndef/:slug* + destination: /learn/fern-definition/:slug* permanent: true - # # API Definition Introduction redirects + # API Definition Introduction redirects - source: /learn/api-definition/introduction/what-is-an-api-definition - destination: /learn/api-definitions/overview/what-is-an-api-definition + destination: /learn/openapi-definition/overview permanent: true - source: /learn/api-definition/introduction/what-is-the-fern-folder - destination: /learn/api-definitions/overview/project-structure + destination: /learn/sdks/overview/quickstart + permanent: true + - source: /learn/api-definition/introduction/:slug* + destination: /learn/openapi-definition/overview permanent: true # ============================================================================ @@ -567,7 +549,7 @@ redirects: destination: https://buildwithfern.com/customers permanent: true - source: /learn/ask-fern/citations - destination: /learn/ask-fern/features/citations + destination: /learn/ask-fern/configuration/citations permanent: true - source: /learn/ask-fern/custom-prompting destination: /learn/ask-fern/configuration/custom-prompting @@ -591,21 +573,6 @@ redirects: # ============================================================================ # API REFERENCE REDIRECTS # ============================================================================ - - source: /learn/openapi-definition/empty-page - destination: /learn/api-definitions/openapi/overview - permanent: true - - source: /learn/asyncapi-definition/empty-page - destination: /learn/api-definitions/asyncapi/overview - permanent: true - - source: /learn/openrpc-definition/empty-page - destination: /learn/api-definitions/openrpc/overview - permanent: true - - source: /learn/grpc-definition/empty-page - destination: /learn/api-definitions/grpc/overview - permanent: true - - source: /learn/fern-definition/empty-page - destination: /learn/api-definitions/ferndef/overview - permanent: true - source: /learn/openapi-definition/:slug* destination: /learn/api-definitions/openapi/:slug* permanent: true @@ -620,18 +587,4 @@ redirects: permanent: true - source: /learn/fern-definition/:slug* destination: /learn/api-definitions/ferndef/:slug* - permanent: true - - # Redirect old others.mdx extension pages to overview pages - - source: /learn/api-definitions/openapi/extensions/others - destination: /learn/api-definitions/openapi/extensions/overview - permanent: true - - source: /learn/api-definitions/asyncapi/extensions/others - destination: /learn/api-definitions/asyncapi/extensions/overview - permanent: true - - source: /learn/api-definitions/openrpc/extensions/others - destination: /learn/api-definitions/openrpc/extensions/overview - permanent: true - - source: /learn/api-definitions/grpc/extensions/:slug* - destination: /learn/api-definitions/overview/overrides#definition-specific-extensions permanent: true \ No newline at end of file diff --git a/fern/fern.config.json b/fern/fern.config.json index 876c69ec..023935bd 100644 --- a/fern/fern.config.json +++ b/fern/fern.config.json @@ -1,4 +1,4 @@ { "organization": "fern", - "version": "0.66.30" + "version": "0.65.24" } \ No newline at end of file diff --git a/fern/footer-dist/output.js b/fern/footer-dist/output.js index 58163513..0eee302e 100644 --- a/fern/footer-dist/output.js +++ b/fern/footer-dist/output.js @@ -1,4 +1,4 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(l){if(l.ep)return;l.ep=!0;const o=n(l);fetch(l.href,o)}})();function lf(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Fu={exports:{}},el={},Bu={exports:{}},C={};/** +(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const u of o.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&r(u)}).observe(document,{childList:!0,subtree:!0});function t(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(l){if(l.ep)return;l.ep=!0;const o=t(l);fetch(l.href,o)}})();function lf(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Fi={exports:{}},el={},Bi={exports:{}},D={};/** * @license React * react.production.min.js * @@ -6,7 +6,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var In=Symbol.for("react.element"),of=Symbol.for("react.portal"),uf=Symbol.for("react.fragment"),sf=Symbol.for("react.strict_mode"),ff=Symbol.for("react.profiler"),af=Symbol.for("react.provider"),cf=Symbol.for("react.context"),df=Symbol.for("react.forward_ref"),vf=Symbol.for("react.suspense"),pf=Symbol.for("react.memo"),hf=Symbol.for("react.lazy"),ki=Symbol.iterator;function mf(e){return e===null||typeof e!="object"?null:(e=ki&&e[ki]||e["@@iterator"],typeof e=="function"?e:null)}var bu={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Au=Object.assign,Iu={};function rn(e,t,n){this.props=e,this.context=t,this.refs=Iu,this.updater=n||bu}rn.prototype.isReactComponent={};rn.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};rn.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Ku(){}Ku.prototype=rn.prototype;function qo(e,t,n){this.props=e,this.context=t,this.refs=Iu,this.updater=n||bu}var Wo=qo.prototype=new Ku;Wo.constructor=qo;Au(Wo,rn.prototype);Wo.isPureReactComponent=!0;var Ni=Array.isArray,Qu=Object.prototype.hasOwnProperty,So={current:null},Ju={key:!0,ref:!0,__self:!0,__source:!0};function _u(e,t,n){var r,l={},o=null,i=null;if(t!=null)for(r in t.ref!==void 0&&(i=t.ref),t.key!==void 0&&(o=""+t.key),t)Qu.call(t,r)&&!Ju.hasOwnProperty(r)&&(l[r]=t[r]);var u=arguments.length-2;if(u===1)l.children=n;else if(1>>1,K=H[F];if(0>>1;F<$n;){var ht=2*(F+1)-1,xl=H[ht],mt=ht+1,er=H[mt];if(0>l(xl,O))mtl(er,xl)?(H[F]=er,H[mt]=O,F=mt):(H[F]=xl,H[ht]=O,F=ht);else if(mtl(er,O))H[F]=er,H[mt]=O,F=mt;else break e}}return Y}function l(H,Y){var O=H.sortIndex-Y.sortIndex;return O!==0?O:H.id-Y.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var i=Date,u=i.now();e.unstable_now=function(){return i.now()-u}}var s=[],c=[],m=1,h=null,p=3,y=!1,j=!1,g=!1,L=typeof setTimeout=="function"?setTimeout:null,d=typeof clearTimeout=="function"?clearTimeout:null,a=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function v(H){for(var Y=n(c);Y!==null;){if(Y.callback===null)r(c);else if(Y.startTime<=H)r(c),Y.sortIndex=Y.expirationTime,t(s,Y);else break;Y=n(c)}}function P(H){if(g=!1,v(H),!j)if(n(s)!==null)j=!0,ml(z);else{var Y=n(c);Y!==null&&Pl(P,Y.startTime-H)}}function z(H,Y){j=!1,g&&(g=!1,d(G),G=-1),y=!0;var O=p;try{for(v(Y),h=n(s);h!==null&&(!(h.expirationTime>Y)||H&&!Me());){var F=h.callback;if(typeof F=="function"){h.callback=null,p=h.priorityLevel;var K=F(h.expirationTime<=Y);Y=e.unstable_now(),typeof K=="function"?h.callback=K:h===n(s)&&r(s),v(Y)}else r(s);h=n(s)}if(h!==null)var $n=!0;else{var ht=n(c);ht!==null&&Pl(P,ht.startTime-Y),$n=!1}return $n}finally{h=null,p=O,y=!1}}var X=!1,M=null,G=-1,R=5,D=-1;function Me(){return!(e.unstable_now()-DH||125F?(H.sortIndex=O,t(c,H),n(s)===null&&H===n(c)&&(g?(d(G),G=-1):g=!0,Pl(P,O-F))):(H.sortIndex=K,t(s,H),j||y||(j=!0,ml(z))),H},e.unstable_shouldYield=Me,e.unstable_wrapCallback=function(H){var Y=p;return function(){var O=p;p=Y;try{return H.apply(this,arguments)}finally{p=O}}}})(rs);ns.exports=rs;var Yf=ns.exports;/** + */(function(e){function n(H,Y){var O=H.length;H.push(Y);e:for(;0>>1,K=H[F];if(0>>1;F<$t;){var mn=2*(F+1)-1,xl=H[mn],Pn=mn+1,er=H[Pn];if(0>l(xl,O))Pnl(er,xl)?(H[F]=er,H[Pn]=O,F=Pn):(H[F]=xl,H[mn]=O,F=mn);else if(Pnl(er,O))H[F]=er,H[Pn]=O,F=Pn;else break e}}return Y}function l(H,Y){var O=H.sortIndex-Y.sortIndex;return O!==0?O:H.id-Y.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var u=Date,i=u.now();e.unstable_now=function(){return u.now()-i}}var s=[],a=[],m=1,h=null,p=3,y=!1,j=!1,g=!1,L=typeof setTimeout=="function"?setTimeout:null,c=typeof clearTimeout=="function"?clearTimeout:null,f=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function v(H){for(var Y=t(a);Y!==null;){if(Y.callback===null)r(a);else if(Y.startTime<=H)r(a),Y.sortIndex=Y.expirationTime,n(s,Y);else break;Y=t(a)}}function P(H){if(g=!1,v(H),!j)if(t(s)!==null)j=!0,ml(z);else{var Y=t(a);Y!==null&&Pl(P,Y.startTime-H)}}function z(H,Y){j=!1,g&&(g=!1,c(G),G=-1),y=!0;var O=p;try{for(v(Y),h=t(s);h!==null&&(!(h.expirationTime>Y)||H&&!Me());){var F=h.callback;if(typeof F=="function"){h.callback=null,p=h.priorityLevel;var K=F(h.expirationTime<=Y);Y=e.unstable_now(),typeof K=="function"?h.callback=K:h===t(s)&&r(s),v(Y)}else r(s);h=t(s)}if(h!==null)var $t=!0;else{var mn=t(a);mn!==null&&Pl(P,mn.startTime-Y),$t=!1}return $t}finally{h=null,p=O,y=!1}}var X=!1,M=null,G=-1,R=5,C=-1;function Me(){return!(e.unstable_now()-CH||125F?(H.sortIndex=O,n(a,H),t(s)===null&&H===t(a)&&(g?(c(G),G=-1):g=!0,Pl(P,O-F))):(H.sortIndex=K,n(s,H),j||y||(j=!0,ml(z))),H},e.unstable_shouldYield=Me,e.unstable_wrapCallback=function(H){var Y=p;return function(){var O=p;p=Y;try{return H.apply(this,arguments)}finally{p=O}}}})(rs);ts.exports=rs;var Yf=ts.exports;/** * @license React * react-dom.production.min.js * @@ -30,14 +30,14 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Of=Cn,Pe=Yf;function x(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Bl=Object.prototype.hasOwnProperty,Cf=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Vi={},Li={};function Df(e){return Bl.call(Li,e)?!0:Bl.call(Vi,e)?!1:Cf.test(e)?Li[e]=!0:(Vi[e]=!0,!1)}function Zf(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function kf(e,t,n,r){if(t===null||typeof t>"u"||Zf(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function se(e,t,n,r,l,o,i){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var ee={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){ee[e]=new se(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];ee[t]=new se(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){ee[e]=new se(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){ee[e]=new se(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){ee[e]=new se(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){ee[e]=new se(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){ee[e]=new se(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){ee[e]=new se(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){ee[e]=new se(e,5,!1,e.toLowerCase(),null,!1,!1)});var Eo=/[\-:]([a-z])/g;function Ro(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Eo,Ro);ee[t]=new se(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Eo,Ro);ee[t]=new se(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Eo,Ro);ee[t]=new se(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){ee[e]=new se(e,1,!1,e.toLowerCase(),null,!1,!1)});ee.xlinkHref=new se("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){ee[e]=new se(e,1,!1,e.toLowerCase(),null,!0,!0)});function Fo(e,t,n,r){var l=ee.hasOwnProperty(t)?ee[t]:null;(l!==null?l.type!==0:r||!(2"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Bl=Object.prototype.hasOwnProperty,Df=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Vu={},Lu={};function Cf(e){return Bl.call(Lu,e)?!0:Bl.call(Vu,e)?!1:Df.test(e)?Lu[e]=!0:(Vu[e]=!0,!1)}function Zf(e,n,t,r){if(t!==null&&t.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return r?!1:t!==null?!t.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function kf(e,n,t,r){if(n===null||typeof n>"u"||Zf(e,n,t,r))return!0;if(r)return!1;if(t!==null)switch(t.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function se(e,n,t,r,l,o,u){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=t,this.propertyName=e,this.type=n,this.sanitizeURL=o,this.removeEmptyString=u}var ee={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){ee[e]=new se(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];ee[n]=new se(n,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){ee[e]=new se(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){ee[e]=new se(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){ee[e]=new se(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){ee[e]=new se(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){ee[e]=new se(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){ee[e]=new se(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){ee[e]=new se(e,5,!1,e.toLowerCase(),null,!1,!1)});var Eo=/[\-:]([a-z])/g;function Ro(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(Eo,Ro);ee[n]=new se(n,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(Eo,Ro);ee[n]=new se(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(Eo,Ro);ee[n]=new se(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){ee[e]=new se(e,1,!1,e.toLowerCase(),null,!1,!1)});ee.xlinkHref=new se("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){ee[e]=new se(e,1,!1,e.toLowerCase(),null,!0,!0)});function Fo(e,n,t,r){var l=ee.hasOwnProperty(n)?ee[n]:null;(l!==null?l.type!==0:r||!(2u||l[i]!==o[u]){var s=` -`+l[i].replace(" at new "," at ");return e.displayName&&s.includes("")&&(s=s.replace("",e.displayName)),s}while(1<=i&&0<=u);break}}}finally{gl=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Pn(e):""}function Nf(e){switch(e.tag){case 5:return Pn(e.type);case 16:return Pn("Lazy");case 13:return Pn("Suspense");case 19:return Pn("SuspenseList");case 0:case 2:case 15:return e=wl(e.type,!1),e;case 11:return e=wl(e.type.render,!1),e;case 1:return e=wl(e.type,!0),e;default:return""}}function Kl(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case kt:return"Fragment";case Zt:return"Portal";case bl:return"Profiler";case Bo:return"StrictMode";case Al:return"Suspense";case Il:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case is:return(e.displayName||"Context")+".Consumer";case os:return(e._context.displayName||"Context")+".Provider";case bo:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Ao:return t=e.displayName||null,t!==null?t:Kl(e.type)||"Memo";case Qe:t=e._payload,e=e._init;try{return Kl(e(t))}catch{}}return null}function Tf(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Kl(t);case 8:return t===Bo?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function at(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ss(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Vf(e){var t=ss(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var l=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return l.call(this)},set:function(i){r=""+i,o.call(this,i)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(i){r=""+i},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function rr(e){e._valueTracker||(e._valueTracker=Vf(e))}function fs(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ss(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function Cr(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ql(e,t){var n=t.checked;return U({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Wi(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=at(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function as(e,t){t=t.checked,t!=null&&Fo(e,"checked",t,!1)}function Jl(e,t){as(e,t);var n=at(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?_l(e,t.type,n):t.hasOwnProperty("defaultValue")&&_l(e,t.type,at(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Si(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function _l(e,t,n){(t!=="number"||Cr(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var xn=Array.isArray;function Ft(e,t,n,r){if(e=e.options,t){t={};for(var l=0;l"+t.valueOf().toString()+"",t=lr.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Zn(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var gn={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Lf=["Webkit","ms","Moz","O"];Object.keys(gn).forEach(function(e){Lf.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),gn[t]=gn[e]})});function ps(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||gn.hasOwnProperty(e)&&gn[e]?(""+t).trim():t+"px"}function hs(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,l=ps(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,l):e[n]=l}}var qf=U({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function to(e,t){if(t){if(qf[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(x(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(x(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(x(61))}if(t.style!=null&&typeof t.style!="object")throw Error(x(62))}}function no(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ro=null;function Io(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var lo=null,Bt=null,bt=null;function Ri(e){if(e=Jn(e)){if(typeof lo!="function")throw Error(x(280));var t=e.stateNode;t&&(t=ol(t),lo(e.stateNode,e.type,t))}}function ms(e){Bt?bt?bt.push(e):bt=[e]:Bt=e}function Ps(){if(Bt){var e=Bt,t=bt;if(bt=Bt=null,Ri(e),t)for(e=0;e>>=0,e===0?32:31-(Kf(e)/Qf|0)|0}var or=64,ir=4194304;function yn(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Nr(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,l=e.suspendedLanes,o=e.pingedLanes,i=n&268435455;if(i!==0){var u=i&~l;u!==0?r=yn(u):(o&=i,o!==0&&(r=yn(o)))}else i=n&~l,i!==0?r=yn(i):o!==0&&(r=yn(o));if(r===0)return 0;if(t!==0&&t!==r&&!(t&l)&&(l=r&-r,o=t&-t,l>=o||l===16&&(o&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Kn(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-De(t),e[t]=n}function ea(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=zn),_i=" ",$i=!1;function Ls(e,t){switch(e){case"keyup":return Ya.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function qs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Nt=!1;function Ca(e,t){switch(e){case"compositionend":return qs(t);case"keypress":return t.which!==32?null:($i=!0,_i);case"textInput":return e=t.data,e===_i&&$i?null:e;default:return null}}function Da(e,t){if(Nt)return e==="compositionend"||!ni&&Ls(e,t)?(e=Ts(),gr=$o=et=null,Nt=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=ru(n)}}function Es(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Es(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Rs(){for(var e=window,t=Cr();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Cr(e.document)}return t}function ri(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Sa(e){var t=Rs(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Es(n.ownerDocument.documentElement,n)){if(r!==null&&ri(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var l=n.textContent.length,o=Math.min(r.start,l);r=r.end===void 0?o:Math.min(r.end,l),!e.extend&&o>r&&(l=r,r=o,o=l),l=lu(n,o);var i=lu(n,r);l&&i&&(e.rangeCount!==1||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==i.node||e.focusOffset!==i.offset)&&(t=t.createRange(),t.setStart(l.node,l.offset),e.removeAllRanges(),o>r?(e.addRange(t),e.extend(i.node,i.offset)):(t.setEnd(i.node,i.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,Tt=null,ao=null,Xn=null,co=!1;function ou(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;co||Tt==null||Tt!==Cr(r)||(r=Tt,"selectionStart"in r&&ri(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Xn&&qn(Xn,r)||(Xn=r,r=Lr(ao,"onSelect"),0qt||(e.current=xo[qt],xo[qt]=null,qt--)}function N(e,t){qt++,xo[qt]=e.current,e.current=t}var ct={},le=vt(ct),ce=vt(!1),Ht=ct;function Jt(e,t){var n=e.type.contextTypes;if(!n)return ct;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var l={},o;for(o in n)l[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=l),l}function de(e){return e=e.childContextTypes,e!=null}function Wr(){V(ce),V(le)}function du(e,t,n){if(le.current!==ct)throw Error(x(168));N(le,t),N(ce,n)}function _s(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var l in r)if(!(l in t))throw Error(x(108,Tf(e)||"Unknown",l));return U({},n,r)}function Sr(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||ct,Ht=le.current,N(le,e),N(ce,ce.current),!0}function vu(e,t,n){var r=e.stateNode;if(!r)throw Error(x(169));n?(e=_s(e,t,Ht),r.__reactInternalMemoizedMergedChildContext=e,V(ce),V(le),N(le,e)):V(ce),N(ce,n)}var Se=null,il=!1,Vl=!1;function $s(e){Se===null?Se=[e]:Se.push(e)}function _a(e){il=!0,$s(e)}function pt(){if(!Vl&&Se!==null){Vl=!0;var e=0,t=k;try{var n=Se;for(k=1;e>=i,l-=i,Ue=1<<32-De(t)+l|n<G?(R=M,M=null):R=M.sibling;var D=p(d,M,v[G],P);if(D===null){M===null&&(M=R);break}e&&M&&D.alternate===null&&t(d,M),a=o(D,a,G),X===null?z=D:X.sibling=D,X=D,M=R}if(G===v.length)return n(d,M),q&&Pt(d,G),z;if(M===null){for(;GG?(R=M,M=null):R=M.sibling;var Me=p(d,M,D.value,P);if(Me===null){M===null&&(M=R);break}e&&M&&Me.alternate===null&&t(d,M),a=o(Me,a,G),X===null?z=Me:X.sibling=Me,X=Me,M=R}if(D.done)return n(d,M),q&&Pt(d,G),z;if(M===null){for(;!D.done;G++,D=v.next())D=h(d,D.value,P),D!==null&&(a=o(D,a,G),X===null?z=D:X.sibling=D,X=D);return q&&Pt(d,G),z}for(M=r(d,M);!D.done;G++,D=v.next())D=y(M,d,G,D.value,P),D!==null&&(e&&D.alternate!==null&&M.delete(D.key===null?G:D.key),a=o(D,a,G),X===null?z=D:X.sibling=D,X=D);return e&&M.forEach(function(un){return t(d,un)}),q&&Pt(d,G),z}function L(d,a,v,P){if(typeof v=="object"&&v!==null&&v.type===kt&&v.key===null&&(v=v.props.children),typeof v=="object"&&v!==null){switch(v.$$typeof){case nr:e:{for(var z=v.key,X=a;X!==null;){if(X.key===z){if(z=v.type,z===kt){if(X.tag===7){n(d,X.sibling),a=l(X,v.props.children),a.return=d,d=a;break e}}else if(X.elementType===z||typeof z=="object"&&z!==null&&z.$$typeof===Qe&&mu(z)===X.type){n(d,X.sibling),a=l(X,v.props),a.ref=pn(d,X,v),a.return=d,d=a;break e}n(d,X);break}else t(d,X);X=X.sibling}v.type===kt?(a=zt(v.props.children,d.mode,P,v.key),a.return=d,d=a):(P=Or(v.type,v.key,v.props,null,d.mode,P),P.ref=pn(d,a,v),P.return=d,d=P)}return i(d);case Zt:e:{for(X=v.key;a!==null;){if(a.key===X)if(a.tag===4&&a.stateNode.containerInfo===v.containerInfo&&a.stateNode.implementation===v.implementation){n(d,a.sibling),a=l(a,v.children||[]),a.return=d,d=a;break e}else{n(d,a);break}else t(d,a);a=a.sibling}a=Fl(v,d.mode,P),a.return=d,d=a}return i(d);case Qe:return X=v._init,L(d,a,X(v._payload),P)}if(xn(v))return j(d,a,v,P);if(fn(v))return g(d,a,v,P);vr(d,v)}return typeof v=="string"&&v!==""||typeof v=="number"?(v=""+v,a!==null&&a.tag===6?(n(d,a.sibling),a=l(a,v),a.return=d,d=a):(n(d,a),a=Rl(v,d.mode,P),a.return=d,d=a),i(d)):n(d,a)}return L}var $t=r1(!0),l1=r1(!1),Rr=vt(null),Fr=null,Ut=null,ui=null;function si(){ui=Ut=Fr=null}function fi(e){var t=Rr.current;V(Rr),e._currentValue=t}function go(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function It(e,t){Fr=e,ui=Ut=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&(ae=!0),e.firstContext=null)}function He(e){var t=e._currentValue;if(ui!==e)if(e={context:e,memoizedValue:t,next:null},Ut===null){if(Fr===null)throw Error(x(308));Ut=e,Fr.dependencies={lanes:0,firstContext:e}}else Ut=Ut.next=e;return t}var jt=null;function ai(e){jt===null?jt=[e]:jt.push(e)}function o1(e,t,n,r){var l=t.interleaved;return l===null?(n.next=n,ai(t)):(n.next=l.next,l.next=n),t.interleaved=n,be(e,r)}function be(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Je=!1;function ci(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function i1(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Re(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function it(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Z&2){var l=r.pending;return l===null?t.next=t:(t.next=l.next,l.next=t),r.pending=t,be(e,n)}return l=r.interleaved,l===null?(t.next=t,ai(r)):(t.next=l.next,l.next=t),r.interleaved=t,be(e,n)}function zr(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qo(e,n)}}function Pu(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var l=null,o=null;if(n=n.firstBaseUpdate,n!==null){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};o===null?l=o=i:o=o.next=i,n=n.next}while(n!==null);o===null?l=o=t:o=o.next=t}else l=o=t;n={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Br(e,t,n,r){var l=e.updateQueue;Je=!1;var o=l.firstBaseUpdate,i=l.lastBaseUpdate,u=l.shared.pending;if(u!==null){l.shared.pending=null;var s=u,c=s.next;s.next=null,i===null?o=c:i.next=c,i=s;var m=e.alternate;m!==null&&(m=m.updateQueue,u=m.lastBaseUpdate,u!==i&&(u===null?m.firstBaseUpdate=c:u.next=c,m.lastBaseUpdate=s))}if(o!==null){var h=l.baseState;i=0,m=c=s=null,u=o;do{var p=u.lane,y=u.eventTime;if((r&p)===p){m!==null&&(m=m.next={eventTime:y,lane:0,tag:u.tag,payload:u.payload,callback:u.callback,next:null});e:{var j=e,g=u;switch(p=t,y=n,g.tag){case 1:if(j=g.payload,typeof j=="function"){h=j.call(y,h,p);break e}h=j;break e;case 3:j.flags=j.flags&-65537|128;case 0:if(j=g.payload,p=typeof j=="function"?j.call(y,h,p):j,p==null)break e;h=U({},h,p);break e;case 2:Je=!0}}u.callback!==null&&u.lane!==0&&(e.flags|=64,p=l.effects,p===null?l.effects=[u]:p.push(u))}else y={eventTime:y,lane:p,tag:u.tag,payload:u.payload,callback:u.callback,next:null},m===null?(c=m=y,s=h):m=m.next=y,i|=p;if(u=u.next,u===null){if(u=l.shared.pending,u===null)break;p=u,u=p.next,p.next=null,l.lastBaseUpdate=p,l.shared.pending=null}}while(!0);if(m===null&&(s=h),l.baseState=s,l.firstBaseUpdate=c,l.lastBaseUpdate=m,t=l.shared.interleaved,t!==null){l=t;do i|=l.lane,l=l.next;while(l!==t)}else o===null&&(l.shared.lanes=0);Gt|=i,e.lanes=i,e.memoizedState=h}}function xu(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=ql.transition;ql.transition={};try{e(!1),t()}finally{k=n,ql.transition=r}}function z1(){return Xe().memoizedState}function n2(e,t,n){var r=st(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},H1(e))X1(t,n);else if(n=o1(e,t,n,r),n!==null){var l=ie();Ze(n,e,r,l),M1(n,t,r)}}function r2(e,t,n){var r=st(e),l={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(H1(e))X1(t,l);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=t.lastRenderedReducer,o!==null))try{var i=t.lastRenderedState,u=o(i,n);if(l.hasEagerState=!0,l.eagerState=u,ke(u,i)){var s=t.interleaved;s===null?(l.next=l,ai(t)):(l.next=s.next,s.next=l),t.interleaved=l;return}}catch{}finally{}n=o1(e,t,l,r),n!==null&&(l=ie(),Ze(n,e,r,l),M1(n,t,r))}}function H1(e){var t=e.alternate;return e===S||t!==null&&t===S}function X1(e,t){Mn=Ar=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function M1(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qo(e,n)}}var Ir={readContext:He,useCallback:te,useContext:te,useEffect:te,useImperativeHandle:te,useInsertionEffect:te,useLayoutEffect:te,useMemo:te,useReducer:te,useRef:te,useState:te,useDebugValue:te,useDeferredValue:te,useTransition:te,useMutableSource:te,useSyncExternalStore:te,useId:te,unstable_isNewReconciler:!1},l2={readContext:He,useCallback:function(e,t){return Te().memoizedState=[e,t===void 0?null:t],e},useContext:He,useEffect:ju,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Xr(4194308,4,x1.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Xr(4194308,4,e,t)},useInsertionEffect:function(e,t){return Xr(4,2,e,t)},useMemo:function(e,t){var n=Te();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Te();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=n2.bind(null,S,e),[r.memoizedState,e]},useRef:function(e){var t=Te();return e={current:e},t.memoizedState=e},useState:yu,useDebugValue:yi,useDeferredValue:function(e){return Te().memoizedState=e},useTransition:function(){var e=yu(!1),t=e[0];return e=t2.bind(null,e[1]),Te().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=S,l=Te();if(q){if(n===void 0)throw Error(x(407));n=n()}else{if(n=t(),J===null)throw Error(x(349));Mt&30||a1(r,t,n)}l.memoizedState=n;var o={value:n,getSnapshot:t};return l.queue=o,ju(d1.bind(null,r,o,e),[e]),r.flags|=2048,bn(9,c1.bind(null,r,o,n,t),void 0,null),n},useId:function(){var e=Te(),t=J.identifierPrefix;if(q){var n=Ee,r=Ue;n=(r&~(1<<32-De(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Fn++,0i||l[u]!==o[i]){var s=` +`+l[u].replace(" at new "," at ");return e.displayName&&s.includes("")&&(s=s.replace("",e.displayName)),s}while(1<=u&&0<=i);break}}}finally{gl=!1,Error.prepareStackTrace=t}return(e=e?e.displayName||e.name:"")?Pt(e):""}function Nf(e){switch(e.tag){case 5:return Pt(e.type);case 16:return Pt("Lazy");case 13:return Pt("Suspense");case 19:return Pt("SuspenseList");case 0:case 2:case 15:return e=wl(e.type,!1),e;case 11:return e=wl(e.type.render,!1),e;case 1:return e=wl(e.type,!0),e;default:return""}}function Kl(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Nn:return"Fragment";case kn:return"Portal";case bl:return"Profiler";case Bo:return"StrictMode";case Al:return"Suspense";case Il:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case us:return(e.displayName||"Context")+".Consumer";case os:return(e._context.displayName||"Context")+".Provider";case bo:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Ao:return n=e.displayName||null,n!==null?n:Kl(e.type)||"Memo";case Qe:n=e._payload,e=e._init;try{return Kl(e(n))}catch{}}return null}function Tf(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Kl(n);case 8:return n===Bo?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function cn(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ss(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function Vf(e){var n=ss(e)?"checked":"value",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),r=""+e[n];if(!e.hasOwnProperty(n)&&typeof t<"u"&&typeof t.get=="function"&&typeof t.set=="function"){var l=t.get,o=t.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return l.call(this)},set:function(u){r=""+u,o.call(this,u)}}),Object.defineProperty(e,n,{enumerable:t.enumerable}),{getValue:function(){return r},setValue:function(u){r=""+u},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function rr(e){e._valueTracker||(e._valueTracker=Vf(e))}function fs(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var t=n.getValue(),r="";return e&&(r=ss(e)?e.checked?"true":"false":e.value),e=r,e!==t?(n.setValue(e),!0):!1}function Dr(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ql(e,n){var t=n.checked;return U({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:t??e._wrapperState.initialChecked})}function Wu(e,n){var t=n.defaultValue==null?"":n.defaultValue,r=n.checked!=null?n.checked:n.defaultChecked;t=cn(n.value!=null?n.value:t),e._wrapperState={initialChecked:r,initialValue:t,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function as(e,n){n=n.checked,n!=null&&Fo(e,"checked",n,!1)}function Jl(e,n){as(e,n);var t=cn(n.value),r=n.type;if(t!=null)r==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+t):e.value!==""+t&&(e.value=""+t);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?_l(e,n.type,t):n.hasOwnProperty("defaultValue")&&_l(e,n.type,cn(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function Su(e,n,t){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var r=n.type;if(!(r!=="submit"&&r!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,t||n===e.value||(e.value=n),e.defaultValue=n}t=e.name,t!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,t!==""&&(e.name=t)}function _l(e,n,t){(n!=="number"||Dr(e.ownerDocument)!==e)&&(t==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+t&&(e.defaultValue=""+t))}var xt=Array.isArray;function Bn(e,n,t,r){if(e=e.options,n){n={};for(var l=0;l"+n.valueOf().toString()+"",n=lr.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function Zt(e,n){if(n){var t=e.firstChild;if(t&&t===e.lastChild&&t.nodeType===3){t.nodeValue=n;return}}e.textContent=n}var gt={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Lf=["Webkit","ms","Moz","O"];Object.keys(gt).forEach(function(e){Lf.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),gt[n]=gt[e]})});function ps(e,n,t){return n==null||typeof n=="boolean"||n===""?"":t||typeof n!="number"||n===0||gt.hasOwnProperty(e)&>[e]?(""+n).trim():n+"px"}function hs(e,n){e=e.style;for(var t in n)if(n.hasOwnProperty(t)){var r=t.indexOf("--")===0,l=ps(t,n[t],r);t==="float"&&(t="cssFloat"),r?e.setProperty(t,l):e[t]=l}}var qf=U({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function no(e,n){if(n){if(qf[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(x(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(x(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(x(61))}if(n.style!=null&&typeof n.style!="object")throw Error(x(62))}}function to(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ro=null;function Io(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var lo=null,bn=null,An=null;function Ru(e){if(e=Jt(e)){if(typeof lo!="function")throw Error(x(280));var n=e.stateNode;n&&(n=ol(n),lo(e.stateNode,e.type,n))}}function ms(e){bn?An?An.push(e):An=[e]:bn=e}function Ps(){if(bn){var e=bn,n=An;if(An=bn=null,Ru(e),n)for(e=0;e>>=0,e===0?32:31-(Kf(e)/Qf|0)|0}var or=64,ur=4194304;function yt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Nr(e,n){var t=e.pendingLanes;if(t===0)return 0;var r=0,l=e.suspendedLanes,o=e.pingedLanes,u=t&268435455;if(u!==0){var i=u&~l;i!==0?r=yt(i):(o&=u,o!==0&&(r=yt(o)))}else u=t&~l,u!==0?r=yt(u):o!==0&&(r=yt(o));if(r===0)return 0;if(n!==0&&n!==r&&!(n&l)&&(l=r&-r,o=n&-n,l>=o||l===16&&(o&4194240)!==0))return n;if(r&4&&(r|=t&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=r;0t;t++)n.push(e);return n}function Kt(e,n,t){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-Ce(n),e[n]=t}function ea(e,n){var t=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=zt),_u=" ",$u=!1;function Ls(e,n){switch(e){case"keyup":return Ya.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function qs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Tn=!1;function Da(e,n){switch(e){case"compositionend":return qs(n);case"keypress":return n.which!==32?null:($u=!0,_u);case"textInput":return e=n.data,e===_u&&$u?null:e;default:return null}}function Ca(e,n){if(Tn)return e==="compositionend"||!tu&&Ls(e,n)?(e=Ts(),gr=$o=en=null,Tn=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:t,offset:n-e};e=r}e:{for(;t;){if(t.nextSibling){t=t.nextSibling;break e}t=t.parentNode}t=void 0}t=ri(t)}}function Es(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Es(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function Rs(){for(var e=window,n=Dr();n instanceof e.HTMLIFrameElement;){try{var t=typeof n.contentWindow.location.href=="string"}catch{t=!1}if(t)e=n.contentWindow;else break;n=Dr(e.document)}return n}function ru(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function Sa(e){var n=Rs(),t=e.focusedElem,r=e.selectionRange;if(n!==t&&t&&t.ownerDocument&&Es(t.ownerDocument.documentElement,t)){if(r!==null&&ru(t)){if(n=r.start,e=r.end,e===void 0&&(e=n),"selectionStart"in t)t.selectionStart=n,t.selectionEnd=Math.min(e,t.value.length);else if(e=(n=t.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var l=t.textContent.length,o=Math.min(r.start,l);r=r.end===void 0?o:Math.min(r.end,l),!e.extend&&o>r&&(l=r,r=o,o=l),l=li(t,o);var u=li(t,r);l&&u&&(e.rangeCount!==1||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==u.node||e.focusOffset!==u.offset)&&(n=n.createRange(),n.setStart(l.node,l.offset),e.removeAllRanges(),o>r?(e.addRange(n),e.extend(u.node,u.offset)):(n.setEnd(u.node,u.offset),e.addRange(n)))}}for(n=[],e=t;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof t.focus=="function"&&t.focus(),t=0;t=document.documentMode,Vn=null,ao=null,Xt=null,co=!1;function oi(e,n,t){var r=t.window===t?t.document:t.nodeType===9?t:t.ownerDocument;co||Vn==null||Vn!==Dr(r)||(r=Vn,"selectionStart"in r&&ru(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Xt&&qt(Xt,r)||(Xt=r,r=Lr(ao,"onSelect"),0Wn||(e.current=xo[Wn],xo[Wn]=null,Wn--)}function N(e,n){Wn++,xo[Wn]=e.current,e.current=n}var dn={},le=pn(dn),ce=pn(!1),Xn=dn;function _n(e,n){var t=e.type.contextTypes;if(!t)return dn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===n)return r.__reactInternalMemoizedMaskedChildContext;var l={},o;for(o in t)l[o]=n[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=l),l}function de(e){return e=e.childContextTypes,e!=null}function Wr(){V(ce),V(le)}function di(e,n,t){if(le.current!==dn)throw Error(x(168));N(le,n),N(ce,t)}function _s(e,n,t){var r=e.stateNode;if(n=n.childContextTypes,typeof r.getChildContext!="function")return t;r=r.getChildContext();for(var l in r)if(!(l in n))throw Error(x(108,Tf(e)||"Unknown",l));return U({},t,r)}function Sr(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||dn,Xn=le.current,N(le,e),N(ce,ce.current),!0}function vi(e,n,t){var r=e.stateNode;if(!r)throw Error(x(169));t?(e=_s(e,n,Xn),r.__reactInternalMemoizedMergedChildContext=e,V(ce),V(le),N(le,e)):V(ce),N(ce,t)}var Se=null,ul=!1,Vl=!1;function $s(e){Se===null?Se=[e]:Se.push(e)}function _a(e){ul=!0,$s(e)}function hn(){if(!Vl&&Se!==null){Vl=!0;var e=0,n=k;try{var t=Se;for(k=1;e>=u,l-=u,Ue=1<<32-Ce(n)+l|t<G?(R=M,M=null):R=M.sibling;var C=p(c,M,v[G],P);if(C===null){M===null&&(M=R);break}e&&M&&C.alternate===null&&n(c,M),f=o(C,f,G),X===null?z=C:X.sibling=C,X=C,M=R}if(G===v.length)return t(c,M),q&&xn(c,G),z;if(M===null){for(;GG?(R=M,M=null):R=M.sibling;var Me=p(c,M,C.value,P);if(Me===null){M===null&&(M=R);break}e&&M&&Me.alternate===null&&n(c,M),f=o(Me,f,G),X===null?z=Me:X.sibling=Me,X=Me,M=R}if(C.done)return t(c,M),q&&xn(c,G),z;if(M===null){for(;!C.done;G++,C=v.next())C=h(c,C.value,P),C!==null&&(f=o(C,f,G),X===null?z=C:X.sibling=C,X=C);return q&&xn(c,G),z}for(M=r(c,M);!C.done;G++,C=v.next())C=y(M,c,G,C.value,P),C!==null&&(e&&C.alternate!==null&&M.delete(C.key===null?G:C.key),f=o(C,f,G),X===null?z=C:X.sibling=C,X=C);return e&&M.forEach(function(it){return n(c,it)}),q&&xn(c,G),z}function L(c,f,v,P){if(typeof v=="object"&&v!==null&&v.type===Nn&&v.key===null&&(v=v.props.children),typeof v=="object"&&v!==null){switch(v.$$typeof){case tr:e:{for(var z=v.key,X=f;X!==null;){if(X.key===z){if(z=v.type,z===Nn){if(X.tag===7){t(c,X.sibling),f=l(X,v.props.children),f.return=c,c=f;break e}}else if(X.elementType===z||typeof z=="object"&&z!==null&&z.$$typeof===Qe&&mi(z)===X.type){t(c,X.sibling),f=l(X,v.props),f.ref=pt(c,X,v),f.return=c,c=f;break e}t(c,X);break}else n(c,X);X=X.sibling}v.type===Nn?(f=Hn(v.props.children,c.mode,P,v.key),f.return=c,c=f):(P=Or(v.type,v.key,v.props,null,c.mode,P),P.ref=pt(c,f,v),P.return=c,c=P)}return u(c);case kn:e:{for(X=v.key;f!==null;){if(f.key===X)if(f.tag===4&&f.stateNode.containerInfo===v.containerInfo&&f.stateNode.implementation===v.implementation){t(c,f.sibling),f=l(f,v.children||[]),f.return=c,c=f;break e}else{t(c,f);break}else n(c,f);f=f.sibling}f=Fl(v,c.mode,P),f.return=c,c=f}return u(c);case Qe:return X=v._init,L(c,f,X(v._payload),P)}if(xt(v))return j(c,f,v,P);if(ft(v))return g(c,f,v,P);vr(c,v)}return typeof v=="string"&&v!==""||typeof v=="number"?(v=""+v,f!==null&&f.tag===6?(t(c,f.sibling),f=l(f,v),f.return=c,c=f):(t(c,f),f=Rl(v,c.mode,P),f.return=c,c=f),u(c)):t(c,f)}return L}var et=r1(!0),l1=r1(!1),Rr=pn(null),Fr=null,En=null,iu=null;function su(){iu=En=Fr=null}function fu(e){var n=Rr.current;V(Rr),e._currentValue=n}function go(e,n,t){for(;e!==null;){var r=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,r!==null&&(r.childLanes|=n)):r!==null&&(r.childLanes&n)!==n&&(r.childLanes|=n),e===t)break;e=e.return}}function Kn(e,n){Fr=e,iu=En=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&n&&(ae=!0),e.firstContext=null)}function He(e){var n=e._currentValue;if(iu!==e)if(e={context:e,memoizedValue:n,next:null},En===null){if(Fr===null)throw Error(x(308));En=e,Fr.dependencies={lanes:0,firstContext:e}}else En=En.next=e;return n}var gn=null;function au(e){gn===null?gn=[e]:gn.push(e)}function o1(e,n,t,r){var l=n.interleaved;return l===null?(t.next=t,au(n)):(t.next=l.next,l.next=t),n.interleaved=t,be(e,r)}function be(e,n){e.lanes|=n;var t=e.alternate;for(t!==null&&(t.lanes|=n),t=e,e=e.return;e!==null;)e.childLanes|=n,t=e.alternate,t!==null&&(t.childLanes|=n),t=e,e=e.return;return t.tag===3?t.stateNode:null}var Je=!1;function cu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function u1(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Re(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function un(e,n,t){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Z&2){var l=r.pending;return l===null?n.next=n:(n.next=l.next,l.next=n),r.pending=n,be(e,t)}return l=r.interleaved,l===null?(n.next=n,au(r)):(n.next=l.next,l.next=n),r.interleaved=n,be(e,t)}function zr(e,n,t){if(n=n.updateQueue,n!==null&&(n=n.shared,(t&4194240)!==0)){var r=n.lanes;r&=e.pendingLanes,t|=r,n.lanes=t,Qo(e,t)}}function Pi(e,n){var t=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,t===r)){var l=null,o=null;if(t=t.firstBaseUpdate,t!==null){do{var u={eventTime:t.eventTime,lane:t.lane,tag:t.tag,payload:t.payload,callback:t.callback,next:null};o===null?l=o=u:o=o.next=u,t=t.next}while(t!==null);o===null?l=o=n:o=o.next=n}else l=o=n;t={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=t;return}e=t.lastBaseUpdate,e===null?t.firstBaseUpdate=n:e.next=n,t.lastBaseUpdate=n}function Br(e,n,t,r){var l=e.updateQueue;Je=!1;var o=l.firstBaseUpdate,u=l.lastBaseUpdate,i=l.shared.pending;if(i!==null){l.shared.pending=null;var s=i,a=s.next;s.next=null,u===null?o=a:u.next=a,u=s;var m=e.alternate;m!==null&&(m=m.updateQueue,i=m.lastBaseUpdate,i!==u&&(i===null?m.firstBaseUpdate=a:i.next=a,m.lastBaseUpdate=s))}if(o!==null){var h=l.baseState;u=0,m=a=s=null,i=o;do{var p=i.lane,y=i.eventTime;if((r&p)===p){m!==null&&(m=m.next={eventTime:y,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var j=e,g=i;switch(p=n,y=t,g.tag){case 1:if(j=g.payload,typeof j=="function"){h=j.call(y,h,p);break e}h=j;break e;case 3:j.flags=j.flags&-65537|128;case 0:if(j=g.payload,p=typeof j=="function"?j.call(y,h,p):j,p==null)break e;h=U({},h,p);break e;case 2:Je=!0}}i.callback!==null&&i.lane!==0&&(e.flags|=64,p=l.effects,p===null?l.effects=[i]:p.push(i))}else y={eventTime:y,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},m===null?(a=m=y,s=h):m=m.next=y,u|=p;if(i=i.next,i===null){if(i=l.shared.pending,i===null)break;p=i,i=p.next,p.next=null,l.lastBaseUpdate=p,l.shared.pending=null}}while(!0);if(m===null&&(s=h),l.baseState=s,l.firstBaseUpdate=a,l.lastBaseUpdate=m,n=l.shared.interleaved,n!==null){l=n;do u|=l.lane,l=l.next;while(l!==n)}else o===null&&(l.shared.lanes=0);Yn|=u,e.lanes=u,e.memoizedState=h}}function xi(e,n,t){if(e=n.effects,n.effects=null,e!==null)for(n=0;nt?t:4,e(!0);var r=ql.transition;ql.transition={};try{e(!1),n()}finally{k=t,ql.transition=r}}function z1(){return Xe().memoizedState}function t2(e,n,t){var r=fn(e);if(t={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null},H1(e))X1(n,t);else if(t=o1(e,n,t,r),t!==null){var l=ue();Ze(t,e,r,l),M1(t,n,r)}}function r2(e,n,t){var r=fn(e),l={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null};if(H1(e))X1(n,l);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=n.lastRenderedReducer,o!==null))try{var u=n.lastRenderedState,i=o(u,t);if(l.hasEagerState=!0,l.eagerState=i,ke(i,u)){var s=n.interleaved;s===null?(l.next=l,au(n)):(l.next=s.next,s.next=l),n.interleaved=l;return}}catch{}finally{}t=o1(e,n,l,r),t!==null&&(l=ue(),Ze(t,e,r,l),M1(t,n,r))}}function H1(e){var n=e.alternate;return e===S||n!==null&&n===S}function X1(e,n){Mt=Ar=!0;var t=e.pending;t===null?n.next=n:(n.next=t.next,t.next=n),e.pending=n}function M1(e,n,t){if(t&4194240){var r=n.lanes;r&=e.pendingLanes,t|=r,n.lanes=t,Qo(e,t)}}var Ir={readContext:He,useCallback:ne,useContext:ne,useEffect:ne,useImperativeHandle:ne,useInsertionEffect:ne,useLayoutEffect:ne,useMemo:ne,useReducer:ne,useRef:ne,useState:ne,useDebugValue:ne,useDeferredValue:ne,useTransition:ne,useMutableSource:ne,useSyncExternalStore:ne,useId:ne,unstable_isNewReconciler:!1},l2={readContext:He,useCallback:function(e,n){return Te().memoizedState=[e,n===void 0?null:n],e},useContext:He,useEffect:ji,useImperativeHandle:function(e,n,t){return t=t!=null?t.concat([e]):null,Xr(4194308,4,x1.bind(null,n,e),t)},useLayoutEffect:function(e,n){return Xr(4194308,4,e,n)},useInsertionEffect:function(e,n){return Xr(4,2,e,n)},useMemo:function(e,n){var t=Te();return n=n===void 0?null:n,e=e(),t.memoizedState=[e,n],e},useReducer:function(e,n,t){var r=Te();return n=t!==void 0?t(n):n,r.memoizedState=r.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},r.queue=e,e=e.dispatch=t2.bind(null,S,e),[r.memoizedState,e]},useRef:function(e){var n=Te();return e={current:e},n.memoizedState=e},useState:yi,useDebugValue:yu,useDeferredValue:function(e){return Te().memoizedState=e},useTransition:function(){var e=yi(!1),n=e[0];return e=n2.bind(null,e[1]),Te().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,t){var r=S,l=Te();if(q){if(t===void 0)throw Error(x(407));t=t()}else{if(t=n(),J===null)throw Error(x(349));Gn&30||a1(r,n,t)}l.memoizedState=t;var o={value:t,getSnapshot:n};return l.queue=o,ji(d1.bind(null,r,o,e),[e]),r.flags|=2048,bt(9,c1.bind(null,r,o,t,n),void 0,null),t},useId:function(){var e=Te(),n=J.identifierPrefix;if(q){var t=Ee,r=Ue;t=(r&~(1<<32-Ce(r)-1)).toString(32)+t,n=":"+n+"R"+t,t=Ft++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=i.createElement(n,{is:r.is}):(e=i.createElement(n),n==="select"&&(i=e,r.multiple?i.multiple=!0:r.size&&(i.size=r.size))):e=i.createElementNS(e,n),e[Ve]=t,e[Un]=r,V1(e,t,!1,!1),t.stateNode=e;e:{switch(i=no(n,r),n){case"dialog":T("cancel",e),T("close",e),l=r;break;case"iframe":case"object":case"embed":T("load",e),l=r;break;case"video":case"audio":for(l=0;lnn&&(t.flags|=128,r=!0,hn(o,!1),t.lanes=4194304)}else{if(!r)if(e=br(i),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),hn(o,!0),o.tail===null&&o.tailMode==="hidden"&&!i.alternate&&!q)return ne(t),null}else 2*B()-o.renderingStartTime>nn&&n!==1073741824&&(t.flags|=128,r=!0,hn(o,!1),t.lanes=4194304);o.isBackwards?(i.sibling=t.child,t.child=i):(n=o.last,n!==null?n.sibling=i:t.child=i,o.last=i)}return o.tail!==null?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=B(),t.sibling=null,n=W.current,N(W,r?n&1|2:n&1),t):(ne(t),null);case 22:case 23:return Xi(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?pe&1073741824&&(ne(t),t.subtreeFlags&6&&(t.flags|=8192)):ne(t),null;case 24:return null;case 25:return null}throw Error(x(156,t.tag))}function d2(e,t){switch(oi(t),t.tag){case 1:return de(t.type)&&Wr(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return en(),V(ce),V(le),pi(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return vi(t),null;case 13:if(V(W),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(x(340));_t()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return V(W),null;case 4:return en(),null;case 10:return fi(t.type._context),null;case 22:case 23:return Xi(),null;case 24:return null;default:return null}}var hr=!1,re=!1,v2=typeof WeakSet=="function"?WeakSet:Set,w=null;function Et(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){E(e,t,r)}else n.current=null}function Co(e,t,n){try{n()}catch(r){E(e,t,r)}}var Du=!1;function p2(e,t){if(vo=Tr,e=Rs(),ri(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var l=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break e}var i=0,u=-1,s=-1,c=0,m=0,h=e,p=null;t:for(;;){for(var y;h!==n||l!==0&&h.nodeType!==3||(u=i+l),h!==o||r!==0&&h.nodeType!==3||(s=i+r),h.nodeType===3&&(i+=h.nodeValue.length),(y=h.firstChild)!==null;)p=h,h=y;for(;;){if(h===e)break t;if(p===n&&++c===l&&(u=i),p===o&&++m===r&&(s=i),(y=h.nextSibling)!==null)break;h=p,p=h.parentNode}h=y}n=u===-1||s===-1?null:{start:u,end:s}}else n=null}n=n||{start:0,end:0}}else n=null;for(po={focusedElem:e,selectionRange:n},Tr=!1,w=t;w!==null;)if(t=w,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,w=e;else for(;w!==null;){t=w;try{var j=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(j!==null){var g=j.memoizedProps,L=j.memoizedState,d=t.stateNode,a=d.getSnapshotBeforeUpdate(t.elementType===t.type?g:Ye(t.type,g),L);d.__reactInternalSnapshotBeforeUpdate=a}break;case 3:var v=t.stateNode.containerInfo;v.nodeType===1?v.textContent="":v.nodeType===9&&v.documentElement&&v.removeChild(v.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(x(163))}}catch(P){E(t,t.return,P)}if(e=t.sibling,e!==null){e.return=t.return,w=e;break}w=t.return}return j=Du,Du=!1,j}function Gn(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var l=r=r.next;do{if((l.tag&e)===e){var o=l.destroy;l.destroy=void 0,o!==void 0&&Co(t,n,o)}l=l.next}while(l!==r)}}function fl(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Do(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function W1(e){var t=e.alternate;t!==null&&(e.alternate=null,W1(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Ve],delete t[Un],delete t[Po],delete t[Qa],delete t[Ja])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function S1(e){return e.tag===5||e.tag===3||e.tag===4}function Zu(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||S1(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zo(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=qr));else if(r!==4&&(e=e.child,e!==null))for(Zo(e,t,n),e=e.sibling;e!==null;)Zo(e,t,n),e=e.sibling}function ko(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(ko(e,t,n),e=e.sibling;e!==null;)ko(e,t,n),e=e.sibling}var _=null,Oe=!1;function Ke(e,t,n){for(n=n.child;n!==null;)U1(e,t,n),n=n.sibling}function U1(e,t,n){if(Le&&typeof Le.onCommitFiberUnmount=="function")try{Le.onCommitFiberUnmount(tl,n)}catch{}switch(n.tag){case 5:re||Et(n,t);case 6:var r=_,l=Oe;_=null,Ke(e,t,n),_=r,Oe=l,_!==null&&(Oe?(e=_,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):_.removeChild(n.stateNode));break;case 18:_!==null&&(Oe?(e=_,n=n.stateNode,e.nodeType===8?Tl(e.parentNode,n):e.nodeType===1&&Tl(e,n),Vn(e)):Tl(_,n.stateNode));break;case 4:r=_,l=Oe,_=n.stateNode.containerInfo,Oe=!0,Ke(e,t,n),_=r,Oe=l;break;case 0:case 11:case 14:case 15:if(!re&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){l=r=r.next;do{var o=l,i=o.destroy;o=o.tag,i!==void 0&&(o&2||o&4)&&Co(n,t,i),l=l.next}while(l!==r)}Ke(e,t,n);break;case 1:if(!re&&(Et(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(u){E(n,t,u)}Ke(e,t,n);break;case 21:Ke(e,t,n);break;case 22:n.mode&1?(re=(r=re)||n.memoizedState!==null,Ke(e,t,n),re=r):Ke(e,t,n);break;default:Ke(e,t,n)}}function ku(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new v2),t.forEach(function(r){var l=z2.bind(null,e,r);n.has(r)||(n.add(r),r.then(l,l))})}}function Ge(e,t){var n=t.deletions;if(n!==null)for(var r=0;rl&&(l=i),r&=~o}if(r=l,r=B()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*m2(r/1960))-r,10e?16:e,tt===null)var r=!1;else{if(e=tt,tt=null,Jr=0,Z&6)throw Error(x(331));var l=Z;for(Z|=4,w=e.current;w!==null;){var o=w,i=o.child;if(w.flags&16){var u=o.deletions;if(u!==null){for(var s=0;sB()-zi?wt(e,0):wi|=n),ve(e,t)}function K1(e,t){t===0&&(e.mode&1?(t=ir,ir<<=1,!(ir&130023424)&&(ir=4194304)):t=1);var n=ie();e=be(e,t),e!==null&&(Kn(e,t,n),ve(e,n))}function w2(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),K1(e,n)}function z2(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;l!==null&&(n=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(x(314))}r!==null&&r.delete(t),K1(e,n)}var Q1;Q1=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||ce.current)ae=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return ae=!1,a2(e,t,n);ae=!!(e.flags&131072)}else ae=!1,q&&t.flags&1048576&&e1(t,Er,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Mr(e,t),e=t.pendingProps;var l=Jt(t,le.current);It(t,n),l=mi(null,t,r,e,l,n);var o=Pi();return t.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,de(r)?(o=!0,Sr(t)):o=!1,t.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,ci(t),l.updater=sl,t.stateNode=l,l._reactInternals=t,zo(t,r,e,n),t=Mo(null,t,r,!0,o,n)):(t.tag=0,q&&o&&li(t),oe(null,t,l,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Mr(e,t),e=t.pendingProps,l=r._init,r=l(r._payload),t.type=r,l=t.tag=X2(r),e=Ye(r,e),l){case 0:t=Xo(null,t,r,e,n);break e;case 1:t=Yu(null,t,r,e,n);break e;case 11:t=Mu(null,t,r,e,n);break e;case 14:t=Gu(null,t,r,Ye(r.type,e),n);break e}throw Error(x(306,r,""))}return t;case 0:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:Ye(r,l),Xo(e,t,r,l,n);case 1:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:Ye(r,l),Yu(e,t,r,l,n);case 3:e:{if(k1(t),e===null)throw Error(x(387));r=t.pendingProps,o=t.memoizedState,l=o.element,i1(e,t),Br(t,r,null,n);var i=t.memoizedState;if(r=i.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){l=tn(Error(x(423)),t),t=Ou(e,t,r,n,l);break e}else if(r!==l){l=tn(Error(x(424)),t),t=Ou(e,t,r,n,l);break e}else for(he=ot(t.stateNode.containerInfo.firstChild),me=t,q=!0,Ce=null,n=l1(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(_t(),r===l){t=Ae(e,t,n);break e}oe(e,t,r,n)}t=t.child}return t;case 5:return u1(t),e===null&&jo(t),r=t.type,l=t.pendingProps,o=e!==null?e.memoizedProps:null,i=l.children,ho(r,l)?i=null:o!==null&&ho(r,o)&&(t.flags|=32),Z1(e,t),oe(e,t,i,n),t.child;case 6:return e===null&&jo(t),null;case 13:return N1(e,t,n);case 4:return di(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=$t(t,null,r,n):oe(e,t,r,n),t.child;case 11:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:Ye(r,l),Mu(e,t,r,l,n);case 7:return oe(e,t,t.pendingProps,n),t.child;case 8:return oe(e,t,t.pendingProps.children,n),t.child;case 12:return oe(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,l=t.pendingProps,o=t.memoizedProps,i=l.value,N(Rr,r._currentValue),r._currentValue=i,o!==null)if(ke(o.value,i)){if(o.children===l.children&&!ce.current){t=Ae(e,t,n);break e}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var u=o.dependencies;if(u!==null){i=o.child;for(var s=u.firstContext;s!==null;){if(s.context===r){if(o.tag===1){s=Re(-1,n&-n),s.tag=2;var c=o.updateQueue;if(c!==null){c=c.shared;var m=c.pending;m===null?s.next=s:(s.next=m.next,m.next=s),c.pending=s}}o.lanes|=n,s=o.alternate,s!==null&&(s.lanes|=n),go(o.return,n,t),u.lanes|=n;break}s=s.next}}else if(o.tag===10)i=o.type===t.type?null:o.child;else if(o.tag===18){if(i=o.return,i===null)throw Error(x(341));i.lanes|=n,u=i.alternate,u!==null&&(u.lanes|=n),go(i,n,t),i=o.sibling}else i=o.child;if(i!==null)i.return=o;else for(i=o;i!==null;){if(i===t){i=null;break}if(o=i.sibling,o!==null){o.return=i.return,i=o;break}i=i.return}o=i}oe(e,t,l.children,n),t=t.child}return t;case 9:return l=t.type,r=t.pendingProps.children,It(t,n),l=He(l),r=r(l),t.flags|=1,oe(e,t,r,n),t.child;case 14:return r=t.type,l=Ye(r,t.pendingProps),l=Ye(r.type,l),Gu(e,t,r,l,n);case 15:return C1(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:Ye(r,l),Mr(e,t),t.tag=1,de(r)?(e=!0,Sr(t)):e=!1,It(t,n),G1(t,r,l),zo(t,r,l,n),Mo(null,t,r,!0,e,n);case 19:return T1(e,t,n);case 22:return D1(e,t,n)}throw Error(x(156,t.tag))};function J1(e,t){return Hs(e,t)}function H2(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function we(e,t,n,r){return new H2(e,t,n,r)}function Gi(e){return e=e.prototype,!(!e||!e.isReactComponent)}function X2(e){if(typeof e=="function")return Gi(e)?1:0;if(e!=null){if(e=e.$$typeof,e===bo)return 11;if(e===Ao)return 14}return 2}function ft(e,t){var n=e.alternate;return n===null?(n=we(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Or(e,t,n,r,l,o){var i=2;if(r=e,typeof e=="function")Gi(e)&&(i=1);else if(typeof e=="string")i=5;else e:switch(e){case kt:return zt(n.children,l,o,t);case Bo:i=8,l|=8;break;case bl:return e=we(12,n,t,l|2),e.elementType=bl,e.lanes=o,e;case Al:return e=we(13,n,t,l),e.elementType=Al,e.lanes=o,e;case Il:return e=we(19,n,t,l),e.elementType=Il,e.lanes=o,e;case us:return cl(n,l,o,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case os:i=10;break e;case is:i=9;break e;case bo:i=11;break e;case Ao:i=14;break e;case Qe:i=16,r=null;break e}throw Error(x(130,e==null?e:typeof e,""))}return t=we(i,n,t,l),t.elementType=e,t.type=r,t.lanes=o,t}function zt(e,t,n,r){return e=we(7,e,r,t),e.lanes=n,e}function cl(e,t,n,r){return e=we(22,e,r,t),e.elementType=us,e.lanes=n,e.stateNode={isHidden:!1},e}function Rl(e,t,n){return e=we(6,e,null,t),e.lanes=n,e}function Fl(e,t,n){return t=we(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function M2(e,t,n,r,l){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Hl(0),this.expirationTimes=Hl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Hl(0),this.identifierPrefix=r,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function Yi(e,t,n,r,l,o,i,u,s){return e=new M2(e,t,n,u,s),t===1?(t=1,o===!0&&(t|=8)):t=0,o=we(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},ci(o),e}function G2(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(tf)}catch(e){console.error(e)}}tf(),ts.exports=xe;var Z2=ts.exports,nf,Uu=Z2;nf=Uu.createRoot,Uu.hydrateRoot;const k2=()=>{const[e,t]=Cn.useState({dotClass:"is-loading",statusMessage:"Checking status..."}),n="https://status.buildwithfern.com/api/v1/summary",r=5*60*1e3,l=u=>{let s="is-green",c="All systems operational";if(u.ongoing_incidents&&u.ongoing_incidents.length>0){let m=0;for(const h of u.ongoing_incidents){let p=0;h.current_worst_impact==="degraded_performance"?p=1:h.current_worst_impact==="partial_outage"?p=2:h.current_worst_impact==="full_outage"&&(p=3),p>m&&(m=p)}m===3?(s="is-red",c="Service outage"):m===2?(s="is-orange",c="Partial outage"):m===1&&(s="is-yellow",c="Degraded performance")}if(u.in_progress_maintenances&&u.in_progress_maintenances.length>0&&s==="is-green"&&(s="is-blue",c="Maintenance in progress"),u.scheduled_maintenances&&u.scheduled_maintenances.length>0&&s==="is-green"){const m=new Date;let h=!1;for(const p of u.scheduled_maintenances)if((new Date(p.starts_at).getTime()-m.getTime())/(1e3*60*60)<=24){h=!0;break}h&&(s="is-blue",c="Scheduled maintenance soon")}t({dotClass:s,statusMessage:c})},o=async()=>{try{const u=await fetch(n);if(u.ok){const s=await u.json();l(s)}else t({dotClass:"is-red",statusMessage:"Cannot check status"})}catch(u){console.error("Error fetching status:",u),t({dotClass:"is-red",statusMessage:"Cannot check status"})}};Cn.useEffect(()=>{o();const u=setInterval(o,r);return()=>clearInterval(u)},[]);const i=()=>{switch(e.dotClass){case"is-green":return"#00c853";case"is-red":return"#f44336";case"is-orange":return"#ff9800";case"is-blue":return"#2196f3";case"is-yellow":return"#ffc107";case"is-loading":return"#cccccc";default:return"#cccccc"}};return f.jsx("a",{href:"https://status.buildwithfern.com",target:"_blank",rel:"noopener noreferrer",style:{textDecoration:"none",color:"inherit"},children:f.jsxs("div",{id:"fern-status-widget",className:"fern-status-widget",children:[f.jsx("div",{className:`footer_badge-dot ${e.dotClass}`,style:{width:"10px",height:"10px",borderRadius:"50%",marginRight:"8px",position:"relative",display:"inline-block",backgroundColor:i()}}),f.jsx("span",{id:"fern-status-text",className:"fern-status-text",children:e.statusMessage}),f.jsx("style",{children:` +`+o.stack}return{value:e,source:n,stack:l,digest:null}}function Ul(e,n,t){return{value:e,source:null,stack:t??null,digest:n??null}}function Ho(e,n){try{console.error(n.value)}catch(t){setTimeout(function(){throw t})}}var i2=typeof WeakMap=="function"?WeakMap:Map;function Y1(e,n,t){t=Re(-1,t),t.tag=3,t.payload={element:null};var r=n.value;return t.callback=function(){Qr||(Qr=!0,No=r),Ho(e,n)},t}function O1(e,n,t){t=Re(-1,t),t.tag=3;var r=e.type.getDerivedStateFromError;if(typeof r=="function"){var l=n.value;t.payload=function(){return r(l)},t.callback=function(){Ho(e,n)}}var o=e.stateNode;return o!==null&&typeof o.componentDidCatch=="function"&&(t.callback=function(){Ho(e,n),typeof r!="function"&&(sn===null?sn=new Set([this]):sn.add(this));var u=n.stack;this.componentDidCatch(n.value,{componentStack:u!==null?u:""})}),t}function zi(e,n,t){var r=e.pingCache;if(r===null){r=e.pingCache=new i2;var l=new Set;r.set(n,l)}else l=r.get(n),l===void 0&&(l=new Set,r.set(n,l));l.has(t)||(l.add(t),e=g2.bind(null,e,n,t),n.then(e,e))}function Hi(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function Xi(e,n,t,r,l){return e.mode&1?(e.flags|=65536,e.lanes=l,e):(e===n?e.flags|=65536:(e.flags|=128,t.flags|=131072,t.flags&=-52805,t.tag===1&&(t.alternate===null?t.tag=17:(n=Re(-1,1),n.tag=2,un(t,n,1))),t.lanes|=1),e)}var s2=Ie.ReactCurrentOwner,ae=!1;function oe(e,n,t,r){n.child=e===null?l1(n,null,t,r):et(n,e.child,t,r)}function Mi(e,n,t,r,l){t=t.render;var o=n.ref;return Kn(n,l),r=mu(e,n,t,r,o,l),t=Pu(),e!==null&&!ae?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~l,Ae(e,n,l)):(q&&t&&lu(n),n.flags|=1,oe(e,n,r,l),n.child)}function Gi(e,n,t,r,l){if(e===null){var o=t.type;return typeof o=="function"&&!Gu(o)&&o.defaultProps===void 0&&t.compare===null&&t.defaultProps===void 0?(n.tag=15,n.type=o,D1(e,n,o,r,l)):(e=Or(t.type,null,r,n,n.mode,l),e.ref=n.ref,e.return=n,n.child=e)}if(o=e.child,!(e.lanes&l)){var u=o.memoizedProps;if(t=t.compare,t=t!==null?t:qt,t(u,r)&&e.ref===n.ref)return Ae(e,n,l)}return n.flags|=1,e=an(o,r),e.ref=n.ref,e.return=n,n.child=e}function D1(e,n,t,r,l){if(e!==null){var o=e.memoizedProps;if(qt(o,r)&&e.ref===n.ref)if(ae=!1,n.pendingProps=r=o,(e.lanes&l)!==0)e.flags&131072&&(ae=!0);else return n.lanes=e.lanes,Ae(e,n,l)}return Xo(e,n,t,r,l)}function C1(e,n,t){var r=n.pendingProps,l=r.children,o=e!==null?e.memoizedState:null;if(r.mode==="hidden")if(!(n.mode&1))n.memoizedState={baseLanes:0,cachePool:null,transitions:null},N(Fn,pe),pe|=t;else{if(!(t&1073741824))return e=o!==null?o.baseLanes|t:t,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,N(Fn,pe),pe|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=o!==null?o.baseLanes:t,N(Fn,pe),pe|=r}else o!==null?(r=o.baseLanes|t,n.memoizedState=null):r=t,N(Fn,pe),pe|=r;return oe(e,n,l,t),n.child}function Z1(e,n){var t=n.ref;(e===null&&t!==null||e!==null&&e.ref!==t)&&(n.flags|=512,n.flags|=2097152)}function Xo(e,n,t,r,l){var o=de(t)?Xn:le.current;return o=_n(n,o),Kn(n,l),t=mu(e,n,t,r,o,l),r=Pu(),e!==null&&!ae?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~l,Ae(e,n,l)):(q&&r&&lu(n),n.flags|=1,oe(e,n,t,l),n.child)}function Yi(e,n,t,r,l){if(de(t)){var o=!0;Sr(n)}else o=!1;if(Kn(n,l),n.stateNode===null)Mr(e,n),G1(n,t,r),zo(n,t,r,l),r=!0;else if(e===null){var u=n.stateNode,i=n.memoizedProps;u.props=i;var s=u.context,a=t.contextType;typeof a=="object"&&a!==null?a=He(a):(a=de(t)?Xn:le.current,a=_n(n,a));var m=t.getDerivedStateFromProps,h=typeof m=="function"||typeof u.getSnapshotBeforeUpdate=="function";h||typeof u.UNSAFE_componentWillReceiveProps!="function"&&typeof u.componentWillReceiveProps!="function"||(i!==r||s!==a)&&wi(n,u,r,a),Je=!1;var p=n.memoizedState;u.state=p,Br(n,r,u,l),s=n.memoizedState,i!==r||p!==s||ce.current||Je?(typeof m=="function"&&(wo(n,t,m,r),s=n.memoizedState),(i=Je||gi(n,t,i,r,p,s,a))?(h||typeof u.UNSAFE_componentWillMount!="function"&&typeof u.componentWillMount!="function"||(typeof u.componentWillMount=="function"&&u.componentWillMount(),typeof u.UNSAFE_componentWillMount=="function"&&u.UNSAFE_componentWillMount()),typeof u.componentDidMount=="function"&&(n.flags|=4194308)):(typeof u.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=r,n.memoizedState=s),u.props=r,u.state=s,u.context=a,r=i):(typeof u.componentDidMount=="function"&&(n.flags|=4194308),r=!1)}else{u=n.stateNode,u1(e,n),i=n.memoizedProps,a=n.type===n.elementType?i:Ye(n.type,i),u.props=a,h=n.pendingProps,p=u.context,s=t.contextType,typeof s=="object"&&s!==null?s=He(s):(s=de(t)?Xn:le.current,s=_n(n,s));var y=t.getDerivedStateFromProps;(m=typeof y=="function"||typeof u.getSnapshotBeforeUpdate=="function")||typeof u.UNSAFE_componentWillReceiveProps!="function"&&typeof u.componentWillReceiveProps!="function"||(i!==h||p!==s)&&wi(n,u,r,s),Je=!1,p=n.memoizedState,u.state=p,Br(n,r,u,l);var j=n.memoizedState;i!==h||p!==j||ce.current||Je?(typeof y=="function"&&(wo(n,t,y,r),j=n.memoizedState),(a=Je||gi(n,t,a,r,p,j,s)||!1)?(m||typeof u.UNSAFE_componentWillUpdate!="function"&&typeof u.componentWillUpdate!="function"||(typeof u.componentWillUpdate=="function"&&u.componentWillUpdate(r,j,s),typeof u.UNSAFE_componentWillUpdate=="function"&&u.UNSAFE_componentWillUpdate(r,j,s)),typeof u.componentDidUpdate=="function"&&(n.flags|=4),typeof u.getSnapshotBeforeUpdate=="function"&&(n.flags|=1024)):(typeof u.componentDidUpdate!="function"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=4),typeof u.getSnapshotBeforeUpdate!="function"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=1024),n.memoizedProps=r,n.memoizedState=j),u.props=r,u.state=j,u.context=s,r=a):(typeof u.componentDidUpdate!="function"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=4),typeof u.getSnapshotBeforeUpdate!="function"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=1024),r=!1)}return Mo(e,n,t,r,o,l)}function Mo(e,n,t,r,l,o){Z1(e,n);var u=(n.flags&128)!==0;if(!r&&!u)return l&&vi(n,t,!1),Ae(e,n,o);r=n.stateNode,s2.current=n;var i=u&&typeof t.getDerivedStateFromError!="function"?null:r.render();return n.flags|=1,e!==null&&u?(n.child=et(n,e.child,null,o),n.child=et(n,null,i,o)):oe(e,n,i,o),n.memoizedState=r.state,l&&vi(n,t,!0),n.child}function k1(e){var n=e.stateNode;n.pendingContext?di(e,n.pendingContext,n.pendingContext!==n.context):n.context&&di(e,n.context,!1),du(e,n.containerInfo)}function Oi(e,n,t,r,l){return $n(),uu(l),n.flags|=256,oe(e,n,t,r),n.child}var Go={dehydrated:null,treeContext:null,retryLane:0};function Yo(e){return{baseLanes:e,cachePool:null,transitions:null}}function N1(e,n,t){var r=n.pendingProps,l=W.current,o=!1,u=(n.flags&128)!==0,i;if((i=u)||(i=e!==null&&e.memoizedState===null?!1:(l&2)!==0),i?(o=!0,n.flags&=-129):(e===null||e.memoizedState!==null)&&(l|=1),N(W,l&1),e===null)return jo(n),e=n.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(n.mode&1?e.data==="$!"?n.lanes=8:n.lanes=1073741824:n.lanes=1,null):(u=r.children,e=r.fallback,o?(r=n.mode,o=n.child,u={mode:"hidden",children:u},!(r&1)&&o!==null?(o.childLanes=0,o.pendingProps=u):o=cl(u,r,0,null),e=Hn(e,r,t,null),o.return=n,e.return=n,o.sibling=e,n.child=o,n.child.memoizedState=Yo(t),n.memoizedState=Go,e):ju(n,u));if(l=e.memoizedState,l!==null&&(i=l.dehydrated,i!==null))return f2(e,n,u,r,i,l,t);if(o){o=r.fallback,u=n.mode,l=e.child,i=l.sibling;var s={mode:"hidden",children:r.children};return!(u&1)&&n.child!==l?(r=n.child,r.childLanes=0,r.pendingProps=s,n.deletions=null):(r=an(l,s),r.subtreeFlags=l.subtreeFlags&14680064),i!==null?o=an(i,o):(o=Hn(o,u,t,null),o.flags|=2),o.return=n,r.return=n,r.sibling=o,n.child=r,r=o,o=n.child,u=e.child.memoizedState,u=u===null?Yo(t):{baseLanes:u.baseLanes|t,cachePool:null,transitions:u.transitions},o.memoizedState=u,o.childLanes=e.childLanes&~t,n.memoizedState=Go,r}return o=e.child,e=o.sibling,r=an(o,{mode:"visible",children:r.children}),!(n.mode&1)&&(r.lanes=t),r.return=n,r.sibling=null,e!==null&&(t=n.deletions,t===null?(n.deletions=[e],n.flags|=16):t.push(e)),n.child=r,n.memoizedState=null,r}function ju(e,n){return n=cl({mode:"visible",children:n},e.mode,0,null),n.return=e,e.child=n}function pr(e,n,t,r){return r!==null&&uu(r),et(n,e.child,null,t),e=ju(n,n.pendingProps.children),e.flags|=2,n.memoizedState=null,e}function f2(e,n,t,r,l,o,u){if(t)return n.flags&256?(n.flags&=-257,r=Ul(Error(x(422))),pr(e,n,u,r)):n.memoizedState!==null?(n.child=e.child,n.flags|=128,null):(o=r.fallback,l=n.mode,r=cl({mode:"visible",children:r.children},l,0,null),o=Hn(o,l,u,null),o.flags|=2,r.return=n,o.return=n,r.sibling=o,n.child=r,n.mode&1&&et(n,e.child,null,u),n.child.memoizedState=Yo(u),n.memoizedState=Go,o);if(!(n.mode&1))return pr(e,n,u,null);if(l.data==="$!"){if(r=l.nextSibling&&l.nextSibling.dataset,r)var i=r.dgst;return r=i,o=Error(x(419)),r=Ul(o,r,void 0),pr(e,n,u,r)}if(i=(u&e.childLanes)!==0,ae||i){if(r=J,r!==null){switch(u&-u){case 4:l=2;break;case 16:l=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:l=32;break;case 536870912:l=268435456;break;default:l=0}l=l&(r.suspendedLanes|u)?0:l,l!==0&&l!==o.retryLane&&(o.retryLane=l,be(e,l),Ze(r,e,l,-1))}return Mu(),r=Ul(Error(x(421))),pr(e,n,u,r)}return l.data==="$?"?(n.flags|=128,n.child=e.child,n=w2.bind(null,e),l._reactRetry=n,null):(e=o.treeContext,he=on(l.nextSibling),me=n,q=!0,De=null,e!==null&&(je[ge++]=Ue,je[ge++]=Ee,je[ge++]=Mn,Ue=e.id,Ee=e.overflow,Mn=n),n=ju(n,r.children),n.flags|=4096,n)}function Di(e,n,t){e.lanes|=n;var r=e.alternate;r!==null&&(r.lanes|=n),go(e.return,n,t)}function El(e,n,t,r,l){var o=e.memoizedState;o===null?e.memoizedState={isBackwards:n,rendering:null,renderingStartTime:0,last:r,tail:t,tailMode:l}:(o.isBackwards=n,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=t,o.tailMode=l)}function T1(e,n,t){var r=n.pendingProps,l=r.revealOrder,o=r.tail;if(oe(e,n,r.children,t),r=W.current,r&2)r=r&1|2,n.flags|=128;else{if(e!==null&&e.flags&128)e:for(e=n.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Di(e,t,n);else if(e.tag===19)Di(e,t,n);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===n)break e;for(;e.sibling===null;){if(e.return===null||e.return===n)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(N(W,r),!(n.mode&1))n.memoizedState=null;else switch(l){case"forwards":for(t=n.child,l=null;t!==null;)e=t.alternate,e!==null&&br(e)===null&&(l=t),t=t.sibling;t=l,t===null?(l=n.child,n.child=null):(l=t.sibling,t.sibling=null),El(n,!1,l,t,o);break;case"backwards":for(t=null,l=n.child,n.child=null;l!==null;){if(e=l.alternate,e!==null&&br(e)===null){n.child=l;break}e=l.sibling,l.sibling=t,t=l,l=e}El(n,!0,t,null,o);break;case"together":El(n,!1,null,null,void 0);break;default:n.memoizedState=null}return n.child}function Mr(e,n){!(n.mode&1)&&e!==null&&(e.alternate=null,n.alternate=null,n.flags|=2)}function Ae(e,n,t){if(e!==null&&(n.dependencies=e.dependencies),Yn|=n.lanes,!(t&n.childLanes))return null;if(e!==null&&n.child!==e.child)throw Error(x(153));if(n.child!==null){for(e=n.child,t=an(e,e.pendingProps),n.child=t,t.return=n;e.sibling!==null;)e=e.sibling,t=t.sibling=an(e,e.pendingProps),t.return=n;t.sibling=null}return n.child}function a2(e,n,t){switch(n.tag){case 3:k1(n),$n();break;case 5:i1(n);break;case 1:de(n.type)&&Sr(n);break;case 4:du(n,n.stateNode.containerInfo);break;case 10:var r=n.type._context,l=n.memoizedProps.value;N(Rr,r._currentValue),r._currentValue=l;break;case 13:if(r=n.memoizedState,r!==null)return r.dehydrated!==null?(N(W,W.current&1),n.flags|=128,null):t&n.child.childLanes?N1(e,n,t):(N(W,W.current&1),e=Ae(e,n,t),e!==null?e.sibling:null);N(W,W.current&1);break;case 19:if(r=(t&n.childLanes)!==0,e.flags&128){if(r)return T1(e,n,t);n.flags|=128}if(l=n.memoizedState,l!==null&&(l.rendering=null,l.tail=null,l.lastEffect=null),N(W,W.current),r)break;return null;case 22:case 23:return n.lanes=0,C1(e,n,t)}return Ae(e,n,t)}var V1,Oo,L1,q1;V1=function(e,n){for(var t=n.child;t!==null;){if(t.tag===5||t.tag===6)e.appendChild(t.stateNode);else if(t.tag!==4&&t.child!==null){t.child.return=t,t=t.child;continue}if(t===n)break;for(;t.sibling===null;){if(t.return===null||t.return===n)return;t=t.return}t.sibling.return=t.return,t=t.sibling}};Oo=function(){};L1=function(e,n,t,r){var l=e.memoizedProps;if(l!==r){e=n.stateNode,wn(qe.current);var o=null;switch(t){case"input":l=Ql(e,l),r=Ql(e,r),o=[];break;case"select":l=U({},l,{value:void 0}),r=U({},r,{value:void 0}),o=[];break;case"textarea":l=$l(e,l),r=$l(e,r),o=[];break;default:typeof l.onClick!="function"&&typeof r.onClick=="function"&&(e.onclick=qr)}no(t,r);var u;t=null;for(a in l)if(!r.hasOwnProperty(a)&&l.hasOwnProperty(a)&&l[a]!=null)if(a==="style"){var i=l[a];for(u in i)i.hasOwnProperty(u)&&(t||(t={}),t[u]="")}else a!=="dangerouslySetInnerHTML"&&a!=="children"&&a!=="suppressContentEditableWarning"&&a!=="suppressHydrationWarning"&&a!=="autoFocus"&&(Ct.hasOwnProperty(a)?o||(o=[]):(o=o||[]).push(a,null));for(a in r){var s=r[a];if(i=l!=null?l[a]:void 0,r.hasOwnProperty(a)&&s!==i&&(s!=null||i!=null))if(a==="style")if(i){for(u in i)!i.hasOwnProperty(u)||s&&s.hasOwnProperty(u)||(t||(t={}),t[u]="");for(u in s)s.hasOwnProperty(u)&&i[u]!==s[u]&&(t||(t={}),t[u]=s[u])}else t||(o||(o=[]),o.push(a,t)),t=s;else a==="dangerouslySetInnerHTML"?(s=s?s.__html:void 0,i=i?i.__html:void 0,s!=null&&i!==s&&(o=o||[]).push(a,s)):a==="children"?typeof s!="string"&&typeof s!="number"||(o=o||[]).push(a,""+s):a!=="suppressContentEditableWarning"&&a!=="suppressHydrationWarning"&&(Ct.hasOwnProperty(a)?(s!=null&&a==="onScroll"&&T("scroll",e),o||i===s||(o=[])):(o=o||[]).push(a,s))}t&&(o=o||[]).push("style",t);var a=o;(n.updateQueue=a)&&(n.flags|=4)}};q1=function(e,n,t,r){t!==r&&(n.flags|=4)};function ht(e,n){if(!q)switch(e.tailMode){case"hidden":n=e.tail;for(var t=null;n!==null;)n.alternate!==null&&(t=n),n=n.sibling;t===null?e.tail=null:t.sibling=null;break;case"collapsed":t=e.tail;for(var r=null;t!==null;)t.alternate!==null&&(r=t),t=t.sibling;r===null?n||e.tail===null?e.tail=null:e.tail.sibling=null:r.sibling=null}}function te(e){var n=e.alternate!==null&&e.alternate.child===e.child,t=0,r=0;if(n)for(var l=e.child;l!==null;)t|=l.lanes|l.childLanes,r|=l.subtreeFlags&14680064,r|=l.flags&14680064,l.return=e,l=l.sibling;else for(l=e.child;l!==null;)t|=l.lanes|l.childLanes,r|=l.subtreeFlags,r|=l.flags,l.return=e,l=l.sibling;return e.subtreeFlags|=r,e.childLanes=t,n}function c2(e,n,t){var r=n.pendingProps;switch(ou(n),n.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return te(n),null;case 1:return de(n.type)&&Wr(),te(n),null;case 3:return r=n.stateNode,nt(),V(ce),V(le),pu(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),(e===null||e.child===null)&&(dr(n)?n.flags|=4:e===null||e.memoizedState.isDehydrated&&!(n.flags&256)||(n.flags|=1024,De!==null&&(Lo(De),De=null))),Oo(e,n),te(n),null;case 5:vu(n);var l=wn(Rt.current);if(t=n.type,e!==null&&n.stateNode!=null)L1(e,n,t,r,l),e.ref!==n.ref&&(n.flags|=512,n.flags|=2097152);else{if(!r){if(n.stateNode===null)throw Error(x(166));return te(n),null}if(e=wn(qe.current),dr(n)){r=n.stateNode,t=n.type;var o=n.memoizedProps;switch(r[Ve]=n,r[Ut]=o,e=(n.mode&1)!==0,t){case"dialog":T("cancel",r),T("close",r);break;case"iframe":case"object":case"embed":T("load",r);break;case"video":case"audio":for(l=0;l<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=u.createElement(t,{is:r.is}):(e=u.createElement(t),t==="select"&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,t),e[Ve]=n,e[Ut]=r,V1(e,n,!1,!1),n.stateNode=e;e:{switch(u=to(t,r),t){case"dialog":T("cancel",e),T("close",e),l=r;break;case"iframe":case"object":case"embed":T("load",e),l=r;break;case"video":case"audio":for(l=0;lrt&&(n.flags|=128,r=!0,ht(o,!1),n.lanes=4194304)}else{if(!r)if(e=br(u),e!==null){if(n.flags|=128,r=!0,t=e.updateQueue,t!==null&&(n.updateQueue=t,n.flags|=4),ht(o,!0),o.tail===null&&o.tailMode==="hidden"&&!u.alternate&&!q)return te(n),null}else 2*B()-o.renderingStartTime>rt&&t!==1073741824&&(n.flags|=128,r=!0,ht(o,!1),n.lanes=4194304);o.isBackwards?(u.sibling=n.child,n.child=u):(t=o.last,t!==null?t.sibling=u:n.child=u,o.last=u)}return o.tail!==null?(n=o.tail,o.rendering=n,o.tail=n.sibling,o.renderingStartTime=B(),n.sibling=null,t=W.current,N(W,r?t&1|2:t&1),n):(te(n),null);case 22:case 23:return Xu(),r=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(n.flags|=8192),r&&n.mode&1?pe&1073741824&&(te(n),n.subtreeFlags&6&&(n.flags|=8192)):te(n),null;case 24:return null;case 25:return null}throw Error(x(156,n.tag))}function d2(e,n){switch(ou(n),n.tag){case 1:return de(n.type)&&Wr(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return nt(),V(ce),V(le),pu(),e=n.flags,e&65536&&!(e&128)?(n.flags=e&-65537|128,n):null;case 5:return vu(n),null;case 13:if(V(W),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(x(340));$n()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return V(W),null;case 4:return nt(),null;case 10:return fu(n.type._context),null;case 22:case 23:return Xu(),null;case 24:return null;default:return null}}var hr=!1,re=!1,v2=typeof WeakSet=="function"?WeakSet:Set,w=null;function Rn(e,n){var t=e.ref;if(t!==null)if(typeof t=="function")try{t(null)}catch(r){E(e,n,r)}else t.current=null}function Do(e,n,t){try{t()}catch(r){E(e,n,r)}}var Ci=!1;function p2(e,n){if(vo=Tr,e=Rs(),ru(e)){if("selectionStart"in e)var t={start:e.selectionStart,end:e.selectionEnd};else e:{t=(t=e.ownerDocument)&&t.defaultView||window;var r=t.getSelection&&t.getSelection();if(r&&r.rangeCount!==0){t=r.anchorNode;var l=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{t.nodeType,o.nodeType}catch{t=null;break e}var u=0,i=-1,s=-1,a=0,m=0,h=e,p=null;n:for(;;){for(var y;h!==t||l!==0&&h.nodeType!==3||(i=u+l),h!==o||r!==0&&h.nodeType!==3||(s=u+r),h.nodeType===3&&(u+=h.nodeValue.length),(y=h.firstChild)!==null;)p=h,h=y;for(;;){if(h===e)break n;if(p===t&&++a===l&&(i=u),p===o&&++m===r&&(s=u),(y=h.nextSibling)!==null)break;h=p,p=h.parentNode}h=y}t=i===-1||s===-1?null:{start:i,end:s}}else t=null}t=t||{start:0,end:0}}else t=null;for(po={focusedElem:e,selectionRange:t},Tr=!1,w=n;w!==null;)if(n=w,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,w=e;else for(;w!==null;){n=w;try{var j=n.alternate;if(n.flags&1024)switch(n.tag){case 0:case 11:case 15:break;case 1:if(j!==null){var g=j.memoizedProps,L=j.memoizedState,c=n.stateNode,f=c.getSnapshotBeforeUpdate(n.elementType===n.type?g:Ye(n.type,g),L);c.__reactInternalSnapshotBeforeUpdate=f}break;case 3:var v=n.stateNode.containerInfo;v.nodeType===1?v.textContent="":v.nodeType===9&&v.documentElement&&v.removeChild(v.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(x(163))}}catch(P){E(n,n.return,P)}if(e=n.sibling,e!==null){e.return=n.return,w=e;break}w=n.return}return j=Ci,Ci=!1,j}function Gt(e,n,t){var r=n.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var l=r=r.next;do{if((l.tag&e)===e){var o=l.destroy;l.destroy=void 0,o!==void 0&&Do(n,t,o)}l=l.next}while(l!==r)}}function fl(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var t=n=n.next;do{if((t.tag&e)===e){var r=t.create;t.destroy=r()}t=t.next}while(t!==n)}}function Co(e){var n=e.ref;if(n!==null){var t=e.stateNode;switch(e.tag){case 5:e=t;break;default:e=t}typeof n=="function"?n(e):n.current=e}}function W1(e){var n=e.alternate;n!==null&&(e.alternate=null,W1(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[Ve],delete n[Ut],delete n[Po],delete n[Qa],delete n[Ja])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function S1(e){return e.tag===5||e.tag===3||e.tag===4}function Zi(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||S1(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zo(e,n,t){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?t.nodeType===8?t.parentNode.insertBefore(e,n):t.insertBefore(e,n):(t.nodeType===8?(n=t.parentNode,n.insertBefore(e,t)):(n=t,n.appendChild(e)),t=t._reactRootContainer,t!=null||n.onclick!==null||(n.onclick=qr));else if(r!==4&&(e=e.child,e!==null))for(Zo(e,n,t),e=e.sibling;e!==null;)Zo(e,n,t),e=e.sibling}function ko(e,n,t){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?t.insertBefore(e,n):t.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(ko(e,n,t),e=e.sibling;e!==null;)ko(e,n,t),e=e.sibling}var _=null,Oe=!1;function Ke(e,n,t){for(t=t.child;t!==null;)U1(e,n,t),t=t.sibling}function U1(e,n,t){if(Le&&typeof Le.onCommitFiberUnmount=="function")try{Le.onCommitFiberUnmount(nl,t)}catch{}switch(t.tag){case 5:re||Rn(t,n);case 6:var r=_,l=Oe;_=null,Ke(e,n,t),_=r,Oe=l,_!==null&&(Oe?(e=_,t=t.stateNode,e.nodeType===8?e.parentNode.removeChild(t):e.removeChild(t)):_.removeChild(t.stateNode));break;case 18:_!==null&&(Oe?(e=_,t=t.stateNode,e.nodeType===8?Tl(e.parentNode,t):e.nodeType===1&&Tl(e,t),Vt(e)):Tl(_,t.stateNode));break;case 4:r=_,l=Oe,_=t.stateNode.containerInfo,Oe=!0,Ke(e,n,t),_=r,Oe=l;break;case 0:case 11:case 14:case 15:if(!re&&(r=t.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){l=r=r.next;do{var o=l,u=o.destroy;o=o.tag,u!==void 0&&(o&2||o&4)&&Do(t,n,u),l=l.next}while(l!==r)}Ke(e,n,t);break;case 1:if(!re&&(Rn(t,n),r=t.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=t.memoizedProps,r.state=t.memoizedState,r.componentWillUnmount()}catch(i){E(t,n,i)}Ke(e,n,t);break;case 21:Ke(e,n,t);break;case 22:t.mode&1?(re=(r=re)||t.memoizedState!==null,Ke(e,n,t),re=r):Ke(e,n,t);break;default:Ke(e,n,t)}}function ki(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var t=e.stateNode;t===null&&(t=e.stateNode=new v2),n.forEach(function(r){var l=z2.bind(null,e,r);t.has(r)||(t.add(r),r.then(l,l))})}}function Ge(e,n){var t=n.deletions;if(t!==null)for(var r=0;rl&&(l=u),r&=~o}if(r=l,r=B()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*m2(r/1960))-r,10e?16:e,nn===null)var r=!1;else{if(e=nn,nn=null,Jr=0,Z&6)throw Error(x(331));var l=Z;for(Z|=4,w=e.current;w!==null;){var o=w,u=o.child;if(w.flags&16){var i=o.deletions;if(i!==null){for(var s=0;sB()-zu?zn(e,0):wu|=t),ve(e,n)}function K1(e,n){n===0&&(e.mode&1?(n=ur,ur<<=1,!(ur&130023424)&&(ur=4194304)):n=1);var t=ue();e=be(e,n),e!==null&&(Kt(e,n,t),ve(e,t))}function w2(e){var n=e.memoizedState,t=0;n!==null&&(t=n.retryLane),K1(e,t)}function z2(e,n){var t=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;l!==null&&(t=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(x(314))}r!==null&&r.delete(n),K1(e,t)}var Q1;Q1=function(e,n,t){if(e!==null)if(e.memoizedProps!==n.pendingProps||ce.current)ae=!0;else{if(!(e.lanes&t)&&!(n.flags&128))return ae=!1,a2(e,n,t);ae=!!(e.flags&131072)}else ae=!1,q&&n.flags&1048576&&e1(n,Er,n.index);switch(n.lanes=0,n.tag){case 2:var r=n.type;Mr(e,n),e=n.pendingProps;var l=_n(n,le.current);Kn(n,t),l=mu(null,n,r,e,l,t);var o=Pu();return n.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,de(r)?(o=!0,Sr(n)):o=!1,n.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,cu(n),l.updater=sl,n.stateNode=l,l._reactInternals=n,zo(n,r,e,t),n=Mo(null,n,r,!0,o,t)):(n.tag=0,q&&o&&lu(n),oe(null,n,l,t),n=n.child),n;case 16:r=n.elementType;e:{switch(Mr(e,n),e=n.pendingProps,l=r._init,r=l(r._payload),n.type=r,l=n.tag=X2(r),e=Ye(r,e),l){case 0:n=Xo(null,n,r,e,t);break e;case 1:n=Yi(null,n,r,e,t);break e;case 11:n=Mi(null,n,r,e,t);break e;case 14:n=Gi(null,n,r,Ye(r.type,e),t);break e}throw Error(x(306,r,""))}return n;case 0:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:Ye(r,l),Xo(e,n,r,l,t);case 1:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:Ye(r,l),Yi(e,n,r,l,t);case 3:e:{if(k1(n),e===null)throw Error(x(387));r=n.pendingProps,o=n.memoizedState,l=o.element,u1(e,n),Br(n,r,null,t);var u=n.memoizedState;if(r=u.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:u.cache,pendingSuspenseBoundaries:u.pendingSuspenseBoundaries,transitions:u.transitions},n.updateQueue.baseState=o,n.memoizedState=o,n.flags&256){l=tt(Error(x(423)),n),n=Oi(e,n,r,t,l);break e}else if(r!==l){l=tt(Error(x(424)),n),n=Oi(e,n,r,t,l);break e}else for(he=on(n.stateNode.containerInfo.firstChild),me=n,q=!0,De=null,t=l1(n,null,r,t),n.child=t;t;)t.flags=t.flags&-3|4096,t=t.sibling;else{if($n(),r===l){n=Ae(e,n,t);break e}oe(e,n,r,t)}n=n.child}return n;case 5:return i1(n),e===null&&jo(n),r=n.type,l=n.pendingProps,o=e!==null?e.memoizedProps:null,u=l.children,ho(r,l)?u=null:o!==null&&ho(r,o)&&(n.flags|=32),Z1(e,n),oe(e,n,u,t),n.child;case 6:return e===null&&jo(n),null;case 13:return N1(e,n,t);case 4:return du(n,n.stateNode.containerInfo),r=n.pendingProps,e===null?n.child=et(n,null,r,t):oe(e,n,r,t),n.child;case 11:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:Ye(r,l),Mi(e,n,r,l,t);case 7:return oe(e,n,n.pendingProps,t),n.child;case 8:return oe(e,n,n.pendingProps.children,t),n.child;case 12:return oe(e,n,n.pendingProps.children,t),n.child;case 10:e:{if(r=n.type._context,l=n.pendingProps,o=n.memoizedProps,u=l.value,N(Rr,r._currentValue),r._currentValue=u,o!==null)if(ke(o.value,u)){if(o.children===l.children&&!ce.current){n=Ae(e,n,t);break e}}else for(o=n.child,o!==null&&(o.return=n);o!==null;){var i=o.dependencies;if(i!==null){u=o.child;for(var s=i.firstContext;s!==null;){if(s.context===r){if(o.tag===1){s=Re(-1,t&-t),s.tag=2;var a=o.updateQueue;if(a!==null){a=a.shared;var m=a.pending;m===null?s.next=s:(s.next=m.next,m.next=s),a.pending=s}}o.lanes|=t,s=o.alternate,s!==null&&(s.lanes|=t),go(o.return,t,n),i.lanes|=t;break}s=s.next}}else if(o.tag===10)u=o.type===n.type?null:o.child;else if(o.tag===18){if(u=o.return,u===null)throw Error(x(341));u.lanes|=t,i=u.alternate,i!==null&&(i.lanes|=t),go(u,t,n),u=o.sibling}else u=o.child;if(u!==null)u.return=o;else for(u=o;u!==null;){if(u===n){u=null;break}if(o=u.sibling,o!==null){o.return=u.return,u=o;break}u=u.return}o=u}oe(e,n,l.children,t),n=n.child}return n;case 9:return l=n.type,r=n.pendingProps.children,Kn(n,t),l=He(l),r=r(l),n.flags|=1,oe(e,n,r,t),n.child;case 14:return r=n.type,l=Ye(r,n.pendingProps),l=Ye(r.type,l),Gi(e,n,r,l,t);case 15:return D1(e,n,n.type,n.pendingProps,t);case 17:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:Ye(r,l),Mr(e,n),n.tag=1,de(r)?(e=!0,Sr(n)):e=!1,Kn(n,t),G1(n,r,l),zo(n,r,l,t),Mo(null,n,r,!0,e,t);case 19:return T1(e,n,t);case 22:return C1(e,n,t)}throw Error(x(156,n.tag))};function J1(e,n){return Hs(e,n)}function H2(e,n,t,r){this.tag=e,this.key=t,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function we(e,n,t,r){return new H2(e,n,t,r)}function Gu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function X2(e){if(typeof e=="function")return Gu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===bo)return 11;if(e===Ao)return 14}return 2}function an(e,n){var t=e.alternate;return t===null?(t=we(e.tag,n,e.key,e.mode),t.elementType=e.elementType,t.type=e.type,t.stateNode=e.stateNode,t.alternate=e,e.alternate=t):(t.pendingProps=n,t.type=e.type,t.flags=0,t.subtreeFlags=0,t.deletions=null),t.flags=e.flags&14680064,t.childLanes=e.childLanes,t.lanes=e.lanes,t.child=e.child,t.memoizedProps=e.memoizedProps,t.memoizedState=e.memoizedState,t.updateQueue=e.updateQueue,n=e.dependencies,t.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},t.sibling=e.sibling,t.index=e.index,t.ref=e.ref,t}function Or(e,n,t,r,l,o){var u=2;if(r=e,typeof e=="function")Gu(e)&&(u=1);else if(typeof e=="string")u=5;else e:switch(e){case Nn:return Hn(t.children,l,o,n);case Bo:u=8,l|=8;break;case bl:return e=we(12,t,n,l|2),e.elementType=bl,e.lanes=o,e;case Al:return e=we(13,t,n,l),e.elementType=Al,e.lanes=o,e;case Il:return e=we(19,t,n,l),e.elementType=Il,e.lanes=o,e;case is:return cl(t,l,o,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case os:u=10;break e;case us:u=9;break e;case bo:u=11;break e;case Ao:u=14;break e;case Qe:u=16,r=null;break e}throw Error(x(130,e==null?e:typeof e,""))}return n=we(u,t,n,l),n.elementType=e,n.type=r,n.lanes=o,n}function Hn(e,n,t,r){return e=we(7,e,r,n),e.lanes=t,e}function cl(e,n,t,r){return e=we(22,e,r,n),e.elementType=is,e.lanes=t,e.stateNode={isHidden:!1},e}function Rl(e,n,t){return e=we(6,e,null,n),e.lanes=t,e}function Fl(e,n,t){return n=we(4,e.children!==null?e.children:[],e.key,n),n.lanes=t,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function M2(e,n,t,r,l){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Hl(0),this.expirationTimes=Hl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Hl(0),this.identifierPrefix=r,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function Yu(e,n,t,r,l,o,u,i,s){return e=new M2(e,n,t,i,s),n===1?(n=1,o===!0&&(n|=8)):n=0,o=we(3,null,null,n),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:t,cache:null,transitions:null,pendingSuspenseBoundaries:null},cu(o),e}function G2(e,n,t){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(nf)}catch(e){console.error(e)}}nf(),ns.exports=xe;var Z2=ns.exports,tf,Ui=Z2;tf=Ui.createRoot,Ui.hydrateRoot;const k2=()=>{const[e,n]=Dt.useState({dotClass:"is-loading",statusMessage:"Checking status..."}),t="https://status.buildwithfern.com/api/v1/summary",r=5*60*1e3,l=i=>{let s="is-green",a="All systems operational";if(i.ongoing_incidents&&i.ongoing_incidents.length>0){let m=0;for(const h of i.ongoing_incidents){let p=0;h.current_worst_impact==="degraded_performance"?p=1:h.current_worst_impact==="partial_outage"?p=2:h.current_worst_impact==="full_outage"&&(p=3),p>m&&(m=p)}m===3?(s="is-red",a="Service outage"):m===2?(s="is-orange",a="Partial outage"):m===1&&(s="is-yellow",a="Degraded performance")}if(i.in_progress_maintenances&&i.in_progress_maintenances.length>0&&s==="is-green"&&(s="is-blue",a="Maintenance in progress"),i.scheduled_maintenances&&i.scheduled_maintenances.length>0&&s==="is-green"){const m=new Date;let h=!1;for(const p of i.scheduled_maintenances)if((new Date(p.starts_at).getTime()-m.getTime())/(1e3*60*60)<=24){h=!0;break}h&&(s="is-blue",a="Scheduled maintenance soon")}n({dotClass:s,statusMessage:a})},o=async()=>{try{const i=await fetch(t);if(i.ok){const s=await i.json();l(s)}else n({dotClass:"is-red",statusMessage:"Cannot check status"})}catch(i){console.error("Error fetching status:",i),n({dotClass:"is-red",statusMessage:"Cannot check status"})}};Dt.useEffect(()=>{o();const i=setInterval(o,r);return()=>clearInterval(i)},[]);const u=()=>{switch(e.dotClass){case"is-green":return"#00c853";case"is-red":return"#f44336";case"is-orange":return"#ff9800";case"is-blue":return"#2196f3";case"is-yellow":return"#ffc107";case"is-loading":return"#cccccc";default:return"#cccccc"}};return d.jsx("a",{href:"https://status.buildwithfern.com",target:"_blank",rel:"noopener noreferrer",style:{textDecoration:"none",color:"inherit"},children:d.jsxs("div",{id:"fern-status-widget",className:"fern-status-widget",children:[d.jsx("div",{className:`footer_badge-dot ${e.dotClass}`,style:{width:"10px",height:"10px",borderRadius:"50%",marginRight:"8px",position:"relative",display:"inline-block",backgroundColor:u()}}),d.jsx("span",{id:"fern-status-text",className:"fern-status-text",children:e.statusMessage}),d.jsx("style",{children:` .fern-status-widget { display: flex; align-items: center; @@ -93,7 +93,14 @@ Error generating stack: `+o.message+` 0% { transform: scale(0.6); opacity: 0.5; } 100% { transform: scale(1.5); opacity: 0; } } - `})]})})},N2=({width:e=145,height:t=16,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 145 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("path",{d:"M9.79656 4.8H14.5006C15.5139 4.8 16.3192 5.05067 16.9166 5.552C17.5139 6.04267 17.8126 6.71467 17.8126 7.568C17.8126 8.112 17.6739 8.608 17.3966 9.056C17.1192 9.504 16.7512 9.84 16.2926 10.064C16.8579 10.2667 17.3059 10.608 17.6366 11.088C17.9672 11.5573 18.1326 12.1173 18.1326 12.768C18.1326 13.7387 17.8286 14.5227 17.2206 15.12C16.6126 15.7067 15.7752 16 14.7086 16H9.79656V4.8ZM14.4846 14.528C15.1246 14.528 15.6206 14.3627 15.9726 14.032C16.3246 13.7013 16.5006 13.2373 16.5006 12.64C16.5006 12.0427 16.3246 11.5893 15.9726 11.28C15.6312 10.96 15.1352 10.8 14.4846 10.8H11.3966V14.528H14.4846ZM14.2766 9.424C14.8846 9.424 15.3539 9.28533 15.6846 9.008C16.0152 8.72 16.1806 8.32533 16.1806 7.824C16.1806 7.32267 16.0152 6.93867 15.6846 6.672C15.3539 6.40533 14.8846 6.272 14.2766 6.272H11.3966V9.424H14.2766ZM22.5778 16.224C21.6285 16.224 20.8871 15.9413 20.3538 15.376C19.8205 14.8107 19.5538 14 19.5538 12.944V8.304H21.1058V12.8C21.1058 13.472 21.2551 13.9787 21.5538 14.32C21.8631 14.6507 22.3005 14.816 22.8658 14.816C23.4525 14.816 23.9165 14.6293 24.2578 14.256C24.6098 13.872 24.7858 13.3707 24.7858 12.752V8.304H26.3378V16H24.9618V15.12C24.7165 15.4827 24.3858 15.76 23.9698 15.952C23.5538 16.1333 23.0898 16.224 22.5778 16.224ZM28.0746 8.304H29.6266V16H28.0746V8.304ZM27.9786 4.912H29.7066V6.752H27.9786V4.912ZM33.0334 16C32.4894 16 32.0948 15.888 31.8494 15.664C31.6041 15.44 31.4814 15.0667 31.4814 14.544V4.8H33.0334V14.064C33.0334 14.2667 33.0761 14.416 33.1614 14.512C33.2468 14.5973 33.3854 14.64 33.5774 14.64H34.5534V16H33.0334ZM37.9539 16C37.2819 16 36.7966 15.856 36.4979 15.568C36.1993 15.28 36.0499 14.8053 36.0499 14.144V9.664H34.0339V8.304H36.0499V6H37.6019V8.304H40.0179V9.664H37.6019V13.84C37.6019 14.1173 37.6659 14.32 37.7939 14.448C37.9219 14.576 38.1299 14.64 38.4179 14.64H40.0179V16H37.9539ZM43.5709 8.304H45.1869L46.8989 14.272L48.6109 8.304H50.3869L52.0989 14.272L53.8109 8.304H55.4269L53.0429 16H51.2189L49.5069 10.064L47.7789 16H45.9549L43.5709 8.304ZM56.3746 8.304H57.9266V16H56.3746V8.304ZM56.2786 4.912H58.0066V6.752H56.2786V4.912ZM62.5971 16C61.9251 16 61.4397 15.856 61.1411 15.568C60.8424 15.28 60.6931 14.8053 60.6931 14.144V9.664H58.6771V8.304H60.6931V6H62.2451V8.304H64.6611V9.664H62.2451V13.84C62.2451 14.1173 62.3091 14.32 62.4371 14.448C62.5651 14.576 62.7731 14.64 63.0611 14.64H64.6611V16H62.5971ZM65.6727 4.8H67.2247V9.056C67.4807 8.736 67.8007 8.496 68.1847 8.336C68.5794 8.16533 69.0114 8.08 69.4807 8.08C70.4407 8.08 71.1927 8.368 71.7367 8.944C72.2807 9.50933 72.5527 10.3147 72.5527 11.36V16H71.0007V11.504C71.0007 10.832 70.8407 10.3307 70.5207 10C70.2114 9.65867 69.7687 9.488 69.1927 9.488C68.5954 9.488 68.1154 9.68 67.7527 10.064C67.4007 10.4373 67.2247 10.9333 67.2247 11.552V16H65.6727V4.8Z",fill:"#1E1F24"}),f.jsx("path",{d:"M92.3849 7.82856C91.3321 6.93847 89.746 6.58166 88.3403 7.62074C88.2756 7.66779 88.1952 7.58741 88.2442 7.52468C88.5775 7.09532 88.9638 6.63263 89.2755 6.16798C89.5931 5.69157 90.0675 5.35044 90.6145 5.18379C93.5259 4.30155 92.6515 0.00012207 92.6515 0.00012207C92.6515 0.00012207 88.154 0.290282 88.7089 4.17019C88.801 4.81913 88.6285 5.47983 88.2227 5.99545C87.7247 6.62479 87.1463 7.22667 86.7268 7.66191C86.6385 7.7521 86.4895 7.66583 86.5248 7.54428C86.9307 6.17778 87.2267 4.06432 85.821 2.70175L83.8428 1.05881L83.4625 1.56071C82.3312 3.05268 82.6626 5.15634 84.1565 6.28561C85.0132 6.93259 85.4014 7.63643 85.3407 8.40888C85.3034 8.87157 85.0936 9.30485 84.7799 9.64794C84.1898 10.2949 83.6389 10.9889 83.2135 11.7928C83.1546 11.9045 82.9841 11.8614 82.99 11.734C83.0507 10.4067 82.9233 7.41489 80.6883 6.34639L78.1866 5.37984L77.9925 5.9582C77.3632 7.82464 78.3925 9.81851 80.257 10.4518C81.8783 11.0027 82.4567 12.0476 82.0665 13.6141C82.0489 13.671 81.7666 15.2845 81.8058 16.0001H83.6036C83.6644 14.8904 84.829 14.1611 85.8386 14.614C86.1229 14.7414 86.415 14.9238 86.715 15.159C88.3227 16.4255 90.691 16.1256 91.9555 14.516L92.3163 14.0572L90.0421 12.4241C88.4815 11.1968 86.3994 11.7516 84.8584 12.8024C84.729 12.8907 84.5643 12.7495 84.6368 12.6084C86.4993 8.95391 88.9206 8.96175 89.8695 9.77341C91.0204 10.7576 92.7633 10.5812 93.7396 9.4264L94.02 9.09507L92.3829 7.82856H92.3849Z",fill:"#51C233"}),f.jsx("path",{d:"M111.257 4.27539C114.524 4.27557 116.739 6.46855 116.739 9.98145C116.739 10.3833 116.718 10.788 116.673 11.2568H108.84C108.974 12.6434 109.892 13.4053 111.391 13.4053C112.398 13.4052 113.045 12.9803 113.338 12.375H116.538C115.888 14.5682 114.189 16 111.37 16C107.991 15.9998 105.754 13.6502 105.754 10.0703H105.751C105.751 6.55739 107.99 4.27539 111.257 4.27539ZM132.095 4.27539C134.801 4.2756 136.503 6.02159 136.503 8.95117V15.665H133.369V9.28613C133.369 7.81028 132.697 7.09379 131.444 7.09375C130.192 7.09375 129.362 7.96679 129.362 9.37598V15.6621H126.23V4.61035H128.984V5.72852C129.634 4.76615 130.82 4.27539 132.095 4.27539ZM106.379 2.72949H103.313C102.663 2.72949 102.305 2.99745 102.305 3.64746V4.60938H105.706V7.33887H102.305V15.6621H99.171V7.33887H96.42V4.60938H99.171V3.26758C99.171 1.11907 100.402 0 102.528 0H106.379V2.72949ZM120.583 6.55371C120.851 5.30087 121.747 4.60645 123.156 4.60645H125.126V4.98535C125.126 6.28287 124.074 7.33493 122.776 7.33496C121.546 7.33496 120.963 7.96297 120.963 9.21582V15.6611H117.829V4.60645H120.583V6.55371ZM111.257 6.73633C109.736 6.73633 108.907 7.58722 108.818 8.88477H113.584V8.83984C113.584 7.58713 112.778 6.73647 111.257 6.73633Z",fill:"#1E1F24"})]}),T2=({width:e=145,height:t=16,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 145 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("path",{d:"M9.79656 4.8H14.5006C15.5139 4.8 16.3192 5.05067 16.9166 5.552C17.5139 6.04267 17.8126 6.71467 17.8126 7.568C17.8126 8.112 17.6739 8.608 17.3966 9.056C17.1192 9.504 16.7512 9.84 16.2926 10.064C16.8579 10.2667 17.3059 10.608 17.6366 11.088C17.9672 11.5573 18.1326 12.1173 18.1326 12.768C18.1326 13.7387 17.8286 14.5227 17.2206 15.12C16.6126 15.7067 15.7752 16 14.7086 16H9.79656V4.8ZM14.4846 14.528C15.1246 14.528 15.6206 14.3627 15.9726 14.032C16.3246 13.7013 16.5006 13.2373 16.5006 12.64C16.5006 12.0427 16.3246 11.5893 15.9726 11.28C15.6312 10.96 15.1352 10.8 14.4846 10.8H11.3966V14.528H14.4846ZM14.2766 9.424C14.8846 9.424 15.3539 9.28533 15.6846 9.008C16.0152 8.72 16.1806 8.32533 16.1806 7.824C16.1806 7.32267 16.0152 6.93867 15.6846 6.672C15.3539 6.40533 14.8846 6.272 14.2766 6.272H11.3966V9.424H14.2766ZM22.5778 16.224C21.6285 16.224 20.8871 15.9413 20.3538 15.376C19.8205 14.8107 19.5538 14 19.5538 12.944V8.304H21.1058V12.8C21.1058 13.472 21.2551 13.9787 21.5538 14.32C21.8631 14.6507 22.3005 14.816 22.8658 14.816C23.4525 14.816 23.9165 14.6293 24.2578 14.256C24.6098 13.872 24.7858 13.3707 24.7858 12.752V8.304H26.3378V16H24.9618V15.12C24.7165 15.4827 24.3858 15.76 23.9698 15.952C23.5538 16.1333 23.0898 16.224 22.5778 16.224ZM28.0746 8.304H29.6266V16H28.0746V8.304ZM27.9786 4.912H29.7066V6.752H27.9786V4.912ZM33.0334 16C32.4894 16 32.0948 15.888 31.8494 15.664C31.6041 15.44 31.4814 15.0667 31.4814 14.544V4.8H33.0334V14.064C33.0334 14.2667 33.0761 14.416 33.1614 14.512C33.2468 14.5973 33.3854 14.64 33.5774 14.64H34.5534V16H33.0334ZM37.9539 16C37.2819 16 36.7966 15.856 36.4979 15.568C36.1993 15.28 36.0499 14.8053 36.0499 14.144V9.664H34.0339V8.304H36.0499V6H37.6019V8.304H40.0179V9.664H37.6019V13.84C37.6019 14.1173 37.6659 14.32 37.7939 14.448C37.9219 14.576 38.1299 14.64 38.4179 14.64H40.0179V16H37.9539ZM43.5709 8.304H45.1869L46.8989 14.272L48.6109 8.304H50.3869L52.0989 14.272L53.8109 8.304H55.4269L53.0429 16H51.2189L49.5069 10.064L47.7789 16H45.9549L43.5709 8.304ZM56.3746 8.304H57.9266V16H56.3746V8.304ZM56.2786 4.912H58.0066V6.752H56.2786V4.912ZM62.5971 16C61.9251 16 61.4397 15.856 61.1411 15.568C60.8424 15.28 60.6931 14.8053 60.6931 14.144V9.664H58.6771V8.304H60.6931V6H62.2451V8.304H64.6611V9.664H62.2451V13.84C62.2451 14.1173 62.3091 14.32 62.4371 14.448C62.5651 14.576 62.7731 14.64 63.0611 14.64H64.6611V16H62.5971ZM65.6727 4.8H67.2247V9.056C67.4807 8.736 67.8007 8.496 68.1847 8.336C68.5794 8.16533 69.0114 8.08 69.4807 8.08C70.4407 8.08 71.1927 8.368 71.7367 8.944C72.2807 9.50933 72.5527 10.3147 72.5527 11.36V16H71.0007V11.504C71.0007 10.832 70.8407 10.3307 70.5207 10C70.2114 9.65867 69.7687 9.488 69.1927 9.488C68.5954 9.488 68.1154 9.68 67.7527 10.064C67.4007 10.4373 67.2247 10.9333 67.2247 11.552V16H65.6727V4.8Z",fill:"#EEEEF0"}),f.jsx("path",{d:"M92.3848 7.82856C91.332 6.93847 89.7459 6.58166 88.3402 7.62074C88.2755 7.66779 88.1952 7.58741 88.2442 7.52468C88.5775 7.09532 88.9637 6.63263 89.2754 6.16798C89.593 5.69157 90.0675 5.35044 90.6145 5.18379C93.5259 4.30155 92.6515 0.00012207 92.6515 0.00012207C92.6515 0.00012207 88.154 0.290282 88.7088 4.17019C88.801 4.81913 88.6284 5.47983 88.2226 5.99545C87.7246 6.62479 87.1463 7.22667 86.7267 7.66191C86.6385 7.7521 86.4895 7.66583 86.5248 7.54428C86.9306 6.17778 87.2266 4.06432 85.8209 2.70175L83.8427 1.05881L83.4624 1.56071C82.3312 3.05268 82.6625 5.15634 84.1564 6.28561C85.0132 6.93259 85.4014 7.63643 85.3406 8.40888C85.3033 8.87157 85.0936 9.30485 84.7799 9.64794C84.1898 10.2949 83.6388 10.9889 83.2134 11.7928C83.1546 11.9045 82.984 11.8614 82.9899 11.734C83.0507 10.4067 82.9232 7.41489 80.6882 6.34639L78.1866 5.37984L77.9925 5.9582C77.3631 7.82464 78.3924 9.81851 80.2569 10.4518C81.8783 11.0027 82.4566 12.0476 82.0665 13.6141C82.0488 13.671 81.7665 15.2845 81.8057 16.0001H83.6036C83.6643 14.8904 84.8289 14.1611 85.8386 14.614C86.1229 14.7414 86.415 14.9238 86.7149 15.159C88.3226 16.4255 90.6909 16.1256 91.9555 14.516L92.3162 14.0572L90.042 12.4241C88.4814 11.1968 86.3993 11.7516 84.8583 12.8024C84.7289 12.8907 84.5642 12.7495 84.6368 12.6084C86.4993 8.95391 88.9206 8.96175 89.8695 9.77341C91.0203 10.7576 92.7632 10.5812 93.7396 9.4264L94.0199 9.09507L92.3829 7.82856H92.3848Z",fill:"#51C233"}),f.jsx("path",{d:"M111.257 4.27539C114.524 4.27557 116.739 6.46855 116.739 9.98145C116.739 10.3833 116.718 10.788 116.673 11.2568H108.84C108.974 12.6434 109.892 13.4053 111.391 13.4053C112.398 13.4052 113.045 12.9803 113.338 12.375H116.538C115.888 14.5682 114.189 16 111.37 16C107.991 15.9998 105.754 13.6502 105.754 10.0703H105.751C105.751 6.55739 107.989 4.27539 111.257 4.27539ZM132.095 4.27539C134.801 4.2756 136.503 6.02159 136.503 8.95117V15.665H133.369V9.28613C133.369 7.81028 132.697 7.09379 131.444 7.09375C130.191 7.09375 129.362 7.96679 129.362 9.37598V15.6621H126.229V4.61035H128.983V5.72852C129.633 4.76615 130.82 4.27539 132.095 4.27539ZM106.379 2.72949H103.312C102.662 2.72949 102.305 2.99745 102.305 3.64746V4.60938H105.706V7.33887H102.305V15.6621H99.1709V7.33887H96.4199V4.60938H99.1709V3.26758C99.1709 1.11907 100.402 0 102.528 0H106.379V2.72949ZM120.583 6.55371C120.851 5.30087 121.747 4.60645 123.156 4.60645H125.126V4.98535C125.126 6.28287 124.074 7.33493 122.776 7.33496C121.546 7.33496 120.963 7.96297 120.963 9.21582V15.6611H117.829V4.60645H120.583V6.55371ZM111.257 6.73633C109.736 6.73633 108.907 7.58722 108.817 8.88477H113.584V8.83984C113.584 7.58713 112.777 6.73647 111.257 6.73633Z",fill:"#EEEEF0"})]}),V2=({width:e=217,height:t=120,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 217 120",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("line",{x1:"32.5",y1:"2.18557e-08",x2:"32.5",y2:"120",stroke:"url(#paint0_linear_798_27733)"}),f.jsx("line",{x1:"177.5",y1:"2.18557e-08",x2:"177.5",y2:"120",stroke:"url(#paint1_linear_798_27733)"}),f.jsx("line",{x1:"217",y1:"48.5",y2:"48.5",stroke:"url(#paint2_linear_798_27733)"}),f.jsx("line",{x1:"217",y1:"80.5",y2:"80.5",stroke:"url(#paint3_linear_798_27733)"}),f.jsxs("defs",{children:[f.jsxs("linearGradient",{id:"paint0_linear_798_27733",x1:"31.5",y1:"-3.02609e-08",x2:"31.5",y2:"120",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white"}),f.jsx("stop",{offset:"0.401095",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"0.700547",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"1",stopColor:"white"})]}),f.jsxs("linearGradient",{id:"paint1_linear_798_27733",x1:"176.5",y1:"-3.02609e-08",x2:"176.5",y2:"120",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white"}),f.jsx("stop",{offset:"0.401095",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"0.700547",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"1",stopColor:"white"})]}),f.jsxs("linearGradient",{id:"paint2_linear_798_27733",x1:"217",y1:"47.5",x2:"1.52007e-08",y2:"47.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white"}),f.jsx("stop",{offset:"0.180986",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"0.849328",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"1",stopColor:"white"})]}),f.jsxs("linearGradient",{id:"paint3_linear_798_27733",x1:"217",y1:"79.5",x2:"1.52007e-08",y2:"79.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white"}),f.jsx("stop",{offset:"0.180986",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"0.849328",stopColor:"#E0E1E6"}),f.jsx("stop",{offset:"1",stopColor:"white"})]})]})]}),L2=({width:e=217,height:t=120,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 217 120",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("line",{x1:"32.5",y1:"2.18557e-08",x2:"32.5",y2:"120",stroke:"url(#paint0_linear_802_27906)"}),f.jsx("line",{x1:"177.5",y1:"2.18557e-08",x2:"177.5",y2:"120",stroke:"url(#paint1_linear_802_27906)"}),f.jsx("line",{x1:"217",y1:"48.5",y2:"48.5",stroke:"url(#paint2_linear_802_27906)"}),f.jsx("line",{x1:"217",y1:"80.5",y2:"80.5",stroke:"url(#paint3_linear_802_27906)"}),f.jsxs("defs",{children:[f.jsxs("linearGradient",{id:"paint0_linear_802_27906",x1:"31.5",y1:"-3.02609e-08",x2:"31.5",y2:"120",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopOpacity:"0"}),f.jsx("stop",{offset:"0.401743",stopColor:"#303136"}),f.jsx("stop",{offset:"0.672967",stopColor:"#303136"}),f.jsx("stop",{offset:"1",stopOpacity:"0"})]}),f.jsxs("linearGradient",{id:"paint1_linear_802_27906",x1:"176.5",y1:"-3.02609e-08",x2:"176.5",y2:"120",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopOpacity:"0"}),f.jsx("stop",{offset:"0.401743",stopColor:"#303136"}),f.jsx("stop",{offset:"0.672967",stopColor:"#303136"}),f.jsx("stop",{offset:"1",stopOpacity:"0"})]}),f.jsxs("linearGradient",{id:"paint2_linear_802_27906",x1:"217",y1:"47.5",x2:"1.52007e-08",y2:"47.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopOpacity:"0"}),f.jsx("stop",{offset:"0.181082",stopColor:"#303136"}),f.jsx("stop",{offset:"0.849629",stopColor:"#303136"}),f.jsx("stop",{offset:"1",stopOpacity:"0"})]}),f.jsxs("linearGradient",{id:"paint3_linear_802_27906",x1:"217",y1:"79.5",x2:"1.52007e-08",y2:"79.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopOpacity:"0"}),f.jsx("stop",{offset:"0.181082",stopColor:"#303136"}),f.jsx("stop",{offset:"0.849629",stopColor:"#303136"}),f.jsx("stop",{offset:"1",stopOpacity:"0"})]})]})]}),q2=({width:e=25,height:t=24,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("path",{d:"M14.27 17.8332V15.4998C14.3512 14.7691 14.1416 14.0357 13.6867 13.4582C15.4367 13.4582 17.1867 12.2915 17.1867 10.2498C17.2333 9.52067 17.0292 8.80317 16.6033 8.20817C16.7667 7.53734 16.7667 6.83734 16.6033 6.1665C16.6033 6.1665 16.02 6.1665 14.8533 7.0415C13.3133 6.74984 11.7267 6.74984 10.1867 7.0415C9.02002 6.1665 8.43668 6.1665 8.43668 6.1665C8.26168 6.83734 8.26168 7.53734 8.43668 8.20817C8.01194 8.80077 7.80579 9.5223 7.85335 10.2498C7.85335 12.2915 9.60335 13.4582 11.3533 13.4582C11.1258 13.744 10.9567 14.0707 10.8575 14.4207C10.7583 14.7707 10.7292 15.1382 10.77 15.4998V17.8332",stroke:"#62636C",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"}),f.jsx("path",{d:"M10.77 15.5002C8.13919 16.6668 7.85336 14.3335 6.68669 14.3335",stroke:"#62636C",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"})]}),W2=({width:e=24,height:t=24,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:[f.jsx("path",{d:"M13.75 17.8332V15.4998C13.8311 14.7691 13.6216 14.0357 13.1667 13.4582C14.9167 13.4582 16.6667 12.2915 16.6667 10.2498C16.7133 9.52067 16.5092 8.80317 16.0833 8.20817C16.2467 7.53734 16.2467 6.83734 16.0833 6.1665C16.0833 6.1665 15.5 6.1665 14.3333 7.0415C12.7933 6.74984 11.2067 6.74984 9.66666 7.0415C8.5 6.1665 7.91666 6.1665 7.91666 6.1665C7.74166 6.83734 7.74166 7.53734 7.91666 8.20817C7.49192 8.80077 7.28577 9.5223 7.33333 10.2498C7.33333 12.2915 9.08333 13.4582 10.8333 13.4582C10.6058 13.744 10.4367 14.0707 10.3375 14.4207C10.2383 14.7707 10.2092 15.1382 10.25 15.4998V17.8332",stroke:"#B2B3BD",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"}),f.jsx("path",{d:"M10.25 15.5002C7.61917 16.6668 7.33334 14.3335 6.16667 14.3335",stroke:"#B2B3BD",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"})]}),S2=({width:e=25,height:t=24,className:n=""})=>f.jsx("svg",{width:e,height:t,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:f.jsx("path",{d:"M15.9658 6.57812H17.7971L13.7971 11.1805L18.52 17.4215H14.8092L11.9176 13.6384L8.59231 17.4215H6.76098L11.0501 12.5058L6.52002 6.57812H10.3272L12.9538 10.048L15.9658 6.57812ZM15.3152 16.3131H16.3272L9.77303 7.61427H8.6646L15.3152 16.3131Z",fill:"#62636C"})}),U2=({width:e=24,height:t=24,className:n=""})=>f.jsx("svg",{width:e,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:f.jsx("path",{d:"M15.4458 6.57812H17.2771L13.2771 11.1805L18 17.4215H14.2892L11.3976 13.6384L8.07229 17.4215H6.24096L10.5301 12.5058L6 6.57812H9.80723L12.4337 10.048L15.4458 6.57812ZM14.7952 16.3131H15.8072L9.25301 7.61427H8.14458L14.7952 16.3131Z",fill:"#B2B3BD"})}),E2=({width:e=25,height:t=24,className:n=""})=>f.jsx("svg",{width:e,height:t,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:f.jsx("path",{d:"M16.0922 15.5369H14.5887V13.2056C14.5887 12.6497 14.5787 11.9341 13.8068 11.9341C13.0238 11.9341 12.9039 12.5398 12.9039 13.1652V15.5368H11.4005V10.7427H12.8438V11.3979H12.864C13.0084 11.1533 13.2172 10.9522 13.4679 10.8158C13.7187 10.6794 14.0021 10.613 14.2881 10.6235C15.8119 10.6235 16.0928 11.6159 16.0928 12.907L16.0922 15.5369ZM9.70411 10.0874C9.53155 10.0874 9.36285 10.0368 9.21936 9.94191C9.07587 9.84701 8.96402 9.71211 8.89796 9.55427C8.8319 9.39643 8.81458 9.22274 8.84822 9.05516C8.88185 8.88758 8.96492 8.73363 9.08692 8.6128C9.20891 8.49196 9.36436 8.40966 9.53359 8.37629C9.70283 8.34293 9.87825 8.36001 10.0377 8.42536C10.1971 8.49072 10.3334 8.60142 10.4293 8.74347C10.5252 8.88551 10.5764 9.05253 10.5764 9.22338C10.5764 9.33683 10.5539 9.44917 10.5101 9.55399C10.4662 9.6588 10.402 9.75405 10.321 9.83428C10.24 9.91451 10.1438 9.97816 10.038 10.0216C9.93213 10.065 9.81868 10.0874 9.70411 10.0874ZM10.4558 15.5369H8.95082V10.7427H10.4558V15.5369ZM16.8417 6.97725H8.19534C7.99909 6.97505 7.80999 7.0501 7.66959 7.18588C7.52919 7.32167 7.44899 7.50709 7.44659 7.70141V16.2981C7.44891 16.4925 7.52906 16.6781 7.66945 16.814C7.80985 16.95 7.999 17.0251 8.19534 17.0231H16.8417C17.0384 17.0255 17.2281 16.9505 17.3691 16.8146C17.51 16.6787 17.5907 16.4929 17.5934 16.2981V7.70079C17.5906 7.50609 17.5099 7.32045 17.3689 7.18467C17.228 7.04889 17.0384 6.97406 16.8417 6.97663",fill:"#62636C"})}),R2=({width:e=24,height:t=24,className:n=""})=>f.jsx("svg",{width:e,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:n,children:f.jsx("path",{d:"M15.5722 15.5369H14.0687V13.2056C14.0687 12.6497 14.0587 11.9341 13.2868 11.9341C12.5037 11.9341 12.3839 12.5398 12.3839 13.1652V15.5368H10.8805V10.7427H12.3238V11.3979H12.344C12.4884 11.1533 12.6971 10.9522 12.9479 10.8158C13.1987 10.6794 13.4821 10.613 13.768 10.6235C15.2918 10.6235 15.5728 11.6159 15.5728 12.907L15.5722 15.5369ZM9.18409 10.0874C9.01153 10.0874 8.84283 10.0368 8.69934 9.94191C8.55585 9.84701 8.444 9.71211 8.37794 9.55427C8.31188 9.39643 8.29456 9.22274 8.3282 9.05516C8.36183 8.88758 8.4449 8.73363 8.5669 8.6128C8.68889 8.49196 8.84434 8.40966 9.01357 8.37629C9.18281 8.34293 9.35823 8.36001 9.51767 8.42536C9.6771 8.49072 9.81338 8.60142 9.90927 8.74347C10.0052 8.88551 10.0564 9.05253 10.0564 9.22338C10.0564 9.33683 10.0339 9.44917 9.99005 9.55399C9.94622 9.6588 9.88198 9.75405 9.80097 9.83428C9.71997 9.91451 9.6238 9.97816 9.51795 10.0216C9.41211 10.065 9.29866 10.0874 9.18409 10.0874ZM9.93581 15.5369H8.4308V10.7427H9.93581V15.5369ZM16.3217 6.97725H7.67532C7.47907 6.97505 7.28997 7.0501 7.14957 7.18588C7.00917 7.32167 6.92897 7.50709 6.92657 7.70141V16.2981C6.92889 16.4925 7.00904 16.6781 7.14943 16.814C7.28983 16.95 7.47898 17.0251 7.67532 17.0231H16.3217C16.5184 17.0255 16.7081 16.9505 16.8491 16.8146C16.99 16.6787 17.0707 16.4929 17.0734 16.2981V7.70079C17.0706 7.50609 16.9899 7.32045 16.8489 7.18467C16.708 7.04889 16.5183 6.97406 16.3217 6.97663",fill:"#B2B3BD"})}),F2=({width:e=32,height:t=32,className:n=""})=>f.jsxs("svg",{width:e,height:t,viewBox:"0 0 512 512",fill:"none",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",className:n,children:[f.jsxs("g",{clipPath:"url(#clip0_2003_55)",children:[f.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"url(#paint0_linear_2003_55)"}),f.jsx("circle",{cx:"256",cy:"256",r:"254",stroke:"url(#paint1_linear_2003_55)",strokeWidth:"4"}),f.jsx("circle",{cx:"256",cy:"256",r:"190",fill:"url(#paint2_linear_2003_55)",stroke:"url(#paint3_linear_2003_55)",strokeWidth:"4"}),f.jsx("mask",{id:"mask0_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"512",height:"512",children:f.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"white"})}),f.jsxs("g",{mask:"url(#mask0_2003_55)",children:[f.jsx("g",{filter:"url(#filter1_f_2003_55)",children:f.jsx("path",{d:"M442.63 11.6267C456.09 -21.5565 482.511 -41.8116 494.038 -47.7913C504.996 -52.945 521.977 -48.4056 502.24 10.9816C477.567 85.2156 463.797 65.5975 429.79 128.38C395.783 191.162 419.879 133.733 389.781 165.003C359.684 196.273 358.947 200.432 321.716 243.16C284.484 285.889 283.25 280.639 314.634 230.674C346.019 180.709 342.823 181.221 389.886 117.112C436.95 53.0032 425.804 53.1058 442.63 11.6267Z",fill:"white",fillOpacity:"0.32"})}),f.jsx("g",{filter:"url(#filter2_f_2003_55)",children:f.jsx("path",{d:"M477.63 88.6267C491.09 55.4435 517.511 35.1884 529.038 29.2087C539.996 24.055 556.977 28.5944 537.24 87.9816C512.567 162.216 498.797 142.598 464.79 205.38C430.783 268.162 454.879 210.733 424.781 242.003C394.684 273.273 393.947 277.432 356.716 320.16C319.484 362.889 318.25 357.639 349.634 307.674C381.019 257.709 377.823 258.221 424.886 194.112C471.95 130.003 460.804 130.106 477.63 88.6267Z",fill:"white",fillOpacity:"0.32"})}),f.jsx("g",{filter:"url(#filter3_f_2003_55)",children:f.jsx("path",{d:"M231.094 -86.6032C233.2 -123.334 270.507 -143.191 288.898 -148.527C306.772 -152.983 343.73 -145.307 348.572 -78.957C354.625 3.98024 312.875 -20.7962 291.99 47.4952C271.106 115.787 276.336 52.3306 239.894 84.4911C203.452 116.652 205.069 121.389 162.981 165.883C120.893 210.377 114.569 204.091 139.738 150.35C164.908 96.6093 158.962 96.7553 204.701 28.7583C250.44 -39.2386 228.461 -40.6893 231.094 -86.6032Z",fill:"white",fillOpacity:"0.4"})}),f.jsx("g",{filter:"url(#filter4_f_2003_55)",children:f.jsx("path",{d:"M-107.305 324.646C-113.552 285.166 -50.49 273.785 -18.1783 273.029C13.4267 273.091 83.4284 291.641 110.595 365.337C144.553 457.457 61.0399 418.938 41.4844 487.666C21.9289 556.395 14.06 488.629 -44.0227 513.668C-102.105 538.707 -97.8309 544.319 -162.889 581.255C-227.947 618.19 -241.295 609.593 -209.861 557.914C-178.427 506.234 -189.308 504.756 -124.016 443.193C-58.7245 381.63 -99.4971 373.995 -107.305 324.646Z",fill:"white",fillOpacity:"0.24"})}),f.jsx("g",{filter:"url(#filter5_f_2003_55)",children:f.jsx("path",{d:"M579.63 213.627C593.09 180.444 619.511 160.188 631.038 154.209C641.996 149.055 658.977 153.594 639.24 212.982C614.567 287.216 600.797 267.598 566.79 330.38C532.783 393.162 556.879 335.733 526.781 367.003C496.684 398.273 495.947 402.432 458.716 445.16C421.484 487.889 420.25 482.639 451.634 432.674C483.019 382.709 479.823 383.221 526.886 319.112C573.95 255.003 562.804 255.106 579.63 213.627Z",fill:"white",fillOpacity:"0.32"})})]}),f.jsx("mask",{id:"mask1_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"512",height:"512",children:f.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"white"})}),f.jsxs("g",{mask:"url(#mask1_2003_55)",children:[f.jsxs("mask",{id:"mask2_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"9",y:"-46",width:"529",height:"525",children:[f.jsx("ellipse",{cx:"454.793",cy:"203.331",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 454.793 203.331)",fill:"#D9D9D9"}),f.jsx("ellipse",{cx:"270.793",cy:"35.3312",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 270.793 35.3312)",fill:"#D9D9D9"}),f.jsx("ellipse",{cx:"446.793",cy:"67.3312",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 446.793 67.3312)",fill:"#D9D9D9"}),f.jsx("ellipse",{cx:"80.2712",cy:"367.484",rx:"65.2671",ry:"76.7003",transform:"rotate(-44.2469 80.2712 367.484)",fill:"#D9D9D9"}),f.jsx("ellipse",{cx:"360.271",cy:"407.484",rx:"65.2671",ry:"76.7003",transform:"rotate(-44.2469 360.271 407.484)",fill:"#D9D9D9",fillOpacity:"0.24"}),f.jsx("ellipse",{cx:"133.311",cy:"150.002",rx:"118.371",ry:"76.7003",transform:"rotate(-44.2469 133.311 150.002)",fill:"#D9D9D9",fillOpacity:"0.12"})]}),f.jsx("g",{mask:"url(#mask2_2003_55)",children:f.jsx("rect",{x:"6",y:"6",width:"500",height:"500",fill:"url(#pattern0_2003_55)"})})]}),f.jsx("path",{d:"M195.456 161H191.024L203.842 126.091H208.206L221.024 161H216.592L206.161 131.614H205.888L195.456 161ZM197.092 147.364H214.956V151.114H197.092V147.364ZM230.689 126.091V161H226.462V126.091H230.689ZM267.256 137H263.028C262.778 135.784 262.341 134.716 261.716 133.795C261.102 132.875 260.352 132.102 259.466 131.477C258.591 130.841 257.619 130.364 256.551 130.045C255.483 129.727 254.369 129.568 253.21 129.568C251.097 129.568 249.182 130.102 247.466 131.17C245.761 132.239 244.403 133.812 243.392 135.892C242.392 137.972 241.892 140.523 241.892 143.545C241.892 146.568 242.392 149.119 243.392 151.199C244.403 153.278 245.761 154.852 247.466 155.92C249.182 156.989 251.097 157.523 253.21 157.523C254.369 157.523 255.483 157.364 256.551 157.045C257.619 156.727 258.591 156.256 259.466 155.631C260.352 154.994 261.102 154.216 261.716 153.295C262.341 152.364 262.778 151.295 263.028 150.091H267.256C266.938 151.875 266.358 153.472 265.517 154.881C264.676 156.29 263.631 157.489 262.381 158.477C261.131 159.455 259.727 160.199 258.17 160.71C256.625 161.222 254.972 161.477 253.21 161.477C250.233 161.477 247.585 160.75 245.267 159.295C242.949 157.841 241.125 155.773 239.795 153.091C238.466 150.409 237.801 147.227 237.801 143.545C237.801 139.864 238.466 136.682 239.795 134C241.125 131.318 242.949 129.25 245.267 127.795C247.585 126.341 250.233 125.614 253.21 125.614C254.972 125.614 256.625 125.869 258.17 126.381C259.727 126.892 261.131 127.642 262.381 128.631C263.631 129.608 264.676 130.801 265.517 132.21C266.358 133.608 266.938 135.205 267.256 137ZM274.087 161V126.091H285.882C288.621 126.091 290.859 126.585 292.598 127.574C294.348 128.551 295.643 129.875 296.484 131.545C297.325 133.216 297.746 135.08 297.746 137.136C297.746 139.193 297.325 141.062 296.484 142.744C295.655 144.426 294.371 145.767 292.632 146.767C290.893 147.756 288.666 148.25 285.95 148.25H277.496V144.5H285.814C287.689 144.5 289.195 144.176 290.331 143.528C291.467 142.881 292.291 142.006 292.803 140.903C293.325 139.79 293.587 138.534 293.587 137.136C293.587 135.739 293.325 134.489 292.803 133.386C292.291 132.284 291.462 131.42 290.314 130.795C289.166 130.159 287.643 129.841 285.746 129.841H278.314V161H274.087ZM302.425 161H297.993L310.811 126.091H315.175L327.993 161H323.561L313.129 131.614H312.857L302.425 161ZM304.061 147.364H321.925V151.114H304.061V147.364Z",fill:"white"}),f.jsx("line",{x1:"111.5",y1:"184",x2:"407.5",y2:"184",stroke:"url(#paint4_linear_2003_55)",strokeWidth:"2"}),f.jsx("path",{d:"M154.788 255.008C154.476 251.857 153.134 249.409 150.765 247.664C148.395 245.919 145.179 245.047 141.116 245.047C138.356 245.047 136.025 245.437 134.124 246.219C132.223 246.974 130.765 248.029 129.749 249.383C128.759 250.737 128.265 252.273 128.265 253.992C128.213 255.424 128.512 256.674 129.163 257.742C129.84 258.81 130.765 259.734 131.937 260.516C133.108 261.271 134.463 261.935 135.999 262.508C137.535 263.055 139.176 263.523 140.921 263.914L148.108 265.633C151.598 266.414 154.801 267.456 157.718 268.758C160.634 270.06 163.16 271.661 165.296 273.562C167.431 275.464 169.085 277.703 170.257 280.281C171.455 282.859 172.067 285.815 172.093 289.148C172.067 294.044 170.817 298.289 168.343 301.883C165.895 305.451 162.353 308.224 157.718 310.203C153.108 312.156 147.549 313.133 141.038 313.133C134.58 313.133 128.955 312.143 124.163 310.164C119.397 308.185 115.674 305.255 112.991 301.375C110.335 297.469 108.942 292.638 108.812 286.883H125.179C125.361 289.565 126.129 291.805 127.483 293.602C128.864 295.372 130.7 296.714 132.991 297.625C135.309 298.51 137.926 298.953 140.843 298.953C143.707 298.953 146.194 298.536 148.304 297.703C150.439 296.87 152.093 295.711 153.265 294.227C154.437 292.742 155.022 291.036 155.022 289.109C155.022 287.312 154.489 285.802 153.421 284.578C152.379 283.354 150.843 282.312 148.812 281.453C146.806 280.594 144.345 279.812 141.429 279.109L132.718 276.922C125.973 275.281 120.647 272.716 116.741 269.227C112.835 265.737 110.895 261.036 110.921 255.125C110.895 250.281 112.184 246.049 114.788 242.43C117.418 238.81 121.025 235.984 125.608 233.953C130.192 231.922 135.4 230.906 141.233 230.906C147.171 230.906 152.353 231.922 156.78 233.953C161.233 235.984 164.697 238.81 167.171 242.43C169.645 246.049 170.921 250.242 170.999 255.008H154.788ZM256.985 272C256.985 280.724 255.332 288.146 252.024 294.266C248.743 300.385 244.264 305.06 238.587 308.289C232.936 311.492 226.582 313.094 219.524 313.094C212.415 313.094 206.035 311.479 200.384 308.25C194.733 305.021 190.267 300.346 186.985 294.227C183.704 288.107 182.063 280.698 182.063 272C182.063 263.276 183.704 255.854 186.985 249.734C190.267 243.615 194.733 238.953 200.384 235.75C206.035 232.521 212.415 230.906 219.524 230.906C226.582 230.906 232.936 232.521 238.587 235.75C244.264 238.953 248.743 243.615 252.024 249.734C255.332 255.854 256.985 263.276 256.985 272ZM239.837 272C239.837 266.349 238.991 261.583 237.298 257.703C235.631 253.823 233.274 250.88 230.228 248.875C227.181 246.87 223.613 245.867 219.524 245.867C215.436 245.867 211.868 246.87 208.821 248.875C205.774 250.88 203.405 253.823 201.712 257.703C200.045 261.583 199.212 266.349 199.212 272C199.212 277.651 200.045 282.417 201.712 286.297C203.405 290.177 205.774 293.12 208.821 295.125C211.868 297.13 215.436 298.133 219.524 298.133C223.613 298.133 227.181 297.13 230.228 295.125C233.274 293.12 235.631 290.177 237.298 286.297C238.991 282.417 239.837 277.651 239.837 272ZM340.101 260.008H322.991C322.679 257.794 322.041 255.828 321.077 254.109C320.114 252.365 318.877 250.88 317.366 249.656C315.856 248.432 314.111 247.495 312.132 246.844C310.179 246.193 308.056 245.867 305.765 245.867C301.624 245.867 298.017 246.896 294.944 248.953C291.871 250.984 289.489 253.953 287.796 257.859C286.103 261.74 285.257 266.453 285.257 272C285.257 277.703 286.103 282.495 287.796 286.375C289.515 290.255 291.91 293.185 294.983 295.164C298.056 297.143 301.611 298.133 305.647 298.133C307.913 298.133 310.009 297.833 311.937 297.234C313.89 296.635 315.621 295.763 317.132 294.617C318.642 293.445 319.892 292.026 320.882 290.359C321.897 288.693 322.601 286.792 322.991 284.656L340.101 284.734C339.658 288.406 338.551 291.948 336.78 295.359C335.035 298.745 332.679 301.779 329.71 304.461C326.767 307.117 323.252 309.227 319.163 310.789C315.101 312.326 310.504 313.094 305.374 313.094C298.239 313.094 291.858 311.479 286.233 308.25C280.634 305.021 276.207 300.346 272.952 294.227C269.723 288.107 268.108 280.698 268.108 272C268.108 263.276 269.749 255.854 273.03 249.734C276.312 243.615 280.765 238.953 286.39 235.75C292.015 232.521 298.343 230.906 305.374 230.906C310.009 230.906 314.306 231.557 318.265 232.859C322.249 234.161 325.778 236.062 328.851 238.562C331.924 241.036 334.424 244.07 336.351 247.664C338.304 251.258 339.554 255.372 340.101 260.008ZM351.761 312V299.812L380.237 273.445C382.659 271.102 384.69 268.992 386.331 267.117C387.998 265.242 389.261 263.406 390.12 261.609C390.979 259.786 391.409 257.82 391.409 255.711C391.409 253.367 390.875 251.349 389.808 249.656C388.74 247.937 387.282 246.622 385.433 245.711C383.584 244.773 381.487 244.305 379.144 244.305C376.696 244.305 374.56 244.799 372.737 245.789C370.914 246.779 369.508 248.198 368.519 250.047C367.529 251.896 367.034 254.096 367.034 256.648H350.979C350.979 251.414 352.164 246.87 354.534 243.016C356.904 239.161 360.224 236.18 364.495 234.07C368.766 231.961 373.688 230.906 379.261 230.906C384.99 230.906 389.977 231.922 394.222 233.953C398.493 235.958 401.813 238.745 404.183 242.312C406.552 245.88 407.737 249.969 407.737 254.578C407.737 257.599 407.138 260.581 405.94 263.523C404.769 266.466 402.672 269.734 399.651 273.328C396.631 276.896 392.373 281.18 386.878 286.18L375.198 297.625V298.172H408.792V312H351.761Z",fill:"url(#paint5_linear_2003_55)"}),f.jsx("line",{x1:"111.5",y1:"358",x2:"407.5",y2:"358",stroke:"url(#paint6_linear_2003_55)",strokeWidth:"2"})]}),f.jsxs("defs",{children:[f.jsxs("filter",{id:"filter1_f_2003_55",x:"244.349",y:"-97.3701",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[f.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),f.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),f.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),f.jsxs("filter",{id:"filter2_f_2003_55",x:"279.349",y:"-20.3701",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[f.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),f.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),f.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),f.jsxs("filter",{id:"filter3_f_2003_55",x:"76.9136",y:"-197.559",width:"320.252",height:"440.967",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[f.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),f.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),f.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),f.jsxs("filter",{id:"filter4_f_2003_55",x:"-346.122",y:"153.028",width:"584.747",height:"570.864",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[f.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),f.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),f.jsx("feGaussianBlur",{stdDeviation:"60",result:"effect1_foregroundBlur_2003_55"})]}),f.jsxs("filter",{id:"filter5_f_2003_55",x:"381.349",y:"104.63",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[f.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),f.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),f.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),f.jsx("pattern",{id:"pattern0_2003_55",patternContentUnits:"objectBoundingBox",width:"0.8",height:"0.8",children:f.jsx("use",{xlinkHref:"#image0_2003_55",transform:"scale(0.001)"})}),f.jsxs("linearGradient",{id:"paint0_linear_2003_55",x1:"256",y1:"0",x2:"256",y2:"512",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0.2"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.02"})]}),f.jsxs("linearGradient",{id:"paint1_linear_2003_55",x1:"256",y1:"0",x2:"256",y2:"512",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0.64"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.12"})]}),f.jsxs("linearGradient",{id:"paint2_linear_2003_55",x1:"256",y1:"64",x2:"256",y2:"448",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.2"})]}),f.jsxs("linearGradient",{id:"paint3_linear_2003_55",x1:"256",y1:"64",x2:"256",y2:"448",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0.24"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.64"})]}),f.jsxs("linearGradient",{id:"paint4_linear_2003_55",x1:"111.5",y1:"185.5",x2:"407.5",y2:"185.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0"}),f.jsx("stop",{offset:"0.5",stopColor:"white"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0"})]}),f.jsxs("linearGradient",{id:"paint5_linear_2003_55",x1:"259.5",y1:"243.759",x2:"259.5",y2:"309.655",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{offset:"0.25",stopColor:"white"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.24"})]}),f.jsxs("linearGradient",{id:"paint6_linear_2003_55",x1:"111.5",y1:"359.5",x2:"407.5",y2:"359.5",gradientUnits:"userSpaceOnUse",children:[f.jsx("stop",{stopColor:"white",stopOpacity:"0"}),f.jsx("stop",{offset:"0.5",stopColor:"white"}),f.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0"})]}),f.jsx("clipPath",{id:"clip0_2003_55",children:f.jsx("rect",{width:"512",height:"512",fill:"white"})}),f.jsx("image",{id:"image0_2003_55",width:"800",height:"800",preserveAspectRatio:"none",xlinkHref:"data:image/png;base64,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"})]})]}),B2=()=>f.jsxs(f.Fragment,{children:[f.jsx("style",{children:` + + /* Responsive Design - Mobile */ + @media (max-width: 640px) { + .fern-status-widget { + padding-left: 0.5rem !important; + } + } + `})]})})},N2=({width:e=145,height:n=16,className:t=""})=>d.jsxs("svg",{width:e,height:n,viewBox:"0 0 145 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:[d.jsx("path",{d:"M9.79656 4.8H14.5006C15.5139 4.8 16.3192 5.05067 16.9166 5.552C17.5139 6.04267 17.8126 6.71467 17.8126 7.568C17.8126 8.112 17.6739 8.608 17.3966 9.056C17.1192 9.504 16.7512 9.84 16.2926 10.064C16.8579 10.2667 17.3059 10.608 17.6366 11.088C17.9672 11.5573 18.1326 12.1173 18.1326 12.768C18.1326 13.7387 17.8286 14.5227 17.2206 15.12C16.6126 15.7067 15.7752 16 14.7086 16H9.79656V4.8ZM14.4846 14.528C15.1246 14.528 15.6206 14.3627 15.9726 14.032C16.3246 13.7013 16.5006 13.2373 16.5006 12.64C16.5006 12.0427 16.3246 11.5893 15.9726 11.28C15.6312 10.96 15.1352 10.8 14.4846 10.8H11.3966V14.528H14.4846ZM14.2766 9.424C14.8846 9.424 15.3539 9.28533 15.6846 9.008C16.0152 8.72 16.1806 8.32533 16.1806 7.824C16.1806 7.32267 16.0152 6.93867 15.6846 6.672C15.3539 6.40533 14.8846 6.272 14.2766 6.272H11.3966V9.424H14.2766ZM22.5778 16.224C21.6285 16.224 20.8871 15.9413 20.3538 15.376C19.8205 14.8107 19.5538 14 19.5538 12.944V8.304H21.1058V12.8C21.1058 13.472 21.2551 13.9787 21.5538 14.32C21.8631 14.6507 22.3005 14.816 22.8658 14.816C23.4525 14.816 23.9165 14.6293 24.2578 14.256C24.6098 13.872 24.7858 13.3707 24.7858 12.752V8.304H26.3378V16H24.9618V15.12C24.7165 15.4827 24.3858 15.76 23.9698 15.952C23.5538 16.1333 23.0898 16.224 22.5778 16.224ZM28.0746 8.304H29.6266V16H28.0746V8.304ZM27.9786 4.912H29.7066V6.752H27.9786V4.912ZM33.0334 16C32.4894 16 32.0948 15.888 31.8494 15.664C31.6041 15.44 31.4814 15.0667 31.4814 14.544V4.8H33.0334V14.064C33.0334 14.2667 33.0761 14.416 33.1614 14.512C33.2468 14.5973 33.3854 14.64 33.5774 14.64H34.5534V16H33.0334ZM37.9539 16C37.2819 16 36.7966 15.856 36.4979 15.568C36.1993 15.28 36.0499 14.8053 36.0499 14.144V9.664H34.0339V8.304H36.0499V6H37.6019V8.304H40.0179V9.664H37.6019V13.84C37.6019 14.1173 37.6659 14.32 37.7939 14.448C37.9219 14.576 38.1299 14.64 38.4179 14.64H40.0179V16H37.9539ZM43.5709 8.304H45.1869L46.8989 14.272L48.6109 8.304H50.3869L52.0989 14.272L53.8109 8.304H55.4269L53.0429 16H51.2189L49.5069 10.064L47.7789 16H45.9549L43.5709 8.304ZM56.3746 8.304H57.9266V16H56.3746V8.304ZM56.2786 4.912H58.0066V6.752H56.2786V4.912ZM62.5971 16C61.9251 16 61.4397 15.856 61.1411 15.568C60.8424 15.28 60.6931 14.8053 60.6931 14.144V9.664H58.6771V8.304H60.6931V6H62.2451V8.304H64.6611V9.664H62.2451V13.84C62.2451 14.1173 62.3091 14.32 62.4371 14.448C62.5651 14.576 62.7731 14.64 63.0611 14.64H64.6611V16H62.5971ZM65.6727 4.8H67.2247V9.056C67.4807 8.736 67.8007 8.496 68.1847 8.336C68.5794 8.16533 69.0114 8.08 69.4807 8.08C70.4407 8.08 71.1927 8.368 71.7367 8.944C72.2807 9.50933 72.5527 10.3147 72.5527 11.36V16H71.0007V11.504C71.0007 10.832 70.8407 10.3307 70.5207 10C70.2114 9.65867 69.7687 9.488 69.1927 9.488C68.5954 9.488 68.1154 9.68 67.7527 10.064C67.4007 10.4373 67.2247 10.9333 67.2247 11.552V16H65.6727V4.8Z",fill:"#1E1F24"}),d.jsx("path",{d:"M92.3849 7.82856C91.3321 6.93847 89.746 6.58166 88.3403 7.62074C88.2756 7.66779 88.1952 7.58741 88.2442 7.52468C88.5775 7.09532 88.9638 6.63263 89.2755 6.16798C89.5931 5.69157 90.0675 5.35044 90.6145 5.18379C93.5259 4.30155 92.6515 0.00012207 92.6515 0.00012207C92.6515 0.00012207 88.154 0.290282 88.7089 4.17019C88.801 4.81913 88.6285 5.47983 88.2227 5.99545C87.7247 6.62479 87.1463 7.22667 86.7268 7.66191C86.6385 7.7521 86.4895 7.66583 86.5248 7.54428C86.9307 6.17778 87.2267 4.06432 85.821 2.70175L83.8428 1.05881L83.4625 1.56071C82.3312 3.05268 82.6626 5.15634 84.1565 6.28561C85.0132 6.93259 85.4014 7.63643 85.3407 8.40888C85.3034 8.87157 85.0936 9.30485 84.7799 9.64794C84.1898 10.2949 83.6389 10.9889 83.2135 11.7928C83.1546 11.9045 82.9841 11.8614 82.99 11.734C83.0507 10.4067 82.9233 7.41489 80.6883 6.34639L78.1866 5.37984L77.9925 5.9582C77.3632 7.82464 78.3925 9.81851 80.257 10.4518C81.8783 11.0027 82.4567 12.0476 82.0665 13.6141C82.0489 13.671 81.7666 15.2845 81.8058 16.0001H83.6036C83.6644 14.8904 84.829 14.1611 85.8386 14.614C86.1229 14.7414 86.415 14.9238 86.715 15.159C88.3227 16.4255 90.691 16.1256 91.9555 14.516L92.3163 14.0572L90.0421 12.4241C88.4815 11.1968 86.3994 11.7516 84.8584 12.8024C84.729 12.8907 84.5643 12.7495 84.6368 12.6084C86.4993 8.95391 88.9206 8.96175 89.8695 9.77341C91.0204 10.7576 92.7633 10.5812 93.7396 9.4264L94.02 9.09507L92.3829 7.82856H92.3849Z",fill:"#51C233"}),d.jsx("path",{d:"M111.257 4.27539C114.524 4.27557 116.739 6.46855 116.739 9.98145C116.739 10.3833 116.718 10.788 116.673 11.2568H108.84C108.974 12.6434 109.892 13.4053 111.391 13.4053C112.398 13.4052 113.045 12.9803 113.338 12.375H116.538C115.888 14.5682 114.189 16 111.37 16C107.991 15.9998 105.754 13.6502 105.754 10.0703H105.751C105.751 6.55739 107.99 4.27539 111.257 4.27539ZM132.095 4.27539C134.801 4.2756 136.503 6.02159 136.503 8.95117V15.665H133.369V9.28613C133.369 7.81028 132.697 7.09379 131.444 7.09375C130.192 7.09375 129.362 7.96679 129.362 9.37598V15.6621H126.23V4.61035H128.984V5.72852C129.634 4.76615 130.82 4.27539 132.095 4.27539ZM106.379 2.72949H103.313C102.663 2.72949 102.305 2.99745 102.305 3.64746V4.60938H105.706V7.33887H102.305V15.6621H99.171V7.33887H96.42V4.60938H99.171V3.26758C99.171 1.11907 100.402 0 102.528 0H106.379V2.72949ZM120.583 6.55371C120.851 5.30087 121.747 4.60645 123.156 4.60645H125.126V4.98535C125.126 6.28287 124.074 7.33493 122.776 7.33496C121.546 7.33496 120.963 7.96297 120.963 9.21582V15.6611H117.829V4.60645H120.583V6.55371ZM111.257 6.73633C109.736 6.73633 108.907 7.58722 108.818 8.88477H113.584V8.83984C113.584 7.58713 112.778 6.73647 111.257 6.73633Z",fill:"#1E1F24"})]}),T2=({width:e=145,height:n=16,className:t=""})=>d.jsxs("svg",{width:e,height:n,viewBox:"0 0 145 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:[d.jsx("path",{d:"M9.79656 4.8H14.5006C15.5139 4.8 16.3192 5.05067 16.9166 5.552C17.5139 6.04267 17.8126 6.71467 17.8126 7.568C17.8126 8.112 17.6739 8.608 17.3966 9.056C17.1192 9.504 16.7512 9.84 16.2926 10.064C16.8579 10.2667 17.3059 10.608 17.6366 11.088C17.9672 11.5573 18.1326 12.1173 18.1326 12.768C18.1326 13.7387 17.8286 14.5227 17.2206 15.12C16.6126 15.7067 15.7752 16 14.7086 16H9.79656V4.8ZM14.4846 14.528C15.1246 14.528 15.6206 14.3627 15.9726 14.032C16.3246 13.7013 16.5006 13.2373 16.5006 12.64C16.5006 12.0427 16.3246 11.5893 15.9726 11.28C15.6312 10.96 15.1352 10.8 14.4846 10.8H11.3966V14.528H14.4846ZM14.2766 9.424C14.8846 9.424 15.3539 9.28533 15.6846 9.008C16.0152 8.72 16.1806 8.32533 16.1806 7.824C16.1806 7.32267 16.0152 6.93867 15.6846 6.672C15.3539 6.40533 14.8846 6.272 14.2766 6.272H11.3966V9.424H14.2766ZM22.5778 16.224C21.6285 16.224 20.8871 15.9413 20.3538 15.376C19.8205 14.8107 19.5538 14 19.5538 12.944V8.304H21.1058V12.8C21.1058 13.472 21.2551 13.9787 21.5538 14.32C21.8631 14.6507 22.3005 14.816 22.8658 14.816C23.4525 14.816 23.9165 14.6293 24.2578 14.256C24.6098 13.872 24.7858 13.3707 24.7858 12.752V8.304H26.3378V16H24.9618V15.12C24.7165 15.4827 24.3858 15.76 23.9698 15.952C23.5538 16.1333 23.0898 16.224 22.5778 16.224ZM28.0746 8.304H29.6266V16H28.0746V8.304ZM27.9786 4.912H29.7066V6.752H27.9786V4.912ZM33.0334 16C32.4894 16 32.0948 15.888 31.8494 15.664C31.6041 15.44 31.4814 15.0667 31.4814 14.544V4.8H33.0334V14.064C33.0334 14.2667 33.0761 14.416 33.1614 14.512C33.2468 14.5973 33.3854 14.64 33.5774 14.64H34.5534V16H33.0334ZM37.9539 16C37.2819 16 36.7966 15.856 36.4979 15.568C36.1993 15.28 36.0499 14.8053 36.0499 14.144V9.664H34.0339V8.304H36.0499V6H37.6019V8.304H40.0179V9.664H37.6019V13.84C37.6019 14.1173 37.6659 14.32 37.7939 14.448C37.9219 14.576 38.1299 14.64 38.4179 14.64H40.0179V16H37.9539ZM43.5709 8.304H45.1869L46.8989 14.272L48.6109 8.304H50.3869L52.0989 14.272L53.8109 8.304H55.4269L53.0429 16H51.2189L49.5069 10.064L47.7789 16H45.9549L43.5709 8.304ZM56.3746 8.304H57.9266V16H56.3746V8.304ZM56.2786 4.912H58.0066V6.752H56.2786V4.912ZM62.5971 16C61.9251 16 61.4397 15.856 61.1411 15.568C60.8424 15.28 60.6931 14.8053 60.6931 14.144V9.664H58.6771V8.304H60.6931V6H62.2451V8.304H64.6611V9.664H62.2451V13.84C62.2451 14.1173 62.3091 14.32 62.4371 14.448C62.5651 14.576 62.7731 14.64 63.0611 14.64H64.6611V16H62.5971ZM65.6727 4.8H67.2247V9.056C67.4807 8.736 67.8007 8.496 68.1847 8.336C68.5794 8.16533 69.0114 8.08 69.4807 8.08C70.4407 8.08 71.1927 8.368 71.7367 8.944C72.2807 9.50933 72.5527 10.3147 72.5527 11.36V16H71.0007V11.504C71.0007 10.832 70.8407 10.3307 70.5207 10C70.2114 9.65867 69.7687 9.488 69.1927 9.488C68.5954 9.488 68.1154 9.68 67.7527 10.064C67.4007 10.4373 67.2247 10.9333 67.2247 11.552V16H65.6727V4.8Z",fill:"#EEEEF0"}),d.jsx("path",{d:"M92.3848 7.82856C91.332 6.93847 89.7459 6.58166 88.3402 7.62074C88.2755 7.66779 88.1952 7.58741 88.2442 7.52468C88.5775 7.09532 88.9637 6.63263 89.2754 6.16798C89.593 5.69157 90.0675 5.35044 90.6145 5.18379C93.5259 4.30155 92.6515 0.00012207 92.6515 0.00012207C92.6515 0.00012207 88.154 0.290282 88.7088 4.17019C88.801 4.81913 88.6284 5.47983 88.2226 5.99545C87.7246 6.62479 87.1463 7.22667 86.7267 7.66191C86.6385 7.7521 86.4895 7.66583 86.5248 7.54428C86.9306 6.17778 87.2266 4.06432 85.8209 2.70175L83.8427 1.05881L83.4624 1.56071C82.3312 3.05268 82.6625 5.15634 84.1564 6.28561C85.0132 6.93259 85.4014 7.63643 85.3406 8.40888C85.3033 8.87157 85.0936 9.30485 84.7799 9.64794C84.1898 10.2949 83.6388 10.9889 83.2134 11.7928C83.1546 11.9045 82.984 11.8614 82.9899 11.734C83.0507 10.4067 82.9232 7.41489 80.6882 6.34639L78.1866 5.37984L77.9925 5.9582C77.3631 7.82464 78.3924 9.81851 80.2569 10.4518C81.8783 11.0027 82.4566 12.0476 82.0665 13.6141C82.0488 13.671 81.7665 15.2845 81.8057 16.0001H83.6036C83.6643 14.8904 84.8289 14.1611 85.8386 14.614C86.1229 14.7414 86.415 14.9238 86.7149 15.159C88.3226 16.4255 90.6909 16.1256 91.9555 14.516L92.3162 14.0572L90.042 12.4241C88.4814 11.1968 86.3993 11.7516 84.8583 12.8024C84.7289 12.8907 84.5642 12.7495 84.6368 12.6084C86.4993 8.95391 88.9206 8.96175 89.8695 9.77341C91.0203 10.7576 92.7632 10.5812 93.7396 9.4264L94.0199 9.09507L92.3829 7.82856H92.3848Z",fill:"#51C233"}),d.jsx("path",{d:"M111.257 4.27539C114.524 4.27557 116.739 6.46855 116.739 9.98145C116.739 10.3833 116.718 10.788 116.673 11.2568H108.84C108.974 12.6434 109.892 13.4053 111.391 13.4053C112.398 13.4052 113.045 12.9803 113.338 12.375H116.538C115.888 14.5682 114.189 16 111.37 16C107.991 15.9998 105.754 13.6502 105.754 10.0703H105.751C105.751 6.55739 107.989 4.27539 111.257 4.27539ZM132.095 4.27539C134.801 4.2756 136.503 6.02159 136.503 8.95117V15.665H133.369V9.28613C133.369 7.81028 132.697 7.09379 131.444 7.09375C130.191 7.09375 129.362 7.96679 129.362 9.37598V15.6621H126.229V4.61035H128.983V5.72852C129.633 4.76615 130.82 4.27539 132.095 4.27539ZM106.379 2.72949H103.312C102.662 2.72949 102.305 2.99745 102.305 3.64746V4.60938H105.706V7.33887H102.305V15.6621H99.1709V7.33887H96.4199V4.60938H99.1709V3.26758C99.1709 1.11907 100.402 0 102.528 0H106.379V2.72949ZM120.583 6.55371C120.851 5.30087 121.747 4.60645 123.156 4.60645H125.126V4.98535C125.126 6.28287 124.074 7.33493 122.776 7.33496C121.546 7.33496 120.963 7.96297 120.963 9.21582V15.6611H117.829V4.60645H120.583V6.55371ZM111.257 6.73633C109.736 6.73633 108.907 7.58722 108.817 8.88477H113.584V8.83984C113.584 7.58713 112.777 6.73647 111.257 6.73633Z",fill:"#EEEEF0"})]}),V2=({width:e=25,height:n=24,className:t=""})=>d.jsxs("svg",{width:e,height:n,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:[d.jsx("path",{d:"M14.27 17.8332V15.4998C14.3512 14.7691 14.1416 14.0357 13.6867 13.4582C15.4367 13.4582 17.1867 12.2915 17.1867 10.2498C17.2333 9.52067 17.0292 8.80317 16.6033 8.20817C16.7667 7.53734 16.7667 6.83734 16.6033 6.1665C16.6033 6.1665 16.02 6.1665 14.8533 7.0415C13.3133 6.74984 11.7267 6.74984 10.1867 7.0415C9.02002 6.1665 8.43668 6.1665 8.43668 6.1665C8.26168 6.83734 8.26168 7.53734 8.43668 8.20817C8.01194 8.80077 7.80579 9.5223 7.85335 10.2498C7.85335 12.2915 9.60335 13.4582 11.3533 13.4582C11.1258 13.744 10.9567 14.0707 10.8575 14.4207C10.7583 14.7707 10.7292 15.1382 10.77 15.4998V17.8332",stroke:"#62636C",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"}),d.jsx("path",{d:"M10.77 15.5002C8.13919 16.6668 7.85336 14.3335 6.68669 14.3335",stroke:"#62636C",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"})]}),L2=({width:e=24,height:n=24,className:t=""})=>d.jsxs("svg",{width:e,height:n,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:[d.jsx("path",{d:"M13.75 17.8332V15.4998C13.8311 14.7691 13.6216 14.0357 13.1667 13.4582C14.9167 13.4582 16.6667 12.2915 16.6667 10.2498C16.7133 9.52067 16.5092 8.80317 16.0833 8.20817C16.2467 7.53734 16.2467 6.83734 16.0833 6.1665C16.0833 6.1665 15.5 6.1665 14.3333 7.0415C12.7933 6.74984 11.2067 6.74984 9.66666 7.0415C8.5 6.1665 7.91666 6.1665 7.91666 6.1665C7.74166 6.83734 7.74166 7.53734 7.91666 8.20817C7.49192 8.80077 7.28577 9.5223 7.33333 10.2498C7.33333 12.2915 9.08333 13.4582 10.8333 13.4582C10.6058 13.744 10.4367 14.0707 10.3375 14.4207C10.2383 14.7707 10.2092 15.1382 10.25 15.4998V17.8332",stroke:"#B2B3BD",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"}),d.jsx("path",{d:"M10.25 15.5002C7.61917 16.6668 7.33334 14.3335 6.16667 14.3335",stroke:"#B2B3BD",strokeWidth:"1.16667",strokeLinecap:"round",strokeLinejoin:"round"})]}),q2=({width:e=25,height:n=24,className:t=""})=>d.jsx("svg",{width:e,height:n,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:d.jsx("path",{d:"M15.9658 6.57812H17.7971L13.7971 11.1805L18.52 17.4215H14.8092L11.9176 13.6384L8.59231 17.4215H6.76098L11.0501 12.5058L6.52002 6.57812H10.3272L12.9538 10.048L15.9658 6.57812ZM15.3152 16.3131H16.3272L9.77303 7.61427H8.6646L15.3152 16.3131Z",fill:"#62636C"})}),W2=({width:e=24,height:n=24,className:t=""})=>d.jsx("svg",{width:e,height:n,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:d.jsx("path",{d:"M15.4458 6.57812H17.2771L13.2771 11.1805L18 17.4215H14.2892L11.3976 13.6384L8.07229 17.4215H6.24096L10.5301 12.5058L6 6.57812H9.80723L12.4337 10.048L15.4458 6.57812ZM14.7952 16.3131H15.8072L9.25301 7.61427H8.14458L14.7952 16.3131Z",fill:"#B2B3BD"})}),S2=({width:e=25,height:n=24,className:t=""})=>d.jsx("svg",{width:e,height:n,viewBox:"0 0 25 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:d.jsx("path",{d:"M16.0922 15.5369H14.5887V13.2056C14.5887 12.6497 14.5787 11.9341 13.8068 11.9341C13.0238 11.9341 12.9039 12.5398 12.9039 13.1652V15.5368H11.4005V10.7427H12.8438V11.3979H12.864C13.0084 11.1533 13.2172 10.9522 13.4679 10.8158C13.7187 10.6794 14.0021 10.613 14.2881 10.6235C15.8119 10.6235 16.0928 11.6159 16.0928 12.907L16.0922 15.5369ZM9.70411 10.0874C9.53155 10.0874 9.36285 10.0368 9.21936 9.94191C9.07587 9.84701 8.96402 9.71211 8.89796 9.55427C8.8319 9.39643 8.81458 9.22274 8.84822 9.05516C8.88185 8.88758 8.96492 8.73363 9.08692 8.6128C9.20891 8.49196 9.36436 8.40966 9.53359 8.37629C9.70283 8.34293 9.87825 8.36001 10.0377 8.42536C10.1971 8.49072 10.3334 8.60142 10.4293 8.74347C10.5252 8.88551 10.5764 9.05253 10.5764 9.22338C10.5764 9.33683 10.5539 9.44917 10.5101 9.55399C10.4662 9.6588 10.402 9.75405 10.321 9.83428C10.24 9.91451 10.1438 9.97816 10.038 10.0216C9.93213 10.065 9.81868 10.0874 9.70411 10.0874ZM10.4558 15.5369H8.95082V10.7427H10.4558V15.5369ZM16.8417 6.97725H8.19534C7.99909 6.97505 7.80999 7.0501 7.66959 7.18588C7.52919 7.32167 7.44899 7.50709 7.44659 7.70141V16.2981C7.44891 16.4925 7.52906 16.6781 7.66945 16.814C7.80985 16.95 7.999 17.0251 8.19534 17.0231H16.8417C17.0384 17.0255 17.2281 16.9505 17.3691 16.8146C17.51 16.6787 17.5907 16.4929 17.5934 16.2981V7.70079C17.5906 7.50609 17.5099 7.32045 17.3689 7.18467C17.228 7.04889 17.0384 6.97406 16.8417 6.97663",fill:"#62636C"})}),U2=({width:e=24,height:n=24,className:t=""})=>d.jsx("svg",{width:e,height:n,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:d.jsx("path",{d:"M15.5722 15.5369H14.0687V13.2056C14.0687 12.6497 14.0587 11.9341 13.2868 11.9341C12.5037 11.9341 12.3839 12.5398 12.3839 13.1652V15.5368H10.8805V10.7427H12.3238V11.3979H12.344C12.4884 11.1533 12.6971 10.9522 12.9479 10.8158C13.1987 10.6794 13.4821 10.613 13.768 10.6235C15.2918 10.6235 15.5728 11.6159 15.5728 12.907L15.5722 15.5369ZM9.18409 10.0874C9.01153 10.0874 8.84283 10.0368 8.69934 9.94191C8.55585 9.84701 8.444 9.71211 8.37794 9.55427C8.31188 9.39643 8.29456 9.22274 8.3282 9.05516C8.36183 8.88758 8.4449 8.73363 8.5669 8.6128C8.68889 8.49196 8.84434 8.40966 9.01357 8.37629C9.18281 8.34293 9.35823 8.36001 9.51767 8.42536C9.6771 8.49072 9.81338 8.60142 9.90927 8.74347C10.0052 8.88551 10.0564 9.05253 10.0564 9.22338C10.0564 9.33683 10.0339 9.44917 9.99005 9.55399C9.94622 9.6588 9.88198 9.75405 9.80097 9.83428C9.71997 9.91451 9.6238 9.97816 9.51795 10.0216C9.41211 10.065 9.29866 10.0874 9.18409 10.0874ZM9.93581 15.5369H8.4308V10.7427H9.93581V15.5369ZM16.3217 6.97725H7.67532C7.47907 6.97505 7.28997 7.0501 7.14957 7.18588C7.00917 7.32167 6.92897 7.50709 6.92657 7.70141V16.2981C6.92889 16.4925 7.00904 16.6781 7.14943 16.814C7.28983 16.95 7.47898 17.0251 7.67532 17.0231H16.3217C16.5184 17.0255 16.7081 16.9505 16.8491 16.8146C16.99 16.6787 17.0707 16.4929 17.0734 16.2981V7.70079C17.0706 7.50609 16.9899 7.32045 16.8489 7.18467C16.708 7.04889 16.5183 6.97406 16.3217 6.97663",fill:"#B2B3BD"})}),E2=({width:e=32,height:n=32,className:t=""})=>d.jsxs("svg",{width:e,height:n,viewBox:"0 0 512 512",fill:"none",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",className:t,children:[d.jsxs("g",{clipPath:"url(#clip0_2003_55)",children:[d.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"url(#paint0_linear_2003_55)"}),d.jsx("circle",{cx:"256",cy:"256",r:"254",stroke:"url(#paint1_linear_2003_55)",strokeWidth:"4"}),d.jsx("circle",{cx:"256",cy:"256",r:"190",fill:"url(#paint2_linear_2003_55)",stroke:"url(#paint3_linear_2003_55)",strokeWidth:"4"}),d.jsx("mask",{id:"mask0_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"512",height:"512",children:d.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"white"})}),d.jsxs("g",{mask:"url(#mask0_2003_55)",children:[d.jsx("g",{filter:"url(#filter1_f_2003_55)",children:d.jsx("path",{d:"M442.63 11.6267C456.09 -21.5565 482.511 -41.8116 494.038 -47.7913C504.996 -52.945 521.977 -48.4056 502.24 10.9816C477.567 85.2156 463.797 65.5975 429.79 128.38C395.783 191.162 419.879 133.733 389.781 165.003C359.684 196.273 358.947 200.432 321.716 243.16C284.484 285.889 283.25 280.639 314.634 230.674C346.019 180.709 342.823 181.221 389.886 117.112C436.95 53.0032 425.804 53.1058 442.63 11.6267Z",fill:"white",fillOpacity:"0.32"})}),d.jsx("g",{filter:"url(#filter2_f_2003_55)",children:d.jsx("path",{d:"M477.63 88.6267C491.09 55.4435 517.511 35.1884 529.038 29.2087C539.996 24.055 556.977 28.5944 537.24 87.9816C512.567 162.216 498.797 142.598 464.79 205.38C430.783 268.162 454.879 210.733 424.781 242.003C394.684 273.273 393.947 277.432 356.716 320.16C319.484 362.889 318.25 357.639 349.634 307.674C381.019 257.709 377.823 258.221 424.886 194.112C471.95 130.003 460.804 130.106 477.63 88.6267Z",fill:"white",fillOpacity:"0.32"})}),d.jsx("g",{filter:"url(#filter3_f_2003_55)",children:d.jsx("path",{d:"M231.094 -86.6032C233.2 -123.334 270.507 -143.191 288.898 -148.527C306.772 -152.983 343.73 -145.307 348.572 -78.957C354.625 3.98024 312.875 -20.7962 291.99 47.4952C271.106 115.787 276.336 52.3306 239.894 84.4911C203.452 116.652 205.069 121.389 162.981 165.883C120.893 210.377 114.569 204.091 139.738 150.35C164.908 96.6093 158.962 96.7553 204.701 28.7583C250.44 -39.2386 228.461 -40.6893 231.094 -86.6032Z",fill:"white",fillOpacity:"0.4"})}),d.jsx("g",{filter:"url(#filter4_f_2003_55)",children:d.jsx("path",{d:"M-107.305 324.646C-113.552 285.166 -50.49 273.785 -18.1783 273.029C13.4267 273.091 83.4284 291.641 110.595 365.337C144.553 457.457 61.0399 418.938 41.4844 487.666C21.9289 556.395 14.06 488.629 -44.0227 513.668C-102.105 538.707 -97.8309 544.319 -162.889 581.255C-227.947 618.19 -241.295 609.593 -209.861 557.914C-178.427 506.234 -189.308 504.756 -124.016 443.193C-58.7245 381.63 -99.4971 373.995 -107.305 324.646Z",fill:"white",fillOpacity:"0.24"})}),d.jsx("g",{filter:"url(#filter5_f_2003_55)",children:d.jsx("path",{d:"M579.63 213.627C593.09 180.444 619.511 160.188 631.038 154.209C641.996 149.055 658.977 153.594 639.24 212.982C614.567 287.216 600.797 267.598 566.79 330.38C532.783 393.162 556.879 335.733 526.781 367.003C496.684 398.273 495.947 402.432 458.716 445.16C421.484 487.889 420.25 482.639 451.634 432.674C483.019 382.709 479.823 383.221 526.886 319.112C573.95 255.003 562.804 255.106 579.63 213.627Z",fill:"white",fillOpacity:"0.32"})})]}),d.jsx("mask",{id:"mask1_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"512",height:"512",children:d.jsx("path",{d:"M256 0C397.385 0 512 114.615 512 256C512 397.385 397.385 512 256 512C114.615 512 0 397.385 0 256C0 114.615 114.615 0 256 0ZM256 64C149.961 64 64 149.961 64 256C64 362.039 149.961 448 256 448C362.039 448 448 362.039 448 256C448 149.961 362.039 64 256 64Z",fill:"white"})}),d.jsxs("g",{mask:"url(#mask1_2003_55)",children:[d.jsxs("mask",{id:"mask2_2003_55",style:{maskType:"alpha"},maskUnits:"userSpaceOnUse",x:"9",y:"-46",width:"529",height:"525",children:[d.jsx("ellipse",{cx:"454.793",cy:"203.331",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 454.793 203.331)",fill:"#D9D9D9"}),d.jsx("ellipse",{cx:"270.793",cy:"35.3312",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 270.793 35.3312)",fill:"#D9D9D9"}),d.jsx("ellipse",{cx:"446.793",cy:"67.3312",rx:"111.5",ry:"32.8501",transform:"rotate(-44.2469 446.793 67.3312)",fill:"#D9D9D9"}),d.jsx("ellipse",{cx:"80.2712",cy:"367.484",rx:"65.2671",ry:"76.7003",transform:"rotate(-44.2469 80.2712 367.484)",fill:"#D9D9D9"}),d.jsx("ellipse",{cx:"360.271",cy:"407.484",rx:"65.2671",ry:"76.7003",transform:"rotate(-44.2469 360.271 407.484)",fill:"#D9D9D9",fillOpacity:"0.24"}),d.jsx("ellipse",{cx:"133.311",cy:"150.002",rx:"118.371",ry:"76.7003",transform:"rotate(-44.2469 133.311 150.002)",fill:"#D9D9D9",fillOpacity:"0.12"})]}),d.jsx("g",{mask:"url(#mask2_2003_55)",children:d.jsx("rect",{x:"6",y:"6",width:"500",height:"500",fill:"url(#pattern0_2003_55)"})})]}),d.jsx("path",{d:"M195.456 161H191.024L203.842 126.091H208.206L221.024 161H216.592L206.161 131.614H205.888L195.456 161ZM197.092 147.364H214.956V151.114H197.092V147.364ZM230.689 126.091V161H226.462V126.091H230.689ZM267.256 137H263.028C262.778 135.784 262.341 134.716 261.716 133.795C261.102 132.875 260.352 132.102 259.466 131.477C258.591 130.841 257.619 130.364 256.551 130.045C255.483 129.727 254.369 129.568 253.21 129.568C251.097 129.568 249.182 130.102 247.466 131.17C245.761 132.239 244.403 133.812 243.392 135.892C242.392 137.972 241.892 140.523 241.892 143.545C241.892 146.568 242.392 149.119 243.392 151.199C244.403 153.278 245.761 154.852 247.466 155.92C249.182 156.989 251.097 157.523 253.21 157.523C254.369 157.523 255.483 157.364 256.551 157.045C257.619 156.727 258.591 156.256 259.466 155.631C260.352 154.994 261.102 154.216 261.716 153.295C262.341 152.364 262.778 151.295 263.028 150.091H267.256C266.938 151.875 266.358 153.472 265.517 154.881C264.676 156.29 263.631 157.489 262.381 158.477C261.131 159.455 259.727 160.199 258.17 160.71C256.625 161.222 254.972 161.477 253.21 161.477C250.233 161.477 247.585 160.75 245.267 159.295C242.949 157.841 241.125 155.773 239.795 153.091C238.466 150.409 237.801 147.227 237.801 143.545C237.801 139.864 238.466 136.682 239.795 134C241.125 131.318 242.949 129.25 245.267 127.795C247.585 126.341 250.233 125.614 253.21 125.614C254.972 125.614 256.625 125.869 258.17 126.381C259.727 126.892 261.131 127.642 262.381 128.631C263.631 129.608 264.676 130.801 265.517 132.21C266.358 133.608 266.938 135.205 267.256 137ZM274.087 161V126.091H285.882C288.621 126.091 290.859 126.585 292.598 127.574C294.348 128.551 295.643 129.875 296.484 131.545C297.325 133.216 297.746 135.08 297.746 137.136C297.746 139.193 297.325 141.062 296.484 142.744C295.655 144.426 294.371 145.767 292.632 146.767C290.893 147.756 288.666 148.25 285.95 148.25H277.496V144.5H285.814C287.689 144.5 289.195 144.176 290.331 143.528C291.467 142.881 292.291 142.006 292.803 140.903C293.325 139.79 293.587 138.534 293.587 137.136C293.587 135.739 293.325 134.489 292.803 133.386C292.291 132.284 291.462 131.42 290.314 130.795C289.166 130.159 287.643 129.841 285.746 129.841H278.314V161H274.087ZM302.425 161H297.993L310.811 126.091H315.175L327.993 161H323.561L313.129 131.614H312.857L302.425 161ZM304.061 147.364H321.925V151.114H304.061V147.364Z",fill:"white"}),d.jsx("line",{x1:"111.5",y1:"184",x2:"407.5",y2:"184",stroke:"url(#paint4_linear_2003_55)",strokeWidth:"2"}),d.jsx("path",{d:"M154.788 255.008C154.476 251.857 153.134 249.409 150.765 247.664C148.395 245.919 145.179 245.047 141.116 245.047C138.356 245.047 136.025 245.437 134.124 246.219C132.223 246.974 130.765 248.029 129.749 249.383C128.759 250.737 128.265 252.273 128.265 253.992C128.213 255.424 128.512 256.674 129.163 257.742C129.84 258.81 130.765 259.734 131.937 260.516C133.108 261.271 134.463 261.935 135.999 262.508C137.535 263.055 139.176 263.523 140.921 263.914L148.108 265.633C151.598 266.414 154.801 267.456 157.718 268.758C160.634 270.06 163.16 271.661 165.296 273.562C167.431 275.464 169.085 277.703 170.257 280.281C171.455 282.859 172.067 285.815 172.093 289.148C172.067 294.044 170.817 298.289 168.343 301.883C165.895 305.451 162.353 308.224 157.718 310.203C153.108 312.156 147.549 313.133 141.038 313.133C134.58 313.133 128.955 312.143 124.163 310.164C119.397 308.185 115.674 305.255 112.991 301.375C110.335 297.469 108.942 292.638 108.812 286.883H125.179C125.361 289.565 126.129 291.805 127.483 293.602C128.864 295.372 130.7 296.714 132.991 297.625C135.309 298.51 137.926 298.953 140.843 298.953C143.707 298.953 146.194 298.536 148.304 297.703C150.439 296.87 152.093 295.711 153.265 294.227C154.437 292.742 155.022 291.036 155.022 289.109C155.022 287.312 154.489 285.802 153.421 284.578C152.379 283.354 150.843 282.312 148.812 281.453C146.806 280.594 144.345 279.812 141.429 279.109L132.718 276.922C125.973 275.281 120.647 272.716 116.741 269.227C112.835 265.737 110.895 261.036 110.921 255.125C110.895 250.281 112.184 246.049 114.788 242.43C117.418 238.81 121.025 235.984 125.608 233.953C130.192 231.922 135.4 230.906 141.233 230.906C147.171 230.906 152.353 231.922 156.78 233.953C161.233 235.984 164.697 238.81 167.171 242.43C169.645 246.049 170.921 250.242 170.999 255.008H154.788ZM256.985 272C256.985 280.724 255.332 288.146 252.024 294.266C248.743 300.385 244.264 305.06 238.587 308.289C232.936 311.492 226.582 313.094 219.524 313.094C212.415 313.094 206.035 311.479 200.384 308.25C194.733 305.021 190.267 300.346 186.985 294.227C183.704 288.107 182.063 280.698 182.063 272C182.063 263.276 183.704 255.854 186.985 249.734C190.267 243.615 194.733 238.953 200.384 235.75C206.035 232.521 212.415 230.906 219.524 230.906C226.582 230.906 232.936 232.521 238.587 235.75C244.264 238.953 248.743 243.615 252.024 249.734C255.332 255.854 256.985 263.276 256.985 272ZM239.837 272C239.837 266.349 238.991 261.583 237.298 257.703C235.631 253.823 233.274 250.88 230.228 248.875C227.181 246.87 223.613 245.867 219.524 245.867C215.436 245.867 211.868 246.87 208.821 248.875C205.774 250.88 203.405 253.823 201.712 257.703C200.045 261.583 199.212 266.349 199.212 272C199.212 277.651 200.045 282.417 201.712 286.297C203.405 290.177 205.774 293.12 208.821 295.125C211.868 297.13 215.436 298.133 219.524 298.133C223.613 298.133 227.181 297.13 230.228 295.125C233.274 293.12 235.631 290.177 237.298 286.297C238.991 282.417 239.837 277.651 239.837 272ZM340.101 260.008H322.991C322.679 257.794 322.041 255.828 321.077 254.109C320.114 252.365 318.877 250.88 317.366 249.656C315.856 248.432 314.111 247.495 312.132 246.844C310.179 246.193 308.056 245.867 305.765 245.867C301.624 245.867 298.017 246.896 294.944 248.953C291.871 250.984 289.489 253.953 287.796 257.859C286.103 261.74 285.257 266.453 285.257 272C285.257 277.703 286.103 282.495 287.796 286.375C289.515 290.255 291.91 293.185 294.983 295.164C298.056 297.143 301.611 298.133 305.647 298.133C307.913 298.133 310.009 297.833 311.937 297.234C313.89 296.635 315.621 295.763 317.132 294.617C318.642 293.445 319.892 292.026 320.882 290.359C321.897 288.693 322.601 286.792 322.991 284.656L340.101 284.734C339.658 288.406 338.551 291.948 336.78 295.359C335.035 298.745 332.679 301.779 329.71 304.461C326.767 307.117 323.252 309.227 319.163 310.789C315.101 312.326 310.504 313.094 305.374 313.094C298.239 313.094 291.858 311.479 286.233 308.25C280.634 305.021 276.207 300.346 272.952 294.227C269.723 288.107 268.108 280.698 268.108 272C268.108 263.276 269.749 255.854 273.03 249.734C276.312 243.615 280.765 238.953 286.39 235.75C292.015 232.521 298.343 230.906 305.374 230.906C310.009 230.906 314.306 231.557 318.265 232.859C322.249 234.161 325.778 236.062 328.851 238.562C331.924 241.036 334.424 244.07 336.351 247.664C338.304 251.258 339.554 255.372 340.101 260.008ZM351.761 312V299.812L380.237 273.445C382.659 271.102 384.69 268.992 386.331 267.117C387.998 265.242 389.261 263.406 390.12 261.609C390.979 259.786 391.409 257.82 391.409 255.711C391.409 253.367 390.875 251.349 389.808 249.656C388.74 247.937 387.282 246.622 385.433 245.711C383.584 244.773 381.487 244.305 379.144 244.305C376.696 244.305 374.56 244.799 372.737 245.789C370.914 246.779 369.508 248.198 368.519 250.047C367.529 251.896 367.034 254.096 367.034 256.648H350.979C350.979 251.414 352.164 246.87 354.534 243.016C356.904 239.161 360.224 236.18 364.495 234.07C368.766 231.961 373.688 230.906 379.261 230.906C384.99 230.906 389.977 231.922 394.222 233.953C398.493 235.958 401.813 238.745 404.183 242.312C406.552 245.88 407.737 249.969 407.737 254.578C407.737 257.599 407.138 260.581 405.94 263.523C404.769 266.466 402.672 269.734 399.651 273.328C396.631 276.896 392.373 281.18 386.878 286.18L375.198 297.625V298.172H408.792V312H351.761Z",fill:"url(#paint5_linear_2003_55)"}),d.jsx("line",{x1:"111.5",y1:"358",x2:"407.5",y2:"358",stroke:"url(#paint6_linear_2003_55)",strokeWidth:"2"})]}),d.jsxs("defs",{children:[d.jsxs("filter",{id:"filter1_f_2003_55",x:"244.349",y:"-97.3701",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[d.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),d.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),d.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),d.jsxs("filter",{id:"filter2_f_2003_55",x:"279.349",y:"-20.3701",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[d.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),d.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),d.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),d.jsxs("filter",{id:"filter3_f_2003_55",x:"76.9136",y:"-197.559",width:"320.252",height:"440.967",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[d.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),d.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),d.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),d.jsxs("filter",{id:"filter4_f_2003_55",x:"-346.122",y:"153.028",width:"584.747",height:"570.864",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[d.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),d.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),d.jsx("feGaussianBlur",{stdDeviation:"60",result:"effect1_foregroundBlur_2003_55"})]}),d.jsxs("filter",{id:"filter5_f_2003_55",x:"381.349",y:"104.63",width:"314.972",height:"417.365",filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",children:[d.jsx("feFlood",{floodOpacity:"0",result:"BackgroundImageFix"}),d.jsx("feBlend",{mode:"normal",in:"SourceGraphic",in2:"BackgroundImageFix",result:"shape"}),d.jsx("feGaussianBlur",{stdDeviation:"24",result:"effect1_foregroundBlur_2003_55"})]}),d.jsx("pattern",{id:"pattern0_2003_55",patternContentUnits:"objectBoundingBox",width:"0.8",height:"0.8",children:d.jsx("use",{xlinkHref:"#image0_2003_55",transform:"scale(0.001)"})}),d.jsxs("linearGradient",{id:"paint0_linear_2003_55",x1:"256",y1:"0",x2:"256",y2:"512",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0.2"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.02"})]}),d.jsxs("linearGradient",{id:"paint1_linear_2003_55",x1:"256",y1:"0",x2:"256",y2:"512",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0.64"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.12"})]}),d.jsxs("linearGradient",{id:"paint2_linear_2003_55",x1:"256",y1:"64",x2:"256",y2:"448",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.2"})]}),d.jsxs("linearGradient",{id:"paint3_linear_2003_55",x1:"256",y1:"64",x2:"256",y2:"448",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0.24"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.64"})]}),d.jsxs("linearGradient",{id:"paint4_linear_2003_55",x1:"111.5",y1:"185.5",x2:"407.5",y2:"185.5",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0"}),d.jsx("stop",{offset:"0.5",stopColor:"white"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0"})]}),d.jsxs("linearGradient",{id:"paint5_linear_2003_55",x1:"259.5",y1:"243.759",x2:"259.5",y2:"309.655",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{offset:"0.25",stopColor:"white"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0.24"})]}),d.jsxs("linearGradient",{id:"paint6_linear_2003_55",x1:"111.5",y1:"359.5",x2:"407.5",y2:"359.5",gradientUnits:"userSpaceOnUse",children:[d.jsx("stop",{stopColor:"white",stopOpacity:"0"}),d.jsx("stop",{offset:"0.5",stopColor:"white"}),d.jsx("stop",{offset:"1",stopColor:"white",stopOpacity:"0"})]}),d.jsx("clipPath",{id:"clip0_2003_55",children:d.jsx("rect",{width:"512",height:"512",fill:"white"})}),d.jsx("image",{id:"image0_2003_55",width:"800",height:"800",preserveAspectRatio:"none",xlinkHref:"data:image/png;base64,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"})]})]}),R2=()=>d.jsxs(d.Fragment,{children:[d.jsx("style",{children:` #fern-footer { position: relative; } @@ -135,6 +142,7 @@ Error generating stack: `+o.message+` height: 1rem; margin: 0; filter: saturate(0) opacity(0.7); + transform: translateX(-0.5rem); } .footer-logo-frame { @@ -264,13 +272,13 @@ Error generating stack: `+o.message+` /* Responsive Design - Mobile */ @media (max-width: 640px) { .footer { - padding: 2rem 1.5rem; + padding: 2rem 1rem; } .footer-top { flex-direction: column; gap: 1.5rem; - margin-bottom: 2rem; + margin-bottom: 1rem; } .footer-logo-frame { @@ -280,7 +288,11 @@ Error generating stack: `+o.message+` .footer-status { flex-direction: column; gap: 0.75rem; - padding-top: 2rem; + padding-top: 0rem; + } + + .footer-link { + width:fit-content; } .footer-links { @@ -302,6 +314,16 @@ Error generating stack: `+o.message+` .footer-bottom-text { order: 2; } + + .footer-column-socials { + flex-direction: row; + flex-wrap: wrap; + gap: 1rem; + } + + .soc2-badge { + padding: 0; + } } /* Tablet breakpoint */ @@ -317,4 +339,4 @@ Error generating stack: `+o.message+` min-width: 200px; } } - `}),f.jsxs("footer",{className:"footer",children:[f.jsxs("div",{className:"footer-top",children:[f.jsxs("a",{className:"footer-logo",href:"https://buildwithfern.com",children:[f.jsx(N2,{className:"footer-logo-img dark:hidden"}),f.jsx(T2,{className:"footer-logo-img hidden dark:block"}),f.jsx(V2,{className:"footer-logo-frame dark:hidden"}),f.jsx(L2,{className:"footer-logo-frame hidden dark:block"})]}),f.jsxs("div",{className:"footer-status",children:[f.jsx(k2,{}),f.jsxs("a",{className:"soc2-badge",href:"https://security.buildwithfern.com/",children:[f.jsx(F2,{className:"soc2-badge-img"}),f.jsx("span",{className:"status-text",children:"Soc 2 Type II"})]})]})]}),f.jsxs("div",{className:"footer-links",children:[f.jsx("div",{className:"footer-bottom-text",children:" © 2025 Fern • Located in Brooklyn, NY "}),f.jsxs("div",{className:"footer-columns",children:[f.jsxs("div",{className:"footer-column",children:[f.jsx("h4",{className:"footer-column-title",children:"Documentation"}),f.jsxs("div",{className:"footer-column-links",children:[f.jsx("a",{href:"/learn/sdks/overview/introduction",className:"footer-link",children:"SDKs"}),f.jsx("a",{href:"/learn/docs/getting-started/overview",className:"footer-link",children:"Docs"}),f.jsx("a",{href:"/learn/ask-fern",className:"footer-link",children:"Ask Fern"}),f.jsx("a",{href:"/learn/cli-api-reference/cli-reference/overview",className:"footer-link",children:"CLI Reference"}),f.jsx("a",{href:"/learn/cli-api-reference/api-reference/overview",className:"footer-link",children:"API Reference"})]})]}),f.jsxs("div",{className:"footer-column",children:[f.jsx("h4",{className:"footer-column-title",children:"API Definitions"}),f.jsxs("div",{className:"footer-column-links",children:[f.jsx("a",{href:"/learn/api-definitions/openapi/overview",className:"footer-link",children:"OpenAPI"}),f.jsx("a",{href:"/learn/api-definitions/asyncapi/overview",className:"footer-link",children:"AsyncAPI"}),f.jsx("a",{href:"/learn/api-definitions/openrpc/overview",className:"footer-link",children:"OpenRPC"}),f.jsx("a",{href:"/learn/api-definitions/grpc/overview",className:"footer-link",children:"gRPC"}),f.jsx("a",{href:"/learn/api-definitions/ferndef/overview",className:"footer-link",children:"Fern Definition"})]})]}),f.jsxs("div",{className:"footer-column",children:[f.jsx("h4",{className:"footer-column-title",children:"Resources"}),f.jsxs("div",{className:"footer-column-links",children:[f.jsx("a",{href:"https://buildwithfern.com/blog",className:"footer-link",children:"Blog"}),f.jsx("a",{href:"learn/home#help",className:"footer-link",children:"Support"}),f.jsx("a",{href:"https://buildwithfern.com/pricing",className:"footer-link",children:"Pricing"}),f.jsx("a",{href:"https://buildwithfern.com/slack",className:"footer-link",children:"Slack"})]})]}),f.jsxs("div",{className:"footer-column",children:[f.jsx("h4",{className:"footer-column-title",children:"Company"}),f.jsxs("div",{className:"footer-column-links",children:[f.jsx("a",{href:"https://brandfetch.com/buildwithfern.com",className:"footer-link",children:"Brand Kit"}),f.jsx("a",{href:"https://buildwithfern.com/privacy-policy",className:"footer-link",children:"Privacy Policy"}),f.jsx("a",{href:"https://buildwithfern.com/terms-of-service",className:"footer-link",children:"Terms of Service"})]})]}),f.jsxs("div",{className:"footer-column-socials",children:[f.jsxs("a",{href:"https://github.com/fern-api/fern",className:"footer-link",children:[f.jsx(q2,{className:"footer-social-icon dark:hidden"}),f.jsx(W2,{className:"footer-social-icon hidden dark:block"})]}),f.jsxs("a",{href:"https://x.com/buildwithfern",className:"footer-link",children:[f.jsx(S2,{className:"footer-social-icon dark:hidden"}),f.jsx(U2,{className:"footer-social-icon hidden dark:block"})]}),f.jsxs("a",{href:"https://www.linkedin.com/company/buildwithfern",className:"footer-link",children:[f.jsx(E2,{className:"footer-social-icon dark:hidden"}),f.jsx(R2,{className:"footer-social-icon hidden dark:block"})]})]})]})]})]})]}),Eu="fern-footer",Ru=async()=>{if(!document.getElementById("footer")){const t=document.createElement("div");t.setAttribute("id","fern-footer-wrapper"),t.setAttribute("data-react-component","true");let n=document.getElementById(Eu);n||(n=document.createElement("div"),n.setAttribute("id",Eu),document.body.appendChild(n)),n.insertBefore(t,n.firstChild),nf(t).render(f.jsx(gf.StrictMode,{children:f.jsx(B2,{})})),n&&(n.style.display="block")}};window.addEventListener("load",async()=>{await Ru(),new MutationObserver(async e=>{e.some(n=>n.type==="childList"&&!document.getElementById("fern-footer-wrapper"))&&await Ru()}).observe(document.body,{childList:!0,subtree:!0})}); + `}),d.jsxs("footer",{className:"footer",children:[d.jsxs("div",{className:"footer-top",children:[d.jsxs("a",{className:"footer-logo",href:"https://buildwithfern.com",children:[d.jsx(N2,{className:"footer-logo-img dark:hidden"}),d.jsx(T2,{className:"footer-logo-img hidden dark:block"})]}),d.jsxs("div",{className:"footer-status",children:[d.jsx(k2,{}),d.jsxs("a",{className:"soc2-badge",href:"https://security.buildwithfern.com/",children:[d.jsx(E2,{className:"soc2-badge-img"}),d.jsx("span",{className:"status-text",children:"Soc 2 Type II"})]})]})]}),d.jsxs("div",{className:"footer-links",children:[d.jsx("div",{className:"footer-bottom-text",children:" © 2025 Fern • Located in Brooklyn, NY "}),d.jsxs("div",{className:"footer-columns",children:[d.jsxs("div",{className:"footer-column",children:[d.jsx("h4",{className:"footer-column-title",children:"Documentation"}),d.jsxs("div",{className:"footer-column-links",children:[d.jsx("a",{href:"/learn/sdks/overview/introduction",className:"footer-link",children:"SDKs"}),d.jsx("a",{href:"/learn/docs/getting-started/overview",className:"footer-link",children:"Docs"}),d.jsx("a",{href:"/learn/ask-fern",className:"footer-link",children:"Ask Fern"}),d.jsx("a",{href:"/learn/cli-api-reference/cli-reference/overview",className:"footer-link",children:"CLI Reference"}),d.jsx("a",{href:"/learn/cli-api-reference/api-reference/overview",className:"footer-link",children:"API Reference"})]})]}),d.jsxs("div",{className:"footer-column",children:[d.jsx("h4",{className:"footer-column-title",children:"API Definitions"}),d.jsxs("div",{className:"footer-column-links",children:[d.jsx("a",{href:"/learn/api-definitions/openapi/overview",className:"footer-link",children:"OpenAPI"}),d.jsx("a",{href:"/learn/api-definitions/asyncapi/overview",className:"footer-link",children:"AsyncAPI"}),d.jsx("a",{href:"/learn/api-definitions/openrpc/overview",className:"footer-link",children:"OpenRPC"}),d.jsx("a",{href:"/learn/api-definitions/grpc/overview",className:"footer-link",children:"gRPC"}),d.jsx("a",{href:"/learn/api-definitions/ferndef/overview",className:"footer-link",children:"Fern Definition"})]})]}),d.jsxs("div",{className:"footer-column",children:[d.jsx("h4",{className:"footer-column-title",children:"Resources"}),d.jsxs("div",{className:"footer-column-links",children:[d.jsx("a",{href:"https://buildwithfern.com/blog",className:"footer-link",children:"Blog"}),d.jsx("a",{href:"learn/home#help",className:"footer-link",children:"Support"}),d.jsx("a",{href:"https://buildwithfern.com/pricing",className:"footer-link",children:"Pricing"}),d.jsx("a",{href:"https://buildwithfern.com/slack",className:"footer-link",children:"Slack"})]})]}),d.jsxs("div",{className:"footer-column",children:[d.jsx("h4",{className:"footer-column-title",children:"Company"}),d.jsxs("div",{className:"footer-column-links",children:[d.jsx("a",{href:"https://brandfetch.com/buildwithfern.com",className:"footer-link",children:"Brand Kit"}),d.jsx("a",{href:"https://buildwithfern.com/privacy-policy",className:"footer-link",children:"Privacy Policy"}),d.jsx("a",{href:"https://buildwithfern.com/terms-of-service",className:"footer-link",children:"Terms of Service"})]})]}),d.jsxs("div",{className:"footer-column-socials",children:[d.jsxs("a",{href:"https://github.com/fern-api/fern",className:"footer-link",children:[d.jsx(V2,{className:"footer-social-icon dark:hidden"}),d.jsx(L2,{className:"footer-social-icon hidden dark:block"})]}),d.jsxs("a",{href:"https://x.com/buildwithfern",className:"footer-link",children:[d.jsx(q2,{className:"footer-social-icon dark:hidden"}),d.jsx(W2,{className:"footer-social-icon hidden dark:block"})]}),d.jsxs("a",{href:"https://www.linkedin.com/company/buildwithfern",className:"footer-link",children:[d.jsx(S2,{className:"footer-social-icon dark:hidden"}),d.jsx(U2,{className:"footer-social-icon hidden dark:block"})]})]})]})]})]})]}),Ei="fern-footer",Ri=async()=>{if(!document.getElementById("footer")){const n=document.createElement("div");n.setAttribute("id","fern-footer-wrapper"),n.setAttribute("data-react-component","true");let t=document.getElementById(Ei);t||(t=document.createElement("div"),t.setAttribute("id",Ei),document.body.appendChild(t)),t.insertBefore(n,t.firstChild),tf(n).render(d.jsx(gf.StrictMode,{children:d.jsx(R2,{})})),t&&(t.style.display="block")}};window.addEventListener("load",async()=>{await Ri(),new MutationObserver(async e=>{e.some(t=>t.type==="childList"&&!document.getElementById("fern-footer-wrapper"))&&await Ri()}).observe(document.body,{childList:!0,subtree:!0})}); diff --git a/fern/products/api-def/api-def.yml b/fern/products/api-def/api-def.yml index 16ec2b7c..0ba6c449 100644 --- a/fern/products/api-def/api-def.yml +++ b/fern/products/api-def/api-def.yml @@ -1,12 +1,10 @@ navigation: - section: Overview contents: - - page: What is an API definition? + - page: What is an API Definition? path: ./pages/what-is-an-api-definition.mdx - - page: Project structure + - page: Project Structure path: ./pages/project-structure.mdx - - page: Overrides - path: ./pages/overrides.mdx - section: OpenAPI collapsed: true slug: openapi @@ -16,64 +14,47 @@ navigation: - page: Authentication path: ./openapi-pages/auth.mdx - page: Servers - path: ./openapi-pages/servers.mdx - - page: Sync your specification - path: ./openapi-pages/automation.mdx - slug: sync-your-open-api-specification + path: ./openapi-pages/servers.mdx - section: Endpoints slug: endpoints contents: - - page: HTTP JSON endpoints + - page: HTTP JSON Endpoints path: ./openapi-pages/endpoints/rest.mdx slug: http - page: Webhooks path: ./openapi-pages/webhooks.mdx - - page: Multipart form uploads + - page: Multipart Form Uploads path: ./openapi-pages/endpoints/multipart.mdx slug: multipart - - page: Server-sent events + - page: Server-Sent Events path: ./openapi-pages/endpoints/sse.mdx slug: sse - section: Extensions slug: extensions contents: - - page: Overview - path: ./openapi-pages/extensions/overview.md - - page: API version - path: ./openapi-pages/extensions/api-version.mdx - page: Audiences path: ./openapi-pages/extensions/audiences.mdx - - page: Availability - path: ./openapi-pages/extensions/availability.mdx - - page: Base path - path: ./openapi-pages/extensions/base-path.mdx - - page: Enum descriptions and names - path: ./openapi-pages/extensions/enums.mdx - - page: Request + response examples - path: ./openapi-pages/extensions/examples.mdx - - page: Global headers - path: ./openapi-pages/extensions/global-headers.mdx - - page: Ignoring elements - path: ./openapi-pages/extensions/ignore.mdx - - page: SDK method names + - page: SDK Method Names path: ./openapi-pages/extensions/method-names.mdx slug: method-names - - page: Parameter names + - page: Parameter Names path: ./openapi-pages/extensions/parameter-names.mdx - - page: Property names - path: ./openapi-pages/extensions/property-names.mdx - - page: Schema names - path: ./openapi-pages/extensions/schema-names.mdx - - page: Server names - path: ./openapi-pages/extensions/server-names.mdx - - section: Integrate your server framework + - page: Other + path: ./openapi-pages/extensions/others.mdx + slug: others + - section: Workflow & Automation + skip-slug: true + contents: + - page: Overlay Customizations + path: ./openapi-pages/overrides.mdx + - page: Sync your OpenAPI Specification + path: ./openapi-pages/automation.mdx + - section: Integrate your Server Framework slug: frameworks contents: - page: FastAPI path: ./openapi-pages/server-frameworks/fastapi.mdx slug: fastapi - - page: generators.yml reference - path: ./openapi-pages/reference/generators-reference.mdx - section: AsyncAPI collapsed: true slug: asyncapi @@ -83,50 +64,39 @@ navigation: - page: Authentication path: ./asyncapi-pages/auth.mdx - page: Servers - path: ./asyncapi-pages/servers.mdx - - page: Sync your specification - path: ./asyncapi-pages/automation.mdx - slug: sync-your-async-api-specification + path: ./asyncapi-pages/servers.mdx - section: Channels slug: channels contents: - - page: Publish/subscribe operations + - page: Publish/Subscribe Operations path: ./asyncapi-pages/channels/pubsub.mdx slug: pubsub - - page: Message formats + - page: Message Formats path: ./asyncapi-pages/channels/messages.mdx slug: messages - - page: Message bindings + - page: Message Bindings path: ./asyncapi-pages/channels/bindings.mdx slug: bindings - section: Extensions slug: extensions contents: - - page: Overview - path: ./asyncapi-pages/extensions/overview.md - page: Audiences path: ./asyncapi-pages/extensions/audiences.mdx - - page: Availability - path: ./asyncapi-pages/extensions/availability.mdx - - page: Error handling - path: ./asyncapi-pages/extensions/error-handling.mdx - - page: Request + response examples - path: ./asyncapi-pages/extensions/examples.mdx - - page: Ignoring elements - path: ./asyncapi-pages/extensions/ignore.mdx - - page: SDK method names + - page: SDK Method Names path: ./asyncapi-pages/extensions/method-names.mdx slug: method-names - - page: Pagination - path: ./asyncapi-pages/extensions/pagination.mdx - - page: Parameter names + - page: Parameter Names path: ./asyncapi-pages/extensions/parameter-names.mdx - - page: Retry behavior - path: ./asyncapi-pages/extensions/retry.mdx - - page: Server names - path: ./asyncapi-pages/extensions/server-name.mdx - - page: Streaming operations - path: ./asyncapi-pages/extensions/streaming.mdx + - page: Other + path: ./asyncapi-pages/extensions/others.mdx + slug: others + - section: Workflow & Automation + skip-slug: true + contents: + - page: Overlay Customizations + path: ./asyncapi-pages/overrides.mdx + - page: Sync your AsyncAPI Specification + path: ./asyncapi-pages/automation.mdx - section: OpenRPC collapsed: true slug: openrpc @@ -136,56 +106,39 @@ navigation: - page: Authentication path: ./openrpc-pages/auth.mdx - page: Servers - path: ./openrpc-pages/servers.mdx - - page: Sync your specification - path: ./openrpc-pages/automation.mdx - slug: sync-your-open-rpc-specification + path: ./openrpc-pages/servers.mdx - section: Methods slug: methods contents: - - page: JSON-RPC methods + - page: JSON-RPC Methods path: ./openrpc-pages/methods/rpc-methods.mdx slug: rpc-methods - page: Notifications path: ./openrpc-pages/methods/notifications.mdx slug: notifications - - page: Batch requests + - page: Batch Requests path: ./openrpc-pages/methods/batch.mdx slug: batch - section: Extensions slug: extensions contents: - - page: Overview - path: ./openrpc-pages/extensions/overview.md - page: Audiences path: ./openrpc-pages/extensions/audiences.mdx - - page: Availability - path: ./openrpc-pages/extensions/availability.mdx - - page: Base path - path: ./openrpc-pages/extensions/base-path.mdx - - page: Error handling - path: ./openrpc-pages/extensions/error-handling.mdx - - page: Request + response examples - path: ./openrpc-pages/extensions/examples.mdx - - page: Ignoring elements - path: ./openrpc-pages/extensions/ignore.mdx - - page: SDK method names + - page: SDK Method Names path: ./openrpc-pages/extensions/method-names.mdx slug: method-names - - page: Pagination - path: ./openrpc-pages/extensions/pagination.mdx - - page: Parameter names + - page: Parameter Names path: ./openrpc-pages/extensions/parameter-names.mdx - - page: Retry behavior - path: ./openrpc-pages/extensions/retry.mdx - - page: SDK group names - path: ./openrpc-pages/extensions/sdk-group-name.mdx - - page: Server names - path: ./openrpc-pages/extensions/server-name.mdx - - page: Streaming operations - path: ./openrpc-pages/extensions/streaming.mdx - - page: Timeout settings - path: ./openrpc-pages/extensions/timeout.mdx + - page: Other + path: ./openrpc-pages/extensions/others.mdx + slug: others + - section: Workflow & Automation + skip-slug: true + contents: + - page: Overlay Customizations + path: ./openrpc-pages/overrides.mdx + - page: Sync your OpenRPC Specification + path: ./openrpc-pages/automation.mdx - section: gRPC collapsed: true slug: grpc @@ -195,22 +148,39 @@ navigation: - page: Authentication path: ./grpc-pages/auth.mdx - page: Servers - path: ./grpc-pages/servers.mdx - - page: Sync your specification - path: ./grpc-pages/automation.mdx - slug: sync-your-g-rpc-specification + path: ./grpc-pages/servers.mdx - section: Services slug: services contents: - - page: gRPC services + - page: gRPC Services path: ./grpc-pages/services/grpc-services.mdx slug: grpc-services - page: Streaming path: ./grpc-pages/services/streaming.mdx slug: streaming - - page: Error handling + - page: Error Handling path: ./grpc-pages/services/errors.mdx slug: errors + - section: Extensions + slug: extensions + contents: + - page: Audiences + path: ./grpc-pages/extensions/audiences.mdx + - page: SDK Method Names + path: ./grpc-pages/extensions/method-names.mdx + slug: method-names + - page: Parameter Names + path: ./grpc-pages/extensions/parameter-names.mdx + - page: Other + path: ./grpc-pages/extensions/others.mdx + slug: others + - section: Workflow & Automation + skip-slug: true + contents: + - page: Overlay Customizations + path: ./grpc-pages/overrides.mdx + - page: Sync your gRPC Specification + path: ./grpc-pages/automation.mdx - section: Fern Definition collapsed: true slug: ferndef @@ -225,16 +195,16 @@ navigation: contents: - page: Overview path: ./ferndef-pages/endpoints.mdx - - page: HTTP JSON endpoints + - page: HTTP JSON Endpoints path: ./ferndef-pages/endpoints/rest.mdx slug: http - - page: Multipart form uploads + - page: Multipart Form Uploads path: ./ferndef-pages/endpoints/multipart.mdx slug: multipart - page: Bytes path: ./ferndef-pages/endpoints/bytes.mdx slug: bytes - - page: Server-sent events + - page: Server-Sent Events path: ./ferndef-pages/endpoints/sse.mdx slug: sse - section: Advanced @@ -255,14 +225,14 @@ navigation: path: ./ferndef-pages/audiences.mdx - page: Availability path: ./ferndef-pages/availability.mdx - - section: api.yml reference + - section: api.yml Reference slug: api-yml contents: - page: Overview path: ./ferndef-pages/api-yml/overview.mdx - page: Environments path: ./ferndef-pages/api-yml/environments.mdx - - page: Global headers + - page: Global Headers path: ./ferndef-pages/api-yml/global-configuration.mdx - page: Errors path: ./ferndef-pages/api-yml/errors.mdx @@ -271,7 +241,7 @@ navigation: contents: - page: Packages path: ./ferndef-pages/packages.mdx - - page: Depending on other APIs + - page: Depending on Other APIs path: ./ferndef-pages/depending-on-other-apis.mdx - page: Export to OpenAPI slug: export-openapi diff --git a/fern/products/api-def/asyncapi-def.yml b/fern/products/api-def/asyncapi-def.yml deleted file mode 100644 index 5ecf8281..00000000 --- a/fern/products/api-def/asyncapi-def.yml +++ /dev/null @@ -1,5 +0,0 @@ -navigation: - - page: AsyncAPI Definition Redirect Page - path: ./pages/asyncapi-empty.mdx - slug: empty-page - hidden: true diff --git a/fern/products/api-def/asyncapi-pages/extensions/availability.mdx b/fern/products/api-def/asyncapi-pages/extensions/availability.mdx deleted file mode 100644 index 9faa0120..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/availability.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Availability -description: Mark features as available in specific SDK versions using `x-fern-availability` extension ---- - -Mark features as available in specific SDK versions: - -```yaml title="asyncapi.yml" {6-8} -operations: - newFeature: - action: send - channel: - $ref: '#/channels/new~1feature' - x-fern-availability: - status: beta - message: "This feature is in beta and may change" -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/error-handling.mdx b/fern/products/api-def/asyncapi-pages/extensions/error-handling.mdx deleted file mode 100644 index 5350edc0..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/error-handling.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Error handling -description: Configure error handling for operations using `x-fern-error-handling` extension ---- - -Configure error handling for operations: - -```yaml title="asyncapi.yml" {6-16} -operations: - sendMessage: - action: send - channel: - $ref: '#/channels/messages' - x-fern-error-handling: - error_schema: - $ref: '#/components/schemas/MessageError' - error_status_codes: - - 400 - - 429 - - 500 - retry_on_errors: - - 429 - - 500 -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/examples.mdx b/fern/products/api-def/asyncapi-pages/extensions/examples.mdx deleted file mode 100644 index 0affa676..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/examples.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Request + response examples -description: Provide additional examples for better SDK documentation using `x-fern-examples` extension ---- - -Provide additional examples for better SDK documentation: - -```yaml title="asyncapi.yml" {8-20} -components: - messages: - UserEvent: - contentType: application/json - payload: - $ref: '#/components/schemas/User' - x-fern-examples: - - name: NewUserSignup - summary: Example of a new user signup event - payload: - id: "user_123" - email: "john@example.com" - name: "John Doe" - status: "active" - - name: UserDeactivation - summary: Example of user deactivation event - payload: - id: "user_456" - email: "jane@example.com" - name: "Jane Smith" - status: "inactive" -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/ignore.mdx b/fern/products/api-def/asyncapi-pages/extensions/ignore.mdx deleted file mode 100644 index 5a2a7627..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/ignore.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Ignoring operations, channels, or schemas -description: Skip reading specific AsyncAPI elements using `x-fern-ignore` extension ---- - -Use `x-fern-ignore` to exclude specific operations, channels, or schemas from SDK generation: - -```yaml title="asyncapi.yml" {6-7, 13-14} -operations: - debugOperation: - action: send - channel: - $ref: '#/channels/debug' - x-fern-ignore: true - summary: Debug operation (internal only) - -channels: - internal/debug: - address: internal/debug - x-fern-ignore: true - messages: - DebugMessage: - $ref: '#/components/messages/DebugMessage' -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/others.mdx b/fern/products/api-def/asyncapi-pages/extensions/others.mdx new file mode 100644 index 00000000..cbc7d15a --- /dev/null +++ b/fern/products/api-def/asyncapi-pages/extensions/others.mdx @@ -0,0 +1,160 @@ +--- +title: Other Extensions +subtitle: Additional Fern extensions for AsyncAPI specifications +--- + +Fern supports various extensions to enhance your AsyncAPI specifications and improve the generated SDKs and documentation. + +## `x-fern-ignore` + +Use `x-fern-ignore` to exclude specific operations, channels, or schemas from SDK generation: + +```yaml title="asyncapi.yml" {6-7, 13-14} +operations: + debugOperation: + action: send + channel: + $ref: '#/channels/debug' + x-fern-ignore: true + summary: Debug operation (internal only) + +channels: + internal/debug: + address: internal/debug + x-fern-ignore: true + messages: + DebugMessage: + $ref: '#/components/messages/DebugMessage' +``` + +## `x-fern-examples` + +Provide additional examples for better SDK documentation: + +```yaml title="asyncapi.yml" {8-20} +components: + messages: + UserEvent: + contentType: application/json + payload: + $ref: '#/components/schemas/User' + x-fern-examples: + - name: NewUserSignup + summary: Example of a new user signup event + payload: + id: "user_123" + email: "john@example.com" + name: "John Doe" + status: "active" + - name: UserDeactivation + summary: Example of user deactivation event + payload: + id: "user_456" + email: "jane@example.com" + name: "Jane Smith" + status: "inactive" +``` + +## `x-fern-pagination` + +Configure pagination for operations that return multiple results: + +```yaml title="asyncapi.yml" {6-11} +operations: + listUserEvents: + action: receive + channel: + $ref: '#/channels/user~1events' + x-fern-pagination: + cursor: next_cursor + results: events + next_cursor: pagination.next_cursor + has_next_page: pagination.has_next_page +``` + +## `x-fern-retry` + +Configure retry behavior for operations: + +```yaml title="asyncapi.yml" {6-10} +operations: + sendCriticalAlert: + action: send + channel: + $ref: '#/channels/alerts' + x-fern-retry: + max_attempts: 3 + exponential_backoff: true + initial_delay: 1000 + max_delay: 30000 +``` + +## `x-fern-streaming` + +Mark operations as streaming for appropriate SDK generation: + +```yaml title="asyncapi.yml" {6-9} +operations: + streamEvents: + action: receive + channel: + $ref: '#/channels/event~1stream' + x-fern-streaming: + type: server_sent_events + termination: client_closes +``` + +## `x-fern-error-handling` + +Configure error handling for operations: + +```yaml title="asyncapi.yml" {6-16} +operations: + sendMessage: + action: send + channel: + $ref: '#/channels/messages' + x-fern-error-handling: + error_schema: + $ref: '#/components/schemas/MessageError' + error_status_codes: + - 400 + - 429 + - 500 + retry_on_errors: + - 429 + - 500 +``` + +## `x-fern-server-name` + +Specify custom names for servers: + +```yaml title="asyncapi.yml" {4-5} +servers: + production: + host: api.yourcompany.com + x-fern-server-name: Production + protocol: wss + staging: + host: staging.api.yourcompany.com + x-fern-server-name: Staging + protocol: wss +``` + +## `x-fern-availability` + +Mark features as available in specific SDK versions: + +```yaml title="asyncapi.yml" {6-8} +operations: + newFeature: + action: send + channel: + $ref: '#/channels/new~1feature' + x-fern-availability: + status: beta + message: "This feature is in beta and may change" +``` + +These extensions help you create more robust and user-friendly SDKs while maintaining full control over the generated code structure and behavior. \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/overview.md b/fern/products/api-def/asyncapi-pages/extensions/overview.md deleted file mode 100644 index 39c7be3c..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/overview.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Overview of AsyncAPI extensions -description: Learn about Fern's AsyncAPI extensions for generating higher-quality SDKs ---- - -Fern supports a variety of AsyncAPI extensions that enhance your API specification and generate higher-quality SDKs. - -You can apply these extensions in two ways: by overlaying them in separate override files or by embedding them directly in your AsyncAPI specification. See [Overrides](/api-definitions/overview/overrides) for more information. - -## Available extensions - -The table below shows all available extensions and links to detailed documentation for each one. - -| Extension | Description | -| --- | --- | -| [`x-fern-ignore`](./ignoring-elements) | Skip reading specific operations, channels, or schemas | -| [`x-fern-examples`](./request-response-examples) | Provide additional examples for better SDK documentation | -| [`x-fern-pagination`](./pagination) | Configure pagination for operations that return multiple results | -| [`x-fern-retry`](./retry-behavior) | Configure retry behavior for operations | -| [`x-fern-streaming`](./streaming-operations) | Mark operations as streaming for appropriate SDK generation | -| [`x-fern-error-handling`](./error-handling) | Configure error handling for operations | -| [`x-fern-server-name`](./server-names) | Specify custom names for servers | -| [`x-fern-availability`](./availability) | Mark features as available in specific SDK versions | - - - If there's an extension you want that doesn't already exist, file an [issue](https://github.com/fern-api/fern/issues/new) to start a discussion about it. - \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/pagination.mdx b/fern/products/api-def/asyncapi-pages/extensions/pagination.mdx deleted file mode 100644 index 7e40ba9c..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/pagination.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Pagination -description: Configure pagination for operations that return multiple results using `x-fern-pagination` extension ---- - -Configure pagination for operations that return multiple results: - -```yaml title="asyncapi.yml" {6-11} -operations: - listUserEvents: - action: receive - channel: - $ref: '#/channels/user~1events' - x-fern-pagination: - cursor: next_cursor - results: events - next_cursor: pagination.next_cursor - has_next_page: pagination.has_next_page -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/retry.mdx b/fern/products/api-def/asyncapi-pages/extensions/retry.mdx deleted file mode 100644 index 58cd3d99..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/retry.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Retry behavior -description: Configure retry behavior for operations using `x-fern-retry` extension ---- - -Configure retry behavior for operations: - -```yaml title="asyncapi.yml" {6-10} -operations: - sendCriticalAlert: - action: send - channel: - $ref: '#/channels/alerts' - x-fern-retry: - max_attempts: 3 - exponential_backoff: true - initial_delay: 1000 - max_delay: 30000 -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/server-name.mdx b/fern/products/api-def/asyncapi-pages/extensions/server-name.mdx deleted file mode 100644 index 085298ca..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/server-name.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Server names -description: Specify custom names for servers using `x-fern-server-name` extension ---- - -Specify custom names for servers: - -```yaml title="asyncapi.yml" {4-5} -servers: - production: - host: api.yourcompany.com - x-fern-server-name: Production - protocol: wss - staging: - host: staging.api.yourcompany.com - x-fern-server-name: Staging - protocol: wss -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/extensions/streaming.mdx b/fern/products/api-def/asyncapi-pages/extensions/streaming.mdx deleted file mode 100644 index fd66cd5f..00000000 --- a/fern/products/api-def/asyncapi-pages/extensions/streaming.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Streaming operations -description: Mark operations as streaming for appropriate SDK generation using `x-fern-streaming` extension ---- - -Mark operations as streaming for appropriate SDK generation: - -```yaml title="asyncapi.yml" {6-9} -operations: - streamEvents: - action: receive - channel: - $ref: '#/channels/event~1stream' - x-fern-streaming: - type: server_sent_events - termination: client_closes -``` \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/overrides.mdx b/fern/products/api-def/asyncapi-pages/overrides.mdx new file mode 100644 index 00000000..0e76d5f1 --- /dev/null +++ b/fern/products/api-def/asyncapi-pages/overrides.mdx @@ -0,0 +1,168 @@ +--- +title: Overlay Customizations +subtitle: Use overlay files to modify your AsyncAPI specification without editing the original +--- + +Overlays allow you to modify your AsyncAPI specification without directly editing the original file. This is useful for: +- Adding Fern-specific extensions +- Customizing documentation +- Adding examples and descriptions +- Overriding specific properties + +## Configure overlays + +To use overlays, add them to your `generators.yml` file: + +```yaml title="generators.yml" {3-5} +api: + specs: + - spec: asyncapi.yml + overlays: + - overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + +## Overlay file structure + +Overlay files follow the [OpenAPI Overlay Specification](https://spec.openapis.org/overlay/v1.0.0) format: + +```yaml title="overlay.yml" +overlay: 1.0.0 +info: + title: AsyncAPI Fern Extensions + version: 1.0.0 +actions: + - target: $.operations.sendNotification + update: + x-fern-sdk-method-name: notify + summary: Send a notification to a user + - target: $.channels['user/events'] + update: + description: Channel for user-related events + x-fern-audiences: + - public +``` + +## Add method names + +Override SDK method names for better developer experience: + +```yaml title="overlay.yml" {7-9} +overlay: 1.0.0 +info: + title: SDK Method Names + version: 1.0.0 +actions: + - target: $.operations.subscribeToUserEvents + update: + x-fern-sdk-method-name: onUserEvent + summary: Subscribe to user events with callback + - target: $.operations.publishOrderUpdate + update: + x-fern-sdk-method-name: updateOrder + summary: Publish order status update +``` + +## Add examples + +Enhance your specification with examples: + +```yaml title="overlay.yml" {7-17} +overlay: 1.0.0 +info: + title: Message Examples + version: 1.0.0 +actions: + - target: $.components.messages.UserSignup + update: + examples: + - name: StandardSignup + summary: Regular user signup + payload: + id: "user_123" + email: "john@example.com" + name: "John Doe" + signupSource: "web" + timestamp: "2024-01-15T10:30:00Z" +``` + +## Filter with audiences + +Add audience filtering to operations and channels: + +```yaml title="overlay.yml" {7-9, 12-14} +overlay: 1.0.0 +info: + title: Audience Filtering + version: 1.0.0 +actions: + - target: $.operations.adminAlert + update: + x-fern-audiences: + - admin + - target: $.channels['internal/debug'] + update: + x-fern-audiences: + - internal +``` + +## Add documentation + +Enhance descriptions and documentation: + +```yaml title="overlay.yml" {7-11} +overlay: 1.0.0 +info: + title: Enhanced Documentation + version: 1.0.0 +actions: + - target: $.operations.sendMessage + update: + description: | + Send a message to the specified channel. This operation supports + real-time delivery with automatic retry on failure. Messages are + guaranteed to be delivered at least once. + summary: Send message with delivery guarantees +``` + +## Server configurations + +Add server-specific configurations: + +```yaml title="overlay.yml" {7-11} +overlay: 1.0.0 +info: + title: Server Extensions + version: 1.0.0 +actions: + - target: $.servers.production + update: + x-fern-server-name: Production + description: Production environment with high availability + bindings: + ws: + headers: + type: object + properties: + X-API-Version: + type: string + const: "v1" +``` + +## Multiple overlays + +You can apply multiple overlay files in sequence: + +```yaml title="generators.yml" {4-7} +api: + specs: + - spec: asyncapi.yml + overlays: + - base-overlay.yml + - sdk-overlay.yml + - docs-overlay.yml +``` + +Overlays are applied in order, allowing you to build up customizations incrementally while keeping your original AsyncAPI specification clean and focused. \ No newline at end of file diff --git a/fern/products/api-def/asyncapi-pages/overview.mdx b/fern/products/api-def/asyncapi-pages/overview.mdx index c3cecaca..e1133708 100644 --- a/fern/products/api-def/asyncapi-pages/overview.mdx +++ b/fern/products/api-def/asyncapi-pages/overview.mdx @@ -1,16 +1,14 @@ --- title: What is an AsyncAPI Specification? -description: AsyncAPI is a standard for documenting event-driven APIs +subtitle: AsyncAPI is a standard for documenting event-driven APIs --- - - Fern only supports AsyncAPI SDK generation for TypeScript and Python. - - The AsyncAPI Specification is a framework used by developers to document event-driven APIs. The specification is written in JSON or YAML and contains all of your channels, messages, schemas, and authentication schemes. Fern is compatible with AsyncAPI specification [v2.6.0](https://www.asyncapi.com/docs/reference/specification/v2.6.0) and [v3.0.0](https://www.asyncapi.com/docs/reference/specification/v3.0.0). + Considering options to generate an AsyncAPI spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) + Below is an example of an AsyncAPI file: ```yaml asyncapi.yml @@ -109,9 +107,7 @@ components: - message ``` -## Set up your fern folder - - Considering options to generate an AsyncAPI spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) +## Setup your fern folder Start by initializing your fern folder with an AsyncAPI spec diff --git a/fern/products/api-def/ferndef-def.yml b/fern/products/api-def/ferndef-def.yml deleted file mode 100644 index b69e2330..00000000 --- a/fern/products/api-def/ferndef-def.yml +++ /dev/null @@ -1,5 +0,0 @@ -navigation: - - page: Fern Definition Redirect Page - path: ./pages/ferndef-empty.mdx - slug: empty-page - hidden: true diff --git a/fern/products/api-def/ferndef-pages/audiences.mdx b/fern/products/api-def/ferndef-pages/audiences.mdx index e916711f..20f2876a 100644 --- a/fern/products/api-def/ferndef-pages/audiences.mdx +++ b/fern/products/api-def/ferndef-pages/audiences.mdx @@ -3,7 +3,7 @@ title: Audiences in Fern Definition subtitle: Use audiences in your Fern Definition to segment your API for different groups of consumers. --- -Audiences are a useful tool for segmenting your API for different consumers. You can configure your Fern Docs to publish documentation specific to an `Audience`. You can use [audiences in your OpenAPI Specification](/learn/api-definitions/openapi/extensions/audiences), too. +Audiences are a useful tool for segmenting your API for different consumers. You can configure your Fern Docs to publish documentation specific to an `Audience`. You can use [audiences in your OpenAPI Specification](/learn/api-definition/openapi/audiences), too. Common examples of audiences include: diff --git a/fern/products/api-def/ferndef-pages/overview.mdx b/fern/products/api-def/ferndef-pages/overview.mdx index be9f2798..25b04a2d 100644 --- a/fern/products/api-def/ferndef-pages/overview.mdx +++ b/fern/products/api-def/ferndef-pages/overview.mdx @@ -1,6 +1,6 @@ --- title: What is a Fern Definition? -description: "A Fern Definition is a set of YAML files that describe your API." +subtitle: "A Fern Definition is a set of YAML files that describe your API." --- A Fern Definition is a set of YAML files that are the single source of truth for your API. You check your Fern Definition into your repo, diff --git a/fern/products/api-def/ferndef-pages/types.mdx b/fern/products/api-def/ferndef-pages/types.mdx index 6823bdbb..f623832d 100644 --- a/fern/products/api-def/ferndef-pages/types.mdx +++ b/fern/products/api-def/ferndef-pages/types.mdx @@ -282,7 +282,7 @@ interface Person { ### Validating types -You can add validation constraints to your types (both aliases and references) to ensure data integrity. These validation constraints exist in your API definition and are enforced by the server, but the generated client SDKs don't include validation logic. +You can add validation constraints to your types (both aliases and references) to ensure data integrity. Validation constracts are automatically enforced in generated SDKs. ```yaml {8-11, 15-17} @@ -305,6 +305,30 @@ types: max: 150 ``` + + +```typescript +interface Person { + /** The person's full name */ + name: string; + /** Age in years */ + age: number; +} + +// Validation is automatically enforced when creating Person objects +const client = new YourApiClient(); +try { + const person = await client.createPerson({ + name: "A", // Fails minLength validation + age: -5, // Fails min validation + }); +} catch (error) { + if (error instanceof ValidationError) { + console.log(`Validation failed: ${error.message}`); + } +} +``` + diff --git a/fern/products/api-def/grpc-def.yml b/fern/products/api-def/grpc-def.yml deleted file mode 100644 index 0c392980..00000000 --- a/fern/products/api-def/grpc-def.yml +++ /dev/null @@ -1,5 +0,0 @@ -navigation: - - page: gRPC Definition Redirect Page - path: ./pages/grpc-empty.mdx - slug: empty-page - hidden: true diff --git a/fern/products/api-def/grpc-pages/extensions/audiences.mdx b/fern/products/api-def/grpc-pages/extensions/audiences.mdx new file mode 100644 index 00000000..8c18f6ac --- /dev/null +++ b/fern/products/api-def/grpc-pages/extensions/audiences.mdx @@ -0,0 +1,360 @@ +--- +title: Use audiences to filter your API +subtitle: Use `x-fern-audiences` to filter to relevant services, methods and messages +--- + +Audiences are a useful tool for segmenting your gRPC API for different consumers. Common examples of audiences include `public` +and `beta`. + + + Remember to filter your SDKs and Docs after specifying audiences. If **no audiences** are specified, + nothing will be filtered. + + + + +The following example configures the SDK to filter to the `public` audience: + +```yaml title="generators.yml" {3-4} +groups: + sdks: + audiences: + - public + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + + + +The following example configures the docs to filter to the `public` audience: + +```yaml title="docs.yml" {3-4} +navigation: + - api: API Reference + audiences: + - public +``` + + + + + +## Filter services + +Add `x-fern-audiences` to services to control which services are included for specific audiences: + +```protobuf title="user_service.proto" +syntax = "proto3"; + +package userservice.v1; + +// Public user service available to all clients +service UserService { + option (x_fern_audiences) = "public"; + + rpc GetUser(GetUserRequest) returns (User); + rpc CreateUser(CreateUserRequest) returns (User); +} + +// Internal admin service for administrative operations +service AdminService { + option (x_fern_audiences) = "admin"; + + rpc ListAllUsers(ListAllUsersRequest) returns (ListAllUsersResponse); + rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty); + rpc BanUser(BanUserRequest) returns (google.protobuf.Empty); +} +``` + +## Filter individual methods + +You can filter specific methods within services: + +```protobuf title="mixed_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Public method available to all + rpc GetUser(GetUserRequest) returns (User) { + option (x_fern_audiences) = "public"; + } + + // Beta method only for beta testers + rpc GetUserAnalytics(GetUserAnalyticsRequest) returns (UserAnalytics) { + option (x_fern_audiences) = "beta"; + } + + // Internal method for debugging + rpc GetUserDebugInfo(GetUserDebugRequest) returns (UserDebugInfo) { + option (x_fern_audiences) = "internal"; + } +} +``` + +## Filter message fields + +Filter specific fields within message types: + +```protobuf title="user_messages.proto" +syntax = "proto3"; + +package userservice.v1; + +message User { + string id = 1; // Available to all audiences + string email = 2; // Available to all audiences + string name = 3; // Available to all audiences + + // Admin-only fields + string internal_id = 4 [(x_fern_audiences) = "admin"]; + repeated string permissions = 5 [(x_fern_audiences) = "admin"]; + google.protobuf.Timestamp created_at = 6 [(x_fern_audiences) = "admin"]; + + // Debug-only fields + map debug_metadata = 7 [(x_fern_audiences) = "debug"]; + string session_id = 8 [(x_fern_audiences) = "debug"]; +} +``` + +## Filter entire messages + +Filter entire message types to different audiences: + +```protobuf title="filtered_messages.proto" +syntax = "proto3"; + +package userservice.v1; + +// Public user data +message PublicUser { + option (x_fern_audiences) = "public"; + + string id = 1; + string name = 2; + string avatar_url = 3; +} + +// Extended user data for authenticated users +message AuthenticatedUser { + option (x_fern_audiences) = "authenticated"; + + string id = 1; + string name = 2; + string email = 3; + string phone = 4; + UserPreferences preferences = 5; +} + +// Full user data for administrators +message AdminUser { + option (x_fern_audiences) = "admin"; + + string id = 1; + string name = 2; + string email = 3; + string phone = 4; + UserPreferences preferences = 5; + repeated string roles = 6; + repeated Permission permissions = 7; + google.protobuf.Timestamp created_at = 8; + google.protobuf.Timestamp last_login = 9; + string created_by = 10; +} +``` + +## Filter enums and enum values + +Filter enum values based on audience: + +```protobuf title="user_enums.proto" +syntax = "proto3"; + +package userservice.v1; + +enum UserStatus { + USER_STATUS_UNSPECIFIED = 0; + + // Public statuses + USER_STATUS_ACTIVE = 1 [(x_fern_audiences) = "public"]; + USER_STATUS_INACTIVE = 2 [(x_fern_audiences) = "public"]; + + // Admin-only statuses + USER_STATUS_SUSPENDED = 3 [(x_fern_audiences) = "admin"]; + USER_STATUS_BANNED = 4 [(x_fern_audiences) = "admin"]; + USER_STATUS_PENDING_VERIFICATION = 5 [(x_fern_audiences) = "admin"]; + + // Internal debugging statuses + USER_STATUS_DEBUG = 6 [(x_fern_audiences) = "debug"]; + USER_STATUS_TEST = 7 [(x_fern_audiences) = "debug"]; +} + +enum OperationType { + OPERATION_TYPE_UNSPECIFIED = 0; + + // Available to beta users + OPERATION_TYPE_EXPERIMENTAL_FEATURE = 1 [(x_fern_audiences) = "beta"]; + OPERATION_TYPE_ADVANCED_ANALYTICS = 2 [(x_fern_audiences) = "beta"]; + + // Internal operations + OPERATION_TYPE_SYSTEM_MAINTENANCE = 3 [(x_fern_audiences) = "internal"]; +} +``` + +## Request/Response filtering + +Filter request and response messages based on audience: + +```protobuf title="request_response.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Method with different request/response based on audience + rpc GetUserProfile(GetUserProfileRequest) returns (GetUserProfileResponse); +} + +message GetUserProfileRequest { + string user_id = 1; + + // Admin can request additional data + bool include_internal_data = 2 [(x_fern_audiences) = "admin"]; + bool include_audit_log = 3 [(x_fern_audiences) = "admin"]; + + // Debug fields + bool include_debug_info = 4 [(x_fern_audiences) = "debug"]; +} + +message GetUserProfileResponse { + PublicUserProfile public_profile = 1; // Always included + + AdminUserProfile admin_profile = 2 [(x_fern_audiences) = "admin"]; // Admin only + repeated AuditLogEntry audit_log = 3 [(x_fern_audiences) = "admin"]; // Admin only + + DebugInfo debug_info = 4 [(x_fern_audiences) = "debug"]; // Debug only +} +``` + +## Conditional method definitions + +Use audiences to expose different versions of methods: + +```protobuf title="conditional_methods.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Basic user creation for public + rpc CreateUser(CreateUserRequest) returns (User) { + option (x_fern_audiences) = "public"; + } + + // Enhanced user creation for admin + rpc CreateUserWithPermissions(CreateUserWithPermissionsRequest) returns (AdminUser) { + option (x_fern_audiences) = "admin"; + } + + // Bulk user creation for enterprise + rpc BulkCreateUsers(BulkCreateUsersRequest) returns (BulkCreateUsersResponse) { + option (x_fern_audiences) = "enterprise"; + } + + // Beta features + rpc CreateUserWithAI(CreateUserWithAIRequest) returns (User) { + option (x_fern_audiences) = "beta"; + } +} +``` + +## Streaming method filtering + +Filter streaming methods by audience: + +```protobuf title="streaming_methods.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserStreamingService { + // Public event streaming + rpc StreamUserEvents(StreamUserEventsRequest) returns (stream PublicUserEvent) { + option (x_fern_audiences) = "public"; + } + + // Admin event streaming with more details + rpc StreamAdminEvents(StreamAdminEventsRequest) returns (stream AdminEvent) { + option (x_fern_audiences) = "admin"; + } + + // Internal debugging stream + rpc StreamDebugEvents(StreamDebugEventsRequest) returns (stream DebugEvent) { + option (x_fern_audiences) = "debug"; + } +} +``` + +## Multiple audience support + +Assign multiple audiences to services or methods: + +```protobuf title="multiple_audiences.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Available to both public and authenticated users + rpc GetPublicUserInfo(GetPublicUserInfoRequest) returns (PublicUserInfo) { + option (x_fern_audiences) = "public,authenticated"; + } + + // Available to admin and support staff + rpc GetUserSupportInfo(GetUserSupportInfoRequest) returns (UserSupportInfo) { + option (x_fern_audiences) = "admin,support"; + } + + // Available to beta and internal users + rpc TestNewFeature(TestNewFeatureRequest) returns (TestNewFeatureResponse) { + option (x_fern_audiences) = "beta,internal"; + } +} +``` + +## Using custom extensions + +Define custom Fern extensions for audience filtering: + +```protobuf title="custom_extensions.proto" +syntax = "proto3"; + +package userservice.v1; + +import "google/protobuf/descriptor.proto"; + +// Define custom option for audience filtering +extend google.protobuf.ServiceOptions { + string x_fern_audiences = 50001; +} + +extend google.protobuf.MethodOptions { + string x_fern_audiences = 50002; +} + +extend google.protobuf.FieldOptions { + string x_fern_audiences = 50003; +} + +extend google.protobuf.MessageOptions { + string x_fern_audiences = 50004; +} + +extend google.protobuf.EnumValueOptions { + string x_fern_audiences = 50005; +} +``` + +This allows you to create different views of the same gRPC API for different types of consumers, ensuring each audience only sees the services, methods, and data relevant to their use case. \ No newline at end of file diff --git a/fern/products/api-def/grpc-pages/extensions/method-names.mdx b/fern/products/api-def/grpc-pages/extensions/method-names.mdx new file mode 100644 index 00000000..3fe83e3a --- /dev/null +++ b/fern/products/api-def/grpc-pages/extensions/method-names.mdx @@ -0,0 +1,330 @@ +--- +title: SDK Method Names +subtitle: Use `x-fern-sdk-method-name` to customize SDK method names for gRPC methods +--- + +By default, Fern generates SDK method names based on your gRPC service and method names. You can override this behavior using the `x-fern-sdk-method-name` extension. + +## Customize method names + +Use `x-fern-sdk-method-name` to specify custom method names for your gRPC methods: + +```protobuf title="user_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Customize the SDK method name + rpc GetUserById(GetUserByIdRequest) returns (User) { + option (x_fern_sdk_method_name) = "getUser"; + } + + // Another customized method name + rpc CreateNewUser(CreateNewUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "create"; + } + + // Remove redundant service name from method + rpc UpdateUserProfile(UpdateUserProfileRequest) returns (User) { + option (x_fern_sdk_method_name) = "updateProfile"; + } +} +``` + +This will generate SDK methods like: + +```typescript +// Instead of client.userService.getUserById() +const user = await client.userService.getUser({ id: "user_123" }); + +// Instead of client.userService.createNewUser() +const newUser = await client.userService.create({ userData: {...} }); + +// Instead of client.userService.updateUserProfile() +const updatedUser = await client.userService.updateProfile({ profileData: {...} }); +``` + +## Method naming conventions + +Follow these conventions when naming SDK methods: + +### CRUD operations +Use standard CRUD naming for common operations: + +```protobuf title="crud_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc CreateUser(CreateUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "create"; + } + + rpc GetUser(GetUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "get"; + } + + rpc UpdateUser(UpdateUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "update"; + } + + rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) { + option (x_fern_sdk_method_name) = "delete"; + } + + rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { + option (x_fern_sdk_method_name) = "list"; + } +} +``` + +### Search and query operations +Use descriptive names for search operations: + +```protobuf title="search_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc SearchUsers(SearchUsersRequest) returns (SearchUsersResponse) { + option (x_fern_sdk_method_name) = "search"; + } + + rpc FindUserByEmail(FindUserByEmailRequest) returns (User) { + option (x_fern_sdk_method_name) = "findByEmail"; + } + + rpc QueryUsersByRole(QueryUsersByRoleRequest) returns (QueryUsersResponse) { + option (x_fern_sdk_method_name) = "queryByRole"; + } +} +``` + +### Action operations +Use action-oriented names for business operations: + +```protobuf title="action_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc ActivateUserAccount(ActivateUserAccountRequest) returns (User) { + option (x_fern_sdk_method_name) = "activate"; + } + + rpc DeactivateUserAccount(DeactivateUserAccountRequest) returns (User) { + option (x_fern_sdk_method_name) = "deactivate"; + } + + rpc ResetUserPassword(ResetUserPasswordRequest) returns (ResetPasswordResponse) { + option (x_fern_sdk_method_name) = "resetPassword"; + } + + rpc SendVerificationEmail(SendVerificationEmailRequest) returns (google.protobuf.Empty) { + option (x_fern_sdk_method_name) = "sendVerification"; + } +} +``` + +## Language-specific method names + +You can specify different method names for different programming languages: + +```protobuf title="language_specific.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc GetUserPreferences(GetUserPreferencesRequest) returns (UserPreferences) { + option (x_fern_sdk_method_name_python) = "get_preferences"; + option (x_fern_sdk_method_name_typescript) = "getPreferences"; + option (x_fern_sdk_method_name_go) = "GetPreferences"; + option (x_fern_sdk_method_name_java) = "getPreferences"; + option (x_fern_sdk_method_name_csharp) = "GetPreferences"; + } + + rpc UpdateUserPreferences(UpdateUserPreferencesRequest) returns (UserPreferences) { + option (x_fern_sdk_method_name_python) = "update_preferences"; + option (x_fern_sdk_method_name_typescript) = "updatePreferences"; + option (x_fern_sdk_method_name_go) = "UpdatePreferences"; + option (x_fern_sdk_method_name_java) = "updatePreferences"; + option (x_fern_sdk_method_name_csharp) = "UpdatePreferences"; + } +} +``` + +## Streaming method names + +For streaming methods, use appropriate naming: + +```protobuf title="streaming_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserStreamingService { + // Server streaming + rpc StreamUserEvents(StreamUserEventsRequest) returns (stream UserEvent) { + option (x_fern_sdk_method_name) = "streamEvents"; + } + + // Client streaming + rpc UploadUserData(stream UploadUserDataRequest) returns (UploadUserDataResponse) { + option (x_fern_sdk_method_name) = "upload"; + } + + // Bidirectional streaming + rpc ChatWithUser(stream ChatMessage) returns (stream ChatMessage) { + option (x_fern_sdk_method_name) = "chat"; + } + + // Real-time notifications + rpc SubscribeToNotifications(SubscribeRequest) returns (stream Notification) { + option (x_fern_sdk_method_name) = "subscribe"; + } +} +``` + +## Service-level naming + +Customize the service name for better SDK organization: + +```protobuf title="service_naming.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserManagementService { + option (x_fern_sdk_service_name) = "users"; + + rpc CreateUser(CreateUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "create"; + } + + rpc GetUser(GetUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "get"; + } +} + +service AuthenticationService { + option (x_fern_sdk_service_name) = "auth"; + + rpc LoginUser(LoginUserRequest) returns (LoginResponse) { + option (x_fern_sdk_method_name) = "login"; + } + + rpc LogoutUser(LogoutUserRequest) returns (google.protobuf.Empty) { + option (x_fern_sdk_method_name) = "logout"; + } +} +``` + +This generates cleaner SDK interfaces: + +```typescript +// Instead of client.userManagementService.createUser() +await client.users.create({ userData: {...} }); + +// Instead of client.authenticationService.loginUser() +await client.auth.login({ credentials: {...} }); +``` + +## Handling method overloading + +For services with similar methods, use descriptive names to avoid conflicts: + +```protobuf title="overloaded_methods.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Get user by ID + rpc GetUser(GetUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "get"; + } + + // Get user by email + rpc GetUserByEmail(GetUserByEmailRequest) returns (User) { + option (x_fern_sdk_method_name) = "getByEmail"; + } + + // Get user by username + rpc GetUserByUsername(GetUserByUsernameRequest) returns (User) { + option (x_fern_sdk_method_name) = "getByUsername"; + } + + // Get multiple users + rpc GetUsers(GetUsersRequest) returns (GetUsersResponse) { + option (x_fern_sdk_method_name) = "getMany"; + } +} +``` + +## Async method naming + +For long-running operations, consider async naming: + +```protobuf title="async_methods.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Quick operation + rpc GetUser(GetUserRequest) returns (User) { + option (x_fern_sdk_method_name) = "get"; + } + + // Long-running operation + rpc GenerateUserReport(GenerateUserReportRequest) returns (Operation) { + option (x_fern_sdk_method_name) = "generateReportAsync"; + } + + // Batch operation + rpc BatchUpdateUsers(BatchUpdateUsersRequest) returns (Operation) { + option (x_fern_sdk_method_name) = "batchUpdateAsync"; + } +} +``` + +## Grouping related methods + +Use consistent naming for related operations: + +```protobuf title="grouped_methods.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + // Profile operations + rpc GetUserProfile(GetUserProfileRequest) returns (UserProfile) { + option (x_fern_sdk_method_name) = "getProfile"; + } + + rpc UpdateUserProfile(UpdateUserProfileRequest) returns (UserProfile) { + option (x_fern_sdk_method_name) = "updateProfile"; + } + + rpc DeleteUserProfile(DeleteUserProfileRequest) returns (google.protobuf.Empty) { + option (x_fern_sdk_method_name) = "deleteProfile"; + } + + // Settings operations + rpc GetUserSettings(GetUserSettingsRequest) returns (UserSettings) { + option (x_fern_sdk_method_name) = "getSettings"; + } + + rpc UpdateUserSettings(UpdateUserSettingsRequest) returns (UserSettings) { + option (x_fern_sdk_method_name) = "updateSettings"; + } +} +``` + +This ensures method names follow the conventions of each target language while maintaining clear and intuitive APIs for developers. \ No newline at end of file diff --git a/fern/products/api-def/grpc-pages/extensions/others.mdx b/fern/products/api-def/grpc-pages/extensions/others.mdx new file mode 100644 index 00000000..56d7dbf7 --- /dev/null +++ b/fern/products/api-def/grpc-pages/extensions/others.mdx @@ -0,0 +1,403 @@ +--- +title: Other Extensions +subtitle: Additional Fern extensions for gRPC specifications +--- + +Fern supports various extensions to enhance your gRPC specifications and improve the generated SDKs and documentation. + +## `x-fern-ignore` + +Use `x-fern-ignore` to exclude specific services, methods or messages from SDK generation: + +```protobuf title="user_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc GetUser(GetUserRequest) returns (User); + + // Exclude internal debugging method + rpc DebugUserData(DebugUserRequest) returns (DebugUserResponse) { + option (x_fern_ignore) = true; + } + + // Exclude experimental method + rpc ExperimentalFeature(ExperimentalRequest) returns (ExperimentalResponse) { + option (x_fern_ignore) = true; + } +} + +// Exclude internal message from SDK +message InternalUserData { + option (x_fern_ignore) = true; + + string internal_id = 1; + repeated string debug_flags = 2; + map system_metadata = 3; +} +``` + +## `x-fern-examples` + +Provide additional examples for better SDK documentation: + +```protobuf title="user_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc CreateUser(CreateUserRequest) returns (User) { + option (x_fern_examples) = '{ + "StandardUser": { + "description": "Create a regular user account", + "request": { + "email": "john@example.com", + "name": "John Doe", + "age": 30, + "preferences": { + "theme": "dark", + "notifications": true + } + }, + "response": { + "id": "user_123", + "email": "john@example.com", + "name": "John Doe", + "created_at": "2024-01-15T10:30:00Z" + } + }, + "AdminUser": { + "description": "Create an admin user with special permissions", + "request": { + "email": "admin@example.com", + "name": "Admin User", + "role": "admin", + "permissions": ["read", "write", "delete"] + }, + "response": { + "id": "user_456", + "email": "admin@example.com", + "name": "Admin User", + "role": "admin", + "created_at": "2024-01-15T10:30:00Z" + } + } + }'; + } +} +``` + +## `x-fern-pagination` + +Configure pagination for methods that return lists: + +```protobuf title="pagination_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { + option (x_fern_pagination) = '{ + "cursor": "page_token", + "results": "users", + "next_cursor": "next_page_token", + "has_next_page": "has_more" + }'; + } +} + +message ListUsersRequest { + int32 page_size = 1; + string page_token = 2; + string filter = 3; +} + +message ListUsersResponse { + repeated User users = 1; + string next_page_token = 2; + bool has_more = 3; + int32 total_count = 4; +} +``` + +## `x-fern-retry` + +Configure retry behavior for methods: + +```protobuf title="retry_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc ProcessPayment(ProcessPaymentRequest) returns (PaymentResult) { + option (x_fern_retry) = '{ + "max_attempts": 3, + "exponential_backoff": true, + "initial_delay_ms": 1000, + "max_delay_ms": 30000, + "retry_on_status": ["UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"] + }'; + } + + rpc UploadFile(UploadFileRequest) returns (UploadFileResponse) { + option (x_fern_retry) = '{ + "max_attempts": 5, + "exponential_backoff": true, + "initial_delay_ms": 2000, + "max_delay_ms": 60000 + }'; + } +} +``` + +## `x-fern-timeout` + +Configure timeout settings for methods: + +```protobuf title="timeout_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc GenerateReport(GenerateReportRequest) returns (ReportResult) { + option (x_fern_timeout) = '{ + "seconds": 300, + "description": "Report generation can take up to 5 minutes" + }'; + } + + rpc QuickUserLookup(UserLookupRequest) returns (User) { + option (x_fern_timeout) = '{ + "seconds": 5, + "description": "Quick lookup should complete within 5 seconds" + }'; + } +} +``` + +## `x-fern-error-handling` + +Configure error handling for methods: + +```protobuf title="error_handling_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc CreateUser(CreateUserRequest) returns (User) { + option (x_fern_error_handling) = '{ + "ALREADY_EXISTS": { + "error_name": "UserAlreadyExistsError", + "user_friendly_message": "A user with this email already exists" + }, + "INVALID_ARGUMENT": { + "error_name": "ValidationError", + "user_friendly_message": "Please check your input and try again" + }, + "RESOURCE_EXHAUSTED": { + "error_name": "RateLimitError", + "retry_after_seconds": 60 + } + }'; + } +} +``` + +## `x-fern-availability` + +Mark features as available in specific SDK versions: + +```protobuf title="availability_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc GetUser(GetUserRequest) returns (User); + + rpc GetUserAnalytics(GetUserAnalyticsRequest) returns (UserAnalytics) { + option (x_fern_availability) = '{ + "status": "beta", + "message": "This feature is in beta and may change" + }'; + } + + rpc ExperimentalSearch(ExperimentalSearchRequest) returns (SearchResults) { + option (x_fern_availability) = '{ + "status": "experimental", + "message": "This is an experimental feature and may be removed" + }'; + } +} +``` + +## `x-fern-streaming` + +Mark methods as streaming for appropriate SDK generation: + +```protobuf title="streaming_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + rpc StreamEvents(StreamEventsRequest) returns (stream Event) { + option (x_fern_streaming) = '{ + "type": "server_streaming", + "termination": "client_closes" + }'; + } + + rpc UploadData(stream UploadDataRequest) returns (UploadResult) { + option (x_fern_streaming) = '{ + "type": "client_streaming", + "termination": "client_closes" + }'; + } + + rpc Chat(stream ChatMessage) returns (stream ChatMessage) { + option (x_fern_streaming) = '{ + "type": "bidirectional_streaming", + "termination": "either_closes" + }'; + } +} +``` + +## `x-fern-server-name` + +Specify custom names for different server environments: + +```protobuf title="server_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + option (x_fern_server_name_production) = "Production"; + option (x_fern_server_name_staging) = "Staging"; + option (x_fern_server_name_development) = "Development"; + + rpc GetUser(GetUserRequest) returns (User); +} +``` + +## `x-fern-base-path` + +Configure base paths for generated SDK clients: + +```protobuf title="base_path_service.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + option (x_fern_base_path) = "/api/v1"; + + rpc GetUser(GetUserRequest) returns (User); +} +``` + +## `x-fern-sdk-group-name` + +Group related services in the SDK: + +```protobuf title="grouped_services.proto" +syntax = "proto3"; + +package userservice.v1; + +service UserService { + option (x_fern_sdk_group_name) = "users"; + + rpc CreateUser(CreateUserRequest) returns (User); + rpc GetUser(GetUserRequest) returns (User); +} + +service UserProfileService { + option (x_fern_sdk_group_name) = "users"; + + rpc GetProfile(GetProfileRequest) returns (UserProfile); + rpc UpdateProfile(UpdateProfileRequest) returns (UserProfile); +} + +service AuthService { + option (x_fern_sdk_group_name) = "auth"; + + rpc Login(LoginRequest) returns (LoginResponse); + rpc Logout(LogoutRequest) returns (google.protobuf.Empty); +} +``` + +This generates SDKs with grouped services: + +```typescript +client.users.createUser(...) +client.users.getUser(...) +client.users.getProfile(...) +client.users.updateProfile(...) +client.auth.login(...) +client.auth.logout(...) +``` + +## `x-fern-union-naming` + +Configure naming for oneof fields in SDKs: + +```protobuf title="union_naming.proto" +syntax = "proto3"; + +package userservice.v1; + +message NotificationTarget { + oneof target { + option (x_fern_union_naming) = "discriminated"; + + string user_id = 1 [(x_fern_parameter_name) = "userId"]; + string group_id = 2 [(x_fern_parameter_name) = "groupId"]; + BroadcastTarget broadcast = 3; + } +} +``` + +## `x-fern-validation` + +Add validation rules for message fields: + +```protobuf title="validation_service.proto" +syntax = "proto3"; + +package userservice.v1; + +message CreateUserRequest { + string email = 1 [ + (x_fern_validation) = '{ + "format": "email", + "required": true + }' + ]; + + string name = 2 [ + (x_fern_validation) = '{ + "min_length": 1, + "max_length": 100, + "required": true + }' + ]; + + int32 age = 3 [ + (x_fern_validation) = '{ + "minimum": 0, + "maximum": 120 + }' + ]; +} +``` + +These extensions help you create more robust and user-friendly SDKs while maintaining full control over the generated code structure and behavior. \ No newline at end of file diff --git a/fern/products/api-def/grpc-pages/extensions/parameter-names.mdx b/fern/products/api-def/grpc-pages/extensions/parameter-names.mdx new file mode 100644 index 00000000..de31f385 --- /dev/null +++ b/fern/products/api-def/grpc-pages/extensions/parameter-names.mdx @@ -0,0 +1,302 @@ +--- +title: Parameter Names +subtitle: Use `x-fern-parameter-name` to customize SDK parameter names for gRPC message fields +--- + +By default, Fern uses the field names from your Protocol Buffer message definitions as SDK parameter names. You can customize these using the `x-fern-parameter-name` extension. + +## Customize field names + +Use `x-fern-parameter-name` to specify custom parameter names for message fields: + +```protobuf title="user_service.proto" +syntax = "proto3"; + +package userservice.v1; + +message CreateUserRequest { + string email_address = 1 [(x_fern_parameter_name) = "email"]; + string full_name = 2 [(x_fern_parameter_name) = "name"]; + int32 age_in_years = 3 [(x_fern_parameter_name) = "age"]; + string phone_number = 4 [(x_fern_parameter_name) = "phone"]; + UserPreferences user_preferences = 5 [(x_fern_parameter_name) = "preferences"]; +} + +message User { + string user_id = 1 [(x_fern_parameter_name) = "id"]; + string email_address = 2 [(x_fern_parameter_name) = "email"]; + string full_name = 3 [(x_fern_parameter_name) = "name"]; + google.protobuf.Timestamp created_timestamp = 4 [(x_fern_parameter_name) = "createdAt"]; + google.protobuf.Timestamp updated_timestamp = 5 [(x_fern_parameter_name) = "updatedAt"]; +} +``` + +This generates SDK methods with cleaner parameter names: + +```typescript +// Instead of email_address, full_name, age_in_years, phone_number, user_preferences +await client.users.create({ + email: "john@example.com", + name: "John Doe", + age: 30, + phone: "+1-555-0123", + preferences: { theme: "dark" } +}); +``` + +## Language-specific parameter names + +You can specify different parameter names for different programming languages: + +```protobuf title="language_specific.proto" +syntax = "proto3"; + +package userservice.v1; + +message SearchUsersRequest { + string search_query = 1 [ + (x_fern_parameter_name_python) = "search_query", + (x_fern_parameter_name_typescript) = "searchQuery", + (x_fern_parameter_name_go) = "SearchQuery", + (x_fern_parameter_name_java) = "searchQuery", + (x_fern_parameter_name_csharp) = "SearchQuery" + ]; + + int32 page_size = 2 [ + (x_fern_parameter_name_python) = "page_size", + (x_fern_parameter_name_typescript) = "pageSize", + (x_fern_parameter_name_go) = "PageSize", + (x_fern_parameter_name_java) = "pageSize", + (x_fern_parameter_name_csharp) = "PageSize" + ]; + + string page_token = 3 [ + (x_fern_parameter_name_python) = "page_token", + (x_fern_parameter_name_typescript) = "pageToken", + (x_fern_parameter_name_go) = "PageToken", + (x_fern_parameter_name_java) = "pageToken", + (x_fern_parameter_name_csharp) = "PageToken" + ]; +} +``` + +## Nested message naming + +Customize parameter names for nested message fields: + +```protobuf title="nested_messages.proto" +syntax = "proto3"; + +package userservice.v1; + +message CreateUserRequest { + UserProfile user_profile = 1 [(x_fern_parameter_name) = "profile"]; + ContactInfo contact_info = 2 [(x_fern_parameter_name) = "contact"]; + AccountSettings account_settings = 3 [(x_fern_parameter_name) = "settings"]; +} + +message UserProfile { + string first_name = 1 [(x_fern_parameter_name) = "firstName"]; + string last_name = 2 [(x_fern_parameter_name) = "lastName"]; + string display_name = 3 [(x_fern_parameter_name) = "displayName"]; + string bio_text = 4 [(x_fern_parameter_name) = "bio"]; + string avatar_url = 5 [(x_fern_parameter_name) = "avatarUrl"]; +} + +message ContactInfo { + string email_address = 1 [(x_fern_parameter_name) = "email"]; + string phone_number = 2 [(x_fern_parameter_name) = "phone"]; + Address mailing_address = 3 [(x_fern_parameter_name) = "address"]; +} + +message Address { + string street_address = 1 [(x_fern_parameter_name) = "street"]; + string city_name = 2 [(x_fern_parameter_name) = "city"]; + string state_province = 3 [(x_fern_parameter_name) = "state"]; + string postal_code = 4 [(x_fern_parameter_name) = "zipCode"]; + string country_code = 5 [(x_fern_parameter_name) = "country"]; +} +``` + +## Repeated field naming + +Handle repeated fields with custom naming: + +```protobuf title="repeated_fields.proto" +syntax = "proto3"; + +package userservice.v1; + +message User { + string user_id = 1 [(x_fern_parameter_name) = "id"]; + repeated string role_names = 2 [(x_fern_parameter_name) = "roles"]; + repeated string permission_codes = 3 [(x_fern_parameter_name) = "permissions"]; + repeated SocialAccount social_accounts = 4 [(x_fern_parameter_name) = "socialAccounts"]; + repeated string tag_list = 5 [(x_fern_parameter_name) = "tags"]; +} + +message SocialAccount { + string platform_name = 1 [(x_fern_parameter_name) = "platform"]; + string account_handle = 2 [(x_fern_parameter_name) = "handle"]; + string profile_url = 3 [(x_fern_parameter_name) = "url"]; + bool is_verified = 4 [(x_fern_parameter_name) = "verified"]; +} + +message BatchCreateUsersRequest { + repeated CreateUserRequest user_requests = 1 [(x_fern_parameter_name) = "users"]; + bool send_welcome_email = 2 [(x_fern_parameter_name) = "sendWelcomeEmail"]; + bool skip_validation = 3 [(x_fern_parameter_name) = "skipValidation"]; +} +``` + +## Map field naming + +Customize names for map fields: + +```protobuf title="map_fields.proto" +syntax = "proto3"; + +package userservice.v1; + +message UserPreferences { + map notification_settings = 1 [(x_fern_parameter_name) = "notifications"]; + map feature_flags = 2 [(x_fern_parameter_name) = "features"]; + map display_settings = 3 [(x_fern_parameter_name) = "display"]; + map theme_overrides = 4 [(x_fern_parameter_name) = "themes"]; +} + +message MetricsData { + map performance_metrics = 1 [(x_fern_parameter_name) = "performance"]; + map usage_counters = 2 [(x_fern_parameter_name) = "usage"]; + map event_timestamps = 3 [(x_fern_parameter_name) = "events"]; +} +``` + +## Optional and required field naming + +Customize names for optional and required fields: + +```protobuf title="optional_fields.proto" +syntax = "proto3"; + +package userservice.v1; + +message UpdateUserRequest { + // Required fields + string user_id = 1 [(x_fern_parameter_name) = "id"]; + + // Optional fields with custom names + optional string email_address = 2 [(x_fern_parameter_name) = "email"]; + optional string full_name = 3 [(x_fern_parameter_name) = "name"]; + optional int32 age_in_years = 4 [(x_fern_parameter_name) = "age"]; + optional string profile_picture_url = 5 [(x_fern_parameter_name) = "avatarUrl"]; + + // Field mask for partial updates + google.protobuf.FieldMask update_mask = 6 [(x_fern_parameter_name) = "updateMask"]; +} +``` + +## Oneof field naming + +Handle oneof fields with meaningful names: + +```protobuf title="oneof_fields.proto" +syntax = "proto3"; + +package userservice.v1; + +message SearchRequest { + oneof search_criteria { + string search_by_email = 1 [(x_fern_parameter_name) = "email"]; + string search_by_username = 2 [(x_fern_parameter_name) = "username"]; + string search_by_phone = 3 [(x_fern_parameter_name) = "phone"]; + UserIdSearch search_by_id = 4 [(x_fern_parameter_name) = "id"]; + } + + SearchOptions search_options = 5 [(x_fern_parameter_name) = "options"]; +} + +message UserIdSearch { + string user_id = 1 [(x_fern_parameter_name) = "id"]; + bool include_deleted = 2 [(x_fern_parameter_name) = "includeDeleted"]; +} + +message NotificationRequest { + oneof notification_target { + string target_user_id = 1 [(x_fern_parameter_name) = "userId"]; + string target_group_id = 2 [(x_fern_parameter_name) = "groupId"]; + BroadcastTarget target_broadcast = 3 [(x_fern_parameter_name) = "broadcast"]; + } + + string message_content = 4 [(x_fern_parameter_name) = "message"]; + NotificationPriority priority_level = 5 [(x_fern_parameter_name) = "priority"]; +} +``` + +## Timestamp and duration naming + +Customize names for time-related fields: + +```protobuf title="time_fields.proto" +syntax = "proto3"; + +package userservice.v1; + +message UserSession { + string session_id = 1 [(x_fern_parameter_name) = "id"]; + string user_id = 2 [(x_fern_parameter_name) = "userId"]; + google.protobuf.Timestamp created_timestamp = 3 [(x_fern_parameter_name) = "createdAt"]; + google.protobuf.Timestamp last_accessed_timestamp = 4 [(x_fern_parameter_name) = "lastAccessedAt"]; + google.protobuf.Timestamp expires_timestamp = 5 [(x_fern_parameter_name) = "expiresAt"]; + google.protobuf.Duration session_duration = 6 [(x_fern_parameter_name) = "duration"]; + google.protobuf.Duration idle_timeout = 7 [(x_fern_parameter_name) = "idleTimeout"]; +} + +message ScheduledTask { + string task_id = 1 [(x_fern_parameter_name) = "id"]; + google.protobuf.Timestamp scheduled_time = 2 [(x_fern_parameter_name) = "scheduledAt"]; + google.protobuf.Duration execution_timeout = 3 [(x_fern_parameter_name) = "timeout"]; + google.protobuf.Duration retry_delay = 4 [(x_fern_parameter_name) = "retryDelay"]; +} +``` + +## Complex nested naming + +Handle complex nested structures: + +```protobuf title="complex_nested.proto" +syntax = "proto3"; + +package userservice.v1; + +message CreateOrderRequest { + OrderDetails order_details = 1 [(x_fern_parameter_name) = "order"]; + PaymentInfo payment_info = 2 [(x_fern_parameter_name) = "payment"]; + ShippingInfo shipping_info = 3 [(x_fern_parameter_name) = "shipping"]; +} + +message OrderDetails { + repeated OrderItem order_items = 1 [(x_fern_parameter_name) = "items"]; + string promo_code = 2 [(x_fern_parameter_name) = "promoCode"]; + string special_instructions = 3 [(x_fern_parameter_name) = "instructions"]; +} + +message OrderItem { + string product_id = 1 [(x_fern_parameter_name) = "productId"]; + int32 quantity_ordered = 2 [(x_fern_parameter_name) = "quantity"]; + double unit_price = 3 [(x_fern_parameter_name) = "price"]; + repeated string product_options = 4 [(x_fern_parameter_name) = "options"]; +} + +message PaymentInfo { + oneof payment_method { + CreditCardInfo credit_card_info = 1 [(x_fern_parameter_name) = "creditCard"]; + PayPalInfo paypal_info = 2 [(x_fern_parameter_name) = "paypal"]; + BankTransferInfo bank_transfer_info = 3 [(x_fern_parameter_name) = "bankTransfer"]; + } + + BillingAddress billing_address = 4 [(x_fern_parameter_name) = "billingAddress"]; +} +``` + +Using custom parameter names ensures consistent naming conventions across your SDK while maintaining compatibility with your existing Protocol Buffer schemas. \ No newline at end of file diff --git a/fern/products/api-def/grpc-pages/overrides.mdx b/fern/products/api-def/grpc-pages/overrides.mdx new file mode 100644 index 00000000..beda30a9 --- /dev/null +++ b/fern/products/api-def/grpc-pages/overrides.mdx @@ -0,0 +1,432 @@ +--- +title: Overlay Customizations +subtitle: Use overlay files to modify your gRPC specifications without editing the original Proto files +--- + +Overlays allow you to modify your gRPC specifications without directly editing the original Protocol Buffer files. This is useful for: +- Adding Fern-specific extensions +- Customizing SDK method and parameter names +- Adding examples and documentation +- Configuring audiences and filtering + +## Configure overlays + +To use overlays, add them to your `generators.yml` file: + +```yaml title="generators.yml" {3-5} +api: + specs: + - spec: proto/user_service.proto + overlays: + - overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + +## Overlay file structure + +Overlay files use Protocol Buffer text format with Fern extensions: + +```protobuf title="overlay.yml" +# Add SDK method names to existing gRPC methods +service UserService { + rpc CreateUser { + option (x_fern_sdk_method_name) = "create"; + } + + rpc GetUser { + option (x_fern_sdk_method_name) = "get"; + } + + rpc ListUsers { + option (x_fern_sdk_method_name) = "list"; + option (x_fern_pagination) = '{ + "cursor": "page_token", + "results": "users", + "next_cursor": "next_page_token" + }'; + } +} +``` + +## Add method names + +Override SDK method names for better developer experience: + +```protobuf title="overlay.yml" +service UserService { + rpc GetUserById { + option (x_fern_sdk_method_name) = "getUser"; + } + + rpc CreateNewUser { + option (x_fern_sdk_method_name) = "create"; + } + + rpc UpdateUserProfile { + option (x_fern_sdk_method_name) = "updateProfile"; + } + + rpc DeleteUserAccount { + option (x_fern_sdk_method_name) = "delete"; + } +} + +service AuthenticationService { + option (x_fern_sdk_service_name) = "auth"; + + rpc LoginUser { + option (x_fern_sdk_method_name) = "login"; + } + + rpc LogoutUser { + option (x_fern_sdk_method_name) = "logout"; + } +} +``` + +## Add parameter names + +Customize parameter names for better SDK ergonomics: + +```protobuf title="overlay.yml" +message CreateUserRequest { + string email_address { + option (x_fern_parameter_name) = "email"; + } + + string full_name { + option (x_fern_parameter_name) = "name"; + } + + int32 age_in_years { + option (x_fern_parameter_name) = "age"; + } + + UserPreferences user_preferences { + option (x_fern_parameter_name) = "preferences"; + } +} + +message User { + string user_id { + option (x_fern_parameter_name) = "id"; + } + + google.protobuf.Timestamp created_timestamp { + option (x_fern_parameter_name) = "createdAt"; + } + + google.protobuf.Timestamp updated_timestamp { + option (x_fern_parameter_name) = "updatedAt"; + } +} +``` + +## Add examples + +Enhance your specification with comprehensive examples: + +```protobuf title="overlay.yml" +service UserService { + rpc CreateUser { + option (x_fern_examples) = '{ + "StandardUser": { + "description": "Create a regular user account", + "request": { + "email": "john@example.com", + "name": "John Doe", + "age": 30, + "preferences": { + "theme": "dark", + "notifications": true + } + }, + "response": { + "id": "user_123", + "email": "john@example.com", + "name": "John Doe", + "created_at": "2024-01-15T10:30:00Z" + } + }, + "AdminUser": { + "description": "Create an admin user with permissions", + "request": { + "email": "admin@example.com", + "name": "Admin User", + "role": "admin", + "permissions": ["read", "write", "delete"] + }, + "response": { + "id": "user_456", + "email": "admin@example.com", + "name": "Admin User", + "role": "admin", + "created_at": "2024-01-15T10:30:00Z" + } + } + }'; + } +} +``` + +## Filter with audiences + +Add audience filtering to services and methods: + +```protobuf title="overlay.yml" +service UserService { + option (x_fern_audiences) = "public"; + + rpc GetUser { + option (x_fern_audiences) = "public"; + } + + rpc CreateUser { + option (x_fern_audiences) = "public"; + } +} + +service AdminService { + option (x_fern_audiences) = "admin"; + + rpc ListAllUsers { + option (x_fern_audiences) = "admin"; + } + + rpc DeleteUser { + option (x_fern_audiences) = "admin"; + } +} + +service DebugService { + option (x_fern_audiences) = "internal"; + + rpc GetSystemInfo { + option (x_fern_audiences) = "internal"; + } +} +``` + +## Add error handling + +Configure custom error handling for methods: + +```protobuf title="overlay.yml" +service UserService { + rpc CreateUser { + option (x_fern_error_handling) = '{ + "ALREADY_EXISTS": { + "error_name": "UserAlreadyExistsError", + "user_friendly_message": "A user with this email already exists" + }, + "INVALID_ARGUMENT": { + "error_name": "ValidationError", + "user_friendly_message": "Please check your input and try again" + }, + "RESOURCE_EXHAUSTED": { + "error_name": "RateLimitError", + "retry_after_seconds": 60 + } + }'; + } + + rpc ProcessPayment { + option (x_fern_retry) = '{ + "max_attempts": 3, + "exponential_backoff": true, + "initial_delay_ms": 1000, + "max_delay_ms": 30000 + }'; + } +} +``` + +## Add documentation + +Enhance descriptions and documentation: + +```protobuf title="overlay.yml" +service UserService { + option (x_fern_service_description) = "User management service for creating, updating, and managing user accounts with comprehensive authentication and profile management capabilities."; + + rpc CreateUser { + option (x_fern_method_description) = "Create a new user account with email verification and automatic profile setup. Supports custom preferences and role assignment."; + } + + rpc GetUser { + option (x_fern_method_description) = "Retrieve user information by ID with optional inclusion of profile data, preferences, and activity history."; + } + + rpc UpdateUser { + option (x_fern_method_description) = "Update user profile information with field-level updates using Protocol Buffer field masks for efficient partial updates."; + } +} +``` + +## Configure timeouts and retries + +Add timeout and retry configurations: + +```protobuf title="overlay.yml" +service UserService { + rpc GenerateUserReport { + option (x_fern_timeout) = '{ + "seconds": 300, + "description": "Report generation can take up to 5 minutes for large datasets" + }'; + } + + rpc QuickUserLookup { + option (x_fern_timeout) = '{ + "seconds": 5, + "description": "Quick lookup operations should complete within 5 seconds" + }'; + } + + rpc ImportUsers { + option (x_fern_retry) = '{ + "max_attempts": 5, + "exponential_backoff": true, + "initial_delay_ms": 2000, + "max_delay_ms": 60000, + "retry_on_status": ["UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"] + }'; + } +} +``` + +## Streaming configurations + +Configure streaming methods: + +```protobuf title="overlay.yml" +service UserStreamingService { + rpc StreamUserEvents { + option (x_fern_streaming) = '{ + "type": "server_streaming", + "termination": "client_closes", + "description": "Real-time stream of user events with automatic reconnection" + }'; + } + + rpc UploadUserData { + option (x_fern_streaming) = '{ + "type": "client_streaming", + "termination": "client_closes", + "max_message_size": "10MB" + }'; + } + + rpc ChatWithSupport { + option (x_fern_streaming) = '{ + "type": "bidirectional_streaming", + "termination": "either_closes", + "heartbeat_interval": "30s" + }'; + } +} +``` + +## Multiple overlays + +You can apply multiple overlay files in sequence: + +```yaml title="generators.yml" {4-8} +api: + specs: + - spec: proto/user_service.proto + overlays: + - base-overlay.yml + - sdk-overlay.yml + - docs-overlay.yml + - examples-overlay.yml +``` + +## Environment-specific overlays + +Use different overlays for different environments: + +```yaml title="generators.yml" {4-7, 12-15} +groups: + production: + audiences: [public] + specs: + - spec: proto/user_service.proto + overlays: + - production-overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 + internal: + audiences: [admin, internal] + specs: + - spec: proto/user_service.proto + overlays: + - internal-overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + +## Field-level overlays + +Apply overlays to specific message fields: + +```protobuf title="overlay.yml" +message UserPreferences { + map notification_settings { + option (x_fern_parameter_name) = "notifications"; + option (x_fern_field_description) = "User notification preferences with support for email, SMS, and push notifications"; + } + + map feature_flags { + option (x_fern_parameter_name) = "features"; + option (x_fern_field_description) = "Feature flags controlling access to beta and experimental features"; + } + + string preferred_language { + option (x_fern_parameter_name) = "language"; + option (x_fern_validation) = '{ + "enum": ["en", "es", "fr", "de", "zh"], + "default": "en" + }'; + } +} +``` + +## Validation overlays + +Add validation rules to existing fields: + +```protobuf title="overlay.yml" +message CreateUserRequest { + string email { + option (x_fern_validation) = '{ + "format": "email", + "required": true, + "description": "Must be a valid email address" + }'; + } + + string name { + option (x_fern_validation) = '{ + "min_length": 1, + "max_length": 100, + "required": true, + "pattern": "^[a-zA-Z\\s]+$" + }'; + } + + int32 age { + option (x_fern_validation) = '{ + "minimum": 0, + "maximum": 120, + "description": "Age in years" + }'; + } +} +``` + +Overlays are applied in order, allowing you to build up customizations incrementally while keeping your original Protocol Buffer files clean and focused on the core service definition. \ No newline at end of file diff --git a/fern/products/api-def/grpc-pages/overview.mdx b/fern/products/api-def/grpc-pages/overview.mdx index 634cff60..a25da7a3 100644 --- a/fern/products/api-def/grpc-pages/overview.mdx +++ b/fern/products/api-def/grpc-pages/overview.mdx @@ -1,15 +1,13 @@ --- title: What is gRPC? -description: gRPC is a high-performance RPC framework that uses Protocol Buffers +subtitle: gRPC is a high-performance RPC framework that uses Protocol Buffers --- - - Fern only supports gRPC SDK generation for .NET/C#. - - gRPC is a modern, open-source, high-performance Remote Procedure Call (RPC) framework that can run in any environment. It uses Protocol Buffers (protobuf) as the interface definition language and supports multiple programming languages. Fern is compatible with gRPC services and can generate SDKs and documentation from your `.proto` files. + Need help getting started with gRPC and Fern? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) + Below is an example of a gRPC service definition: ```protobuf user_service.proto @@ -157,10 +155,27 @@ enum ChatMessageType { } ``` -## Set up your fern folder +## gRPC Features - Need help getting started with gRPC and Fern? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) +gRPC offers several key features that make it ideal for modern applications: + +### High Performance +- Binary protocol with Protocol Buffers +- HTTP/2 transport for multiplexing and flow control +- Efficient serialization and deserialization + +### Multiple Communication Patterns +- **Unary RPCs**: Simple request/response +- **Server Streaming**: Server sends stream of responses +- **Client Streaming**: Client sends stream of requests +- **Bidirectional Streaming**: Both sides send streams + +### Cross-Platform Support +- Native support for 10+ programming languages +- Generated client libraries and server stubs +- Consistent API across all platforms +## Setup your fern folder Start by initializing your fern folder with a gRPC service @@ -181,4 +196,26 @@ fern/ └─ proto/ ├─ user_service.proto └─ common.proto -``` \ No newline at end of file +``` + +## gRPC vs REST + +| Feature | gRPC | REST | +|---------|------|------| +| Protocol | HTTP/2 | HTTP/1.1 | +| Data Format | Protocol Buffers | JSON | +| Performance | High | Moderate | +| Streaming | Native support | Limited | +| Browser Support | Limited | Full | +| Schema | Strongly typed | Flexible | +| Code Generation | Built-in | Third-party tools | + +## Common Use Cases + +gRPC is particularly well-suited for: + +- **Microservices Communication**: High-performance inter-service communication +- **Real-time Applications**: Streaming for live updates and real-time features +- **Mobile Applications**: Efficient mobile-to-server communication +- **IoT Systems**: Lightweight communication for resource-constrained devices +- **APIs with Strong Contracts**: Type-safe communication with schema evolution \ No newline at end of file diff --git a/fern/products/api-def/openapi-def.yml b/fern/products/api-def/openapi-def.yml deleted file mode 100644 index 42490e7f..00000000 --- a/fern/products/api-def/openapi-def.yml +++ /dev/null @@ -1,5 +0,0 @@ -navigation: - - page: OpenAPI Definition Redirect Page - path: ./pages/openapi-empty.mdx - slug: empty-page - hidden: true diff --git a/fern/products/api-def/openapi-pages/automation.mdx b/fern/products/api-def/openapi-pages/automation.mdx index b4986eea..23a319a9 100644 --- a/fern/products/api-def/openapi-pages/automation.mdx +++ b/fern/products/api-def/openapi-pages/automation.mdx @@ -3,18 +3,15 @@ title: Sync your OpenAPI Specification subtitle: Pull your latest OpenAPI Specification into your Fern Folder automatically. --- -Automatically pull your latest OpenAPI spec from a publicly available URL into your fern folder using the [sync-openapi GitHub Action](https://github.com/fern-api/sync-openapi). This keeps your committed spec in sync with your live API without manual updates. - +If you host your OpenAPI Specification at a publicly available URL, you can have Fern programmatically fetch the latest spec on a preconfigured cadence through the [sync-openapi GitHub Action](https://github.com/fern-api/sync-openapi). This ensures your committed OpenAPI spec stays up to date with your live API. ## Setup Add the origin field to your generators.yml to specify where your OpenAPI spec is hosted: ```yml title="generators.yml" api: - specs: - - openapi: .path/to/openapi.json # Definition file - overrides: .path/to-openapi-overrides.yml # Overrides file - origin: https://api.example.com/openapi.json # URL to fetch latest spec from + path: openapi/openapi.json + origin: https://api.example.com/openapi.json ``` @@ -22,12 +19,12 @@ Automatically pull your latest OpenAPI spec from a publicly available URL into y ```yml name: Sync OpenAPI Specs # can be customized on: # additional custom triggers can be configured - workflow_dispatch: # Manual trigger + workflow_dispatch: # manual dispatch push: branches: - - main # Trigger on push to + - main # on push to main schedule: - - cron: '0 3 * * *' # Daily at 3:00 AM UTC + - cron: '0 3 * * *' # everyday at 3:00 AM UTC jobs: update-from-source: runs-on: ubuntu-latest @@ -45,16 +42,13 @@ Automatically pull your latest OpenAPI spec from a publicly available URL into y add_timestamp: true ``` - - Generate a [fine-grained personal access token](https://github.com/settings/personal-access-tokens) with **Contents** and **Pull requests** read/write permissions for your repository. + + Generate a [fine-grained personal access token](https://github.com/settings/personal-access-tokens) with read/write access to your repository. - In your repository, go to `Settings > Secrets and variables > Actions`. Click **New repository secret**, name it `OPENAPI_SYNC_TOKEN`, paste your token, and click **Add secret**. + Navigate to your repository's `Settings > Secrets and variables > Actions`. Select **New repository secret**, name it `OPENAPI_SYNC_TOKEN`, add your token, and click **Add secret**. +By default, this will create daily PRs with API spec updates to the repo containing your fern folder. If you would like to adjust the frequency, learn more about GitHub's [schedule event](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule). -This creates daily pull requests with any API spec updates. To change the frequency, modify the `cron` schedule (see GitHub's [schedule syntax](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule)). - -## Other use cases - -If your OpenAPI spec lives in a different repository (rather than at a public URL), you can sync it to your Fern folder using cross-repository sync. See the [sync-openapi GitHub Action README](https://github.com/fern-api/sync-openapi) for this and other advanced configurations. + For detailed configuration options and other use cases, see the [sync-openapi GitHub Action README](https://github.com/fern-api/sync-openapi). diff --git a/fern/products/api-def/openapi-pages/extensions/api-version.mdx b/fern/products/api-def/openapi-pages/extensions/api-version.mdx deleted file mode 100644 index c06e6afe..00000000 --- a/fern/products/api-def/openapi-pages/extensions/api-version.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: API version -description: Configure API version schemes and headers using `x-fern-version` extension ---- - -You can define your API version scheme, such as a `X-API-Version` header. The supported versions and default value are specified like so: - -```yaml title="openapi.yaml" -x-fern-version: - version: - header: X-API-Version - default: "2.0.0" - values: - - "1.0.0" - - "2.0.0" - - "latest" -paths: ... -``` \ No newline at end of file diff --git a/fern/products/api-def/openapi-pages/extensions/availability.mdx b/fern/products/api-def/openapi-pages/extensions/availability.mdx deleted file mode 100644 index 69024974..00000000 --- a/fern/products/api-def/openapi-pages/extensions/availability.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Availability -description: Mark endpoint availability status using `x-fern-availability` extension ---- - -The `x-fern-availability` extension is used to mark the availability of an endpoint. The availability information propagates into the generated Fern Docs website as visual tags. - -The options are: - -- `beta` -- `generally-available` -- `deprecated` - -The example below marks that the `POST /pet` endpoint is `deprecated`. - -```yaml title="x-fern-availability in openapi.yml" {4} -paths: - /pet: - post: - x-fern-availability: deprecated -``` - -This renders as: - - -![Screenshot of API Reference endpoint with tag showing deprecated](https://fern-image-hosting.s3.amazonaws.com/fern/x-fern-availability-example.png) - \ No newline at end of file diff --git a/fern/products/api-def/openapi-pages/extensions/base-path.mdx b/fern/products/api-def/openapi-pages/extensions/base-path.mdx deleted file mode 100644 index df950139..00000000 --- a/fern/products/api-def/openapi-pages/extensions/base-path.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Base path -description: Configure base path prepended to endpoints using `x-fern-base-path` extension ---- -## Base path - -The `x-fern-base-path` extension is used to configure the base path prepended to every endpoint. - -In the example below, we have configured the `/v1` base path so the full endpoint path is -`https://api.example.com/v1/users`. - -```yaml title="Set the base path in openapi.yml" {1} -x-fern-base-path: /v1 -servers: - - url: https://api.example.com -paths: - /users: ... -``` diff --git a/fern/products/api-def/openapi-pages/extensions/enums.mdx b/fern/products/api-def/openapi-pages/extensions/enums.mdx deleted file mode 100644 index 05344d7a..00000000 --- a/fern/products/api-def/openapi-pages/extensions/enums.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Enum descriptions and names -description: Add descriptions and custom names to enum values using `x-fern-enum` extension ---- - -OpenAPI doesn't natively support adding descriptions to enum values. To do this in Fern you can use the `x-fern-enum` -extension. - -In the example below, we've added some descriptions to enum values. These descriptions will -propagate into the generated SDK and docs website. - -```yaml title="openapi.yml" {9-13} -components: - schemas: - CardSuit: - enum: - - clubs - - diamonds - - hearts - - spades - x-fern-enum: - clubs: - description: Some docs about clubs - spades: - description: Some docs about spades -``` - -`x-fern-enum` also supports a `name` field that allows you to customize the name of the enum in code. -This is particularly useful when you have enums that rely on symbolic characters that would otherwise cause -generated code not to compile. - -For example, the following OpenAPI - -```yaml title="openapi.yml" {9,12} -components: - schemas: - Operand: - enum: - - '>' - - '<' - x-fern-enum: - '>': - name: GreaterThan - description: Checks if value is greater than - '<': - name: LessThan - description: Checks if value is less than -``` - -would generate - -```typescript title="operand.ts" -export enum Operand { - GreaterThan = ">", - LessThan = "<" -} -``` diff --git a/fern/products/api-def/openapi-pages/extensions/examples.mdx b/fern/products/api-def/openapi-pages/extensions/examples.mdx deleted file mode 100644 index 4cb471d5..00000000 --- a/fern/products/api-def/openapi-pages/extensions/examples.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Request + response examples -description: Associate request and response examples using `x-fern-examples` extension ---- - -While OpenAPI has several fields for examples, there is no easy way -to associate a request with a response. This is especially useful when -you want to show more than one example in your documentation. - -`x-fern-examples` is an array of examples. Each element of the array -can contain `path-parameters`, `query-parameters`, `request` and `response` -examples values that are all associated. - -```yaml title="openapi.yml" {5-16} -paths: - /users/{userId}: - get: - x-fern-examples: - - path-parameters: - userId: user-1234 - response: - body: - name: Foo - ssn: 1234 - - path-parameters: - userId: user-4567 - response: - body: - name: Foo - ssn: 4567 -components: - schemas: - User: - type: object - properties: - name: - type: string - ssn: - type: integer -``` - -### Code samples - -If you'd like to specify custom code samples for your example, use `code-samples`. - -```yaml title="openapi.yml" {11-16} -paths: - /users/{userId}: - get: - x-fern-examples: - - path-parameters: - userId: user-1234 - response: - body: - name: Foo - ssn: 1234 - code-samples: - - sdk: typescript - code: | - import { UserClient } from "..."; - - client.users.get("user-1234") -``` - -If you're on the Fern Basic plan or higher for SDKs you won't have to worry about manually adding code samples! Our generators do that for you. diff --git a/fern/products/api-def/openapi-pages/extensions/global-headers.mdx b/fern/products/api-def/openapi-pages/extensions/global-headers.mdx deleted file mode 100644 index 254c2771..00000000 --- a/fern/products/api-def/openapi-pages/extensions/global-headers.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Global headers -description: Configure headers used across all endpoints using `x-fern-global-headers` extension ---- - -At times, your API will leverage certain headers for every endpoint, or the majority of them, we call these "global headers". For convenience, generated Fern SDKs expose "global headers" to easily be updated on API calls. Take for example an API key, if we declare the API key as a global header, a user will be able to plug theirs in easily: - -```python -import os - -class Client: - - def __init__(self, *, apiKey: str): -``` - -To configure global headers, Fern will automatically pull out headers that are used in every request, or the majority of requests, and mark them as global. -In order to label additional headers as global, or to alias the names of global headers, you can leverage the `x-fern-global-headers` extension: - -```yaml title="openapi.yml" -x-fern-global-headers: - - header: custom_api_key - name: api_key - - header: userpool_id - optional: true -``` - -yields the following client: - -```python -import os - -class Client: - - def __init__(self, *, apiKey: str, userpoolId: typing.Optional[str]) -``` diff --git a/fern/products/api-def/openapi-pages/extensions/ignore.mdx b/fern/products/api-def/openapi-pages/extensions/ignore.mdx deleted file mode 100644 index a244e79d..00000000 --- a/fern/products/api-def/openapi-pages/extensions/ignore.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Ignoring schemas or endpoints -description: Skip reading endpoints or schemas using the `x-fern-ignore` extension ---- - -If you want Fern to skip reading any endpoints or schemas, use the `x-fern-ignore` extension. - -To skip an endpoint, add `x-fern-ignore: true` at the operation level. - -```yaml title="x-fern-ignore at operation level in openapi.yml" {4} -paths: - /users: - get: - x-fern-ignore: true - ... -``` - -To skip a schema, add `x-fern-ignore: true` at the schema level. - -```yaml title="x-fern-ignore at schema level in openapi.yml" {4} -components: - schemas: - SchemaToSkip: - x-fern-ignore: true - ... -``` diff --git a/fern/products/api-def/openapi-pages/extensions/others.mdx b/fern/products/api-def/openapi-pages/extensions/others.mdx new file mode 100644 index 00000000..b3aa4b3e --- /dev/null +++ b/fern/products/api-def/openapi-pages/extensions/others.mdx @@ -0,0 +1,416 @@ +--- +title: Other extensions +description: Learn about Fern's OpenAPI extensions for authentication overrides, global headers, enum descriptions and names, audiences, and more. +--- + +Fern supports different OpenAPI extensions so that you can generate higher-quality SDKs. + +## API version + +You can define your API version scheme, such as a `X-API-Version` header. The supported versions and default value are specified like so: + +```yaml title="openapi.yaml" +x-fern-version: + version: + header: X-API-Version + default: "2.0.0" + values: + - "1.0.0" + - "2.0.0" + - "latest" +paths: ... +``` + +## Global headers + +At times, your API will leverage certain headers for every endpoint, or the majority of them, we call these "global headers". For convenience, generated Fern SDKs expose "global headers" to easily be updated on API calls. Take for example an API key, if we declare the API key as a global header, a user will be able to plug theirs in easily: + +```python +import os + +class Client: + + def __init__(self, *, apiKey: str): +``` + +To configure global headers, Fern will automatically pull out headers that are used in every request, or the majority of requests, and mark them as global. +In order to label additional headers as global, or to alias the names of global headers, you can leverage the `x-fern-global-headers` extension: + +```yaml title="openapi.yml" +x-fern-global-headers: + - header: custom_api_key + name: api_key + - header: userpool_id + optional: true +``` + +yields the following client: + +```python +import os + +class Client: + + def __init__(self, *, apiKey: str, userpoolId: typing.Optional[str]) +``` + +## Enum descriptions and names + +OpenAPI doesn't natively support adding descriptions to enum values. To do this in Fern you can use the `x-fern-enum` +extension. + +In the example below, we've added some descriptions to enum values. These descriptions will +propagate into the generated SDK and docs website. + +```yaml title="openapi.yml" {9-13} +components: + schemas: + CardSuit: + enum: + - clubs + - diamonds + - hearts + - spades + x-fern-enum: + clubs: + description: Some docs about clubs + spades: + description: Some docs about spades +``` + +`x-fern-enum` also supports a `name` field that allows you to customize the name of the enum in code. +This is particularly useful when you have enums that rely on symbolic characters that would otherwise cause +generated code not to compile. + +For example, the following OpenAPI + +```yaml title="openapi.yml" {9,12} +components: + schemas: + Operand: + enum: + - '>' + - '<' + x-fern-enum: + '>': + name: GreaterThan + description: Checks if value is greater than + '<': + name: LessThan + description: Checks if value is less than +``` + +would generate + +```typescript title="operand.ts" +export enum Operand { + GreaterThan = ">", + LessThan = "<" +} +``` + +## Schema names + +OpenAPI allows you to define inlined schemas that do not have names. + +```yaml title="Inline type in openapi.yml" {11} +components: + schemas: + Movie: + type: object + properties: + name: + type: string + cast: + type: array + items: + type: object + properties: + firstName: + type: string + lastName: + type: string + age: + type: integer +``` + +Fern automatically generates names for all the inlined schemas. For example, in this example, +Fern would generate the name `CastItem` for the inlined array item schema. + +```typescript title="Auto-generated name" {6} +export interface Movie { + name?: string; + cast?: CastItem[]; +} + +export interface CastItem { + firstName?: string; + lastName?: string; + age?: integer; +} +``` + +If you want to override the generated name, you can use the extension `x-fern-type-name`. + +```yaml title="openapi.yml" {12} +components: + schemas: + Movie: + type: object + properties: + name: + type: string + cast: + type: array + items: + type: object + x-fern-type-name: Person + properties: + firstName: + type: string + lastName: + type: string + age: + type: integer +``` + +This would replace `CastItem` with `Person` and the generated code would read more idiomatically: + +```typescript title="Overridden name" {6} +export interface Movie { + name?: string; + cast?: Person[]; +} + +export interface Person { + firstName?: string; + lastName?: string; + age?: integer; +} +``` + +## Property names + +The `x-fern-property-name` extension allows you to customize the variable name for object +properties. + +For example, if you had a property called `_metadata` in your schema but you wanted the +variable to be called `data` in your SDK you would do the following: + +```yaml {6} +components: + schemas: + MyUser: + _metadata: + type: object + x-fern-property-name: data +``` + +## Server names + +The `x-fern-server-name` extension is used to name your servers. + +```yaml title="openapi.yml" +servers: + - url: https://api.example.com + x-fern-server-name: Production + - url: https://sandbox.example.com + x-fern-server-name: Sandbox +``` + +In a generated TypeScript SDK, you'd see: + +```typescript title="environment.ts" +export const ExampleEnvironment = { + Production: "https://api.example.com" +} as const; + +export type ExampleEnvironment = typeof ExampleEnvironment.Production; +``` + +## Base path + +The `x-fern-base-path` extension is used to configure the base path prepended to every endpoint. + +In the example below, we have configured the `/v1` base path so the full endpoint path is +`https://api.example.com/v1/users`. + +```yaml title="Set the base path in openapi.yml" {1} +x-fern-base-path: /v1 +servers: + - url: https://api.example.com +paths: + /users: ... +``` + +## Ignoring schemas or endpoints + +If you want Fern to skip reading any endpoints or schemas, use the `x-fern-ignore` extension. + +To skip an endpoint, add `x-fern-ignore: true` at the operation level. + +```yaml title="x-fern-ignore at operation level in openapi.yml" {4} +paths: + /users: + get: + x-fern-ignore: true + ... +``` + +To skip a schema, add `x-fern-ignore: true` at the schema level. + +```yaml title="x-fern-ignore at schema level in openapi.yml" {4} +components: + schemas: + SchemaToSkip: + x-fern-ignore: true + ... +``` + +## Overlaying extensions + +Because of the number of tools that use OpenAPI, it may be more convenient to +"overlay" your fern specific OpenAPI extensions onto your original definition. \ +In order to do this you can specify your overrides file in `generators.yml`. + +Below is an example of how someone can overlay the extensions `x-fern-sdk-method-name` and +`x-fern-sdk-group-name` without polluting their original OpenAPI. The combined result is +shown in the third tab. + + + ```yaml title="generators.yml" {3} + api: + path: ./openapi/openapi.yaml + overrides: ./openapi/overrides.yaml + default-group: sdk + groups: + sdk: + generators: + - name: fernapi/fern-python-sdk + version: 2.2.0 + ``` + + ```yaml title="overrides.yml" + paths: + /users: + get: + x-fern-sdk-group-name: users + x-fern-sdk-method-name: get + ``` + + ```yaml title="Overlaid OpenAPI" {4-5} + paths: + /users: + get: + x-fern-sdk-group-name: users + x-fern-sdk-method-name: get + summary: Get a list of users + description: Retrieve a list of users from the system. + responses: + '200': + description: Successful response + '500': + description: Internal Server Error + ``` + + + +## Embedding extensions + +If instead of overlaying your extensions within an overrides file, as mentioned above. Certain frameworks that generate OpenAPI Specifications make it easy to embed extensions directly from code. + +### FastAPI + +Please view our page on [FastAPI](/learn/api-definition/openapi/frameworks/fastapi) for more information on how to extend your OpenAPI Specification within FastAPI. + +## Request + response examples + +While OpenAPI has several fields for examples, there is no easy way +to associate a request with a response. This is especially useful when +you want to show more than one example in your documentation. + +`x-fern-examples` is an array of examples. Each element of the array +can contain `path-parameters`, `query-parameters`, `request` and `response` +examples values that are all associated. + +```yaml title="openapi.yml" {5-16} +paths: + /users/{userId}: + get: + x-fern-examples: + - path-parameters: + userId: user-1234 + response: + body: + name: Foo + ssn: 1234 + - path-parameters: + userId: user-4567 + response: + body: + name: Foo + ssn: 4567 +components: + schemas: + User: + type: object + properties: + name: + type: string + ssn: + type: integer +``` + +### Code samples + +If you'd like to specify custom code samples for your example, use `code-samples`. + +```yaml title="openapi.yml" {11-16} +paths: + /users/{userId}: + get: + x-fern-examples: + - path-parameters: + userId: user-1234 + response: + body: + name: Foo + ssn: 1234 + code-samples: + - sdk: typescript + code: | + import { UserClient } from "..."; + + client.users.get("user-1234") +``` + +If you're on the Fern Basic plan or higher for SDKs you won't have to worry about manually adding code samples! Our generators do that for you. + +## Availability + +The `x-fern-availability` extension is used to mark the availability of an endpoint. The availability information propagates into the generated Fern Docs website as visual tags. + +The options are: + +- `beta` +- `generally-available` +- `deprecated` + +The example below marks that the `POST /pet` endpoint is `deprecated`. + +```yaml title="x-fern-availability in openapi.yml" {4} +paths: + /pet: + post: + x-fern-availability: deprecated +``` + +This renders as: + + +![Screenshot of API Reference endpoint with tag showing deprecated](https://fern-image-hosting.s3.amazonaws.com/fern/x-fern-availability-example.png) + + +### Request new extensions + +If there's an extension you want that doesn't already exist, file an [issue](https://github.com/fern-api/fern/issues/new) to start a discussion about it. diff --git a/fern/products/api-def/openapi-pages/extensions/overview.md b/fern/products/api-def/openapi-pages/extensions/overview.md deleted file mode 100644 index a68db492..00000000 --- a/fern/products/api-def/openapi-pages/extensions/overview.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Overview of OpenAPI extensions -description: Learn about Fern's OpenAPI extensions ---- -Fern supports a variety of OpenAPI extensions that enhance your API specification and generate higher-quality SDKs. - -You can apply these extensions in two ways: by overlaying them in separate override files or by embedding them directly in your OpenAPI specification. See [Overrides](/api-definitions/overview/overrides) for more information. - -## Available extensions - -The table below shows all available extensions and links to detailed documentation for each one. - -| Extension | Description | -| --- | --- | -| [`x-fern-version`](./api-version) | Configure API version schemes and headers | -| [`x-fern-audiences`](./audiences) | Filter endpoints, schemas, and properties by audience | -| [`x-fern-availability`](./availability) | Mark availability status (beta, generally-available, deprecated) | -| [`x-fern-base-path`](./base-path) | Set base path prepended to all endpoints | -| [`x-fern-enum`](./enum-descriptions-and-names) | Add descriptions and custom names to enum values | -| [`x-fern-examples`](./request-response-examples) | Associate request and response examples | -| [`x-fern-global-headers`](./global-headers) | Configure headers used across all endpoints | -| [`x-fern-ignore`](./ignoring-elements) | Skip reading specific endpoints or schemas | -| [`x-fern-sdk-method-name`](./method-names) | Customize SDK method names | -| [`x-fern-sdk-group-name`](./method-names) | Organize methods into SDK groups | -| [`x-fern-parameter-name`](./parameter-names) | Customize parameter variable names | -| [`x-fern-property-name`](./property-names) | Customize object property variable names | -| [`x-fern-type-name`](./schema-names) | Override auto-generated names for inline schemas | -| [`x-fern-server-name`](./server-names) | Name your servers | - - - If there's an extension you want that doesn't already exist, file an [issue](https://github.com/fern-api/fern/issues/new) to start a discussion about it. - - -### FastAPI - -FastAPI allows you to add extensions directly in your route decorators and models. See our [FastAPI integration guide](/learn/api-definitions/openapi/frameworks/fastapi) for detailed examples. diff --git a/fern/products/api-def/openapi-pages/extensions/property-names.mdx b/fern/products/api-def/openapi-pages/extensions/property-names.mdx deleted file mode 100644 index e37da2f6..00000000 --- a/fern/products/api-def/openapi-pages/extensions/property-names.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Property names -description: Customize variable names for object properties using the `x-fern-property-name` extension ---- - -The `x-fern-property-name` extension allows you to customize the variable name for object -properties. - -For example, if you had a property called `_metadata` in your schema but you wanted the -variable to be called `data` in your SDK you would do the following: - -```yaml {6} -components: - schemas: - MyUser: - _metadata: - type: object - x-fern-property-name: data -``` \ No newline at end of file diff --git a/fern/products/api-def/openapi-pages/extensions/schema-names.mdx b/fern/products/api-def/openapi-pages/extensions/schema-names.mdx deleted file mode 100644 index 75e85feb..00000000 --- a/fern/products/api-def/openapi-pages/extensions/schema-names.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Schema names -description: Override auto-generated names for inline schemas using the `x-fern-type-name` extension ---- - -OpenAPI allows you to define inlined schemas that do not have names. - -```yaml title="Inline type in openapi.yml" {11} -components: - schemas: - Movie: - type: object - properties: - name: - type: string - cast: - type: array - items: - type: object - properties: - firstName: - type: string - lastName: - type: string - age: - type: integer -``` - -Fern automatically generates names for all the inlined schemas. For example, in this example, -Fern would generate the name `CastItem` for the inlined array item schema. - -```typescript title="Auto-generated name" {6} -export interface Movie { - name?: string; - cast?: CastItem[]; -} - -export interface CastItem { - firstName?: string; - lastName?: string; - age?: integer; -} -``` - -If you want to override the generated name, you can use the extension `x-fern-type-name`. - -```yaml title="openapi.yml" {12} -components: - schemas: - Movie: - type: object - properties: - name: - type: string - cast: - type: array - items: - type: object - x-fern-type-name: Person - properties: - firstName: - type: string - lastName: - type: string - age: - type: integer -``` - -This would replace `CastItem` with `Person` and the generated code would read more idiomatically: - -```typescript title="Overridden name" {6} -export interface Movie { - name?: string; - cast?: Person[]; -} - -export interface Person { - firstName?: string; - lastName?: string; - age?: integer; -} -``` diff --git a/fern/products/api-def/openapi-pages/extensions/server-names.mdx b/fern/products/api-def/openapi-pages/extensions/server-names.mdx deleted file mode 100644 index a5f2c159..00000000 --- a/fern/products/api-def/openapi-pages/extensions/server-names.mdx +++ /dev/null @@ -1,25 +0,0 @@ - ---- -title: Server names -description: Name your servers using the `x-fern-server-name` extension ---- - -The `x-fern-server-name` extension is used to name your servers. - -```yaml title="openapi.yml" -servers: - - url: https://api.example.com - x-fern-server-name: Production - - url: https://sandbox.example.com - x-fern-server-name: Sandbox -``` - -In a generated TypeScript SDK, you'd see: - -```typescript title="environment.ts" -export const ExampleEnvironment = { - Production: "https://api.example.com" -} as const; - -export type ExampleEnvironment = typeof ExampleEnvironment.Production; -``` \ No newline at end of file diff --git a/fern/products/api-def/openapi-pages/overrides.mdx b/fern/products/api-def/openapi-pages/overrides.mdx new file mode 100644 index 00000000..50d6462d --- /dev/null +++ b/fern/products/api-def/openapi-pages/overrides.mdx @@ -0,0 +1,74 @@ +--- +title: Overlay customizations on an existing OpenAPI spec +subtitle: Can't directly modify your OpenAPI spec? No worries, use an overrides file instead. +--- + +If you generate your OpenAPI from server code, you may want to tweak your OpenAPI Spec without having to +touch the generated file. Fern supports this via an `overrides` file. + + +```yml openapi.yml +paths: + /users: + post: + description: Create a User + operationId: users_post + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' +``` +```yml title="overrides.yml" {4-5} +paths: + /users: + post: + x-fern-sdk-group-name: users + x-fern-sdk-method-name: create +``` +```yml title="combined" {4-5} +paths: + /users/post: + post: + x-fern-sdk-group-name: users + x-fern-sdk-method-name: create + description: Create a User + operationId: users_post + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' +``` + + +## Configuration + +Follow the steps below to configure your OpenAPI overrides: + + +### Create an `overrides.yml` + +Simply create a yaml file and write down all the overrides you want to add: + +```yaml overrides.yml +paths: + /v1/history: + get: + x-fern-sdk-group-name: + - history + x-fern-sdk-method-name: get_all +``` + +### Reference the file in your `generators.yml` + +```yml generators.yml +api: + path: ../openapi.yml + overrides: ../overrides.yml +``` + + The format of the overrides file is independent from the spec. For example, even if your OpenAPI spec is in JSON format, you can write the overrides in yaml. + + + diff --git a/fern/products/api-def/openapi-pages/overview.mdx b/fern/products/api-def/openapi-pages/overview.mdx index d58c7ed2..c6cc053e 100644 --- a/fern/products/api-def/openapi-pages/overview.mdx +++ b/fern/products/api-def/openapi-pages/overview.mdx @@ -1,12 +1,14 @@ --- title: What is an OpenAPI Specification? -description: OpenAPI is a standard for documenting REST APIs +subtitle: OpenAPI is a standard for documenting REST APIs --- The OpenAPI Specification (OAS) is a framework used by developers to document REST APIs. The specification written in JSON or YAML and contains all of your endpoints, parameters, schemas, and authentication schemes. Fern is compatible with the latest OAS release, which is currently [v3.1.1](https://spec.openapis.org/#openapi-specification). + Considering options to generate an OpenAPI spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) + Below is an example of an OpenAPI file: ```yaml openapi.yml @@ -104,8 +106,6 @@ components: ## Setup your fern folder - Considering options to generate an OpenAPI spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) - Start by initializing your fern folder with an OpenAPI spec diff --git a/fern/products/api-def/openapi-pages/reference/generators-reference.mdx b/fern/products/api-def/openapi-pages/reference/generators-reference.mdx deleted file mode 100644 index 00dec2c8..00000000 --- a/fern/products/api-def/openapi-pages/reference/generators-reference.mdx +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: OpenAPI generators.yml reference -description: Reference for configuring OpenAPI specifications in your generators.yml file ---- - -Configure how your OpenAPI specification is processed and transformed into SDKs using the `generators.yml` configuration file. - - \ No newline at end of file diff --git a/fern/products/api-def/openapi-pages/webhooks.mdx b/fern/products/api-def/openapi-pages/webhooks.mdx index 841d1e81..a6d9ebdd 100644 --- a/fern/products/api-def/openapi-pages/webhooks.mdx +++ b/fern/products/api-def/openapi-pages/webhooks.mdx @@ -12,60 +12,17 @@ Fern supports two methods for defining webhooks in your OpenAPI specification: For OpenAPI 3.1 specifications, use the `webhooks` top-level field to define your webhook operations. Each webhook requires an `operationId` to be properly processed by Fern. -To create dedicated pages in your API reference documentation for each webhook -event, include `tags` and complete `example` data in your schema. Then, [add a -reference in your -`docs.yml`](/docs/api-references/generate-webhook-reference#create-individual-documentation-pages-for-each-webhook-event-openapi). - -```yaml openapi.yml {4, 7-8, 42-48} +```yaml openapi.yml {4} webhooks: newPlant: post: - operationId: newPlantWebhook # Defines webhook - summary: New Plant Added - description: Information about a new plant that was added to the store - tags: - - Plants # Creates dedicated page + operationId: newPlantWebhook requestBody: - description: The plant data when a new plant is added + description: Information about a new Plant in the system content: application/json: schema: - description: The Webhook payload for when a new plant is added to the store - properties: - triggerType: - description: The type of event that triggered the request - type: string - example: "new_plant" - payload: - type: object - description: The payload of data sent from the plant store - properties: - plantId: - type: string - description: The unique identifier for the plant - example: "64f1a2b3c5d6e7f8a9b0c1d2" - name: - type: string - description: The name of the plant - example: "Monstera Deliciosa" - price: - type: number - format: float - description: The price of the plant in dollars - example: 29.99 - addedAt: - type: string - format: date-time - description: The timestamp when the plant was added - example: "2024-01-15T10:30:00.000Z" - example: # Full payload example for docs - triggerType: "new_plant" - payload: - plantId: "64f1a2b3c5d6e7f8a9b0c1d2" - name: "Monstera Deliciosa" - price: 29.99 - addedAt: "2024-01-15T10:30:00.000Z" + $ref: '#/components/schemas/Plant' responses: '200': description: Return a 200 status to indicate that the data was received successfully @@ -75,20 +32,13 @@ webhooks: For OpenAPI 3.0, use the `x-fern-webhook: true` extension to define webhooks. Fern will treat the `requestBody` as the webhook payload. -To create dedicated pages in your API reference documentation for each webhook -event, include `tags` and complete `example` data in your schema. Then, [add a -reference in your -`docs.yml`](/docs/api-references/generate-webhook-reference#create-individual-documentation-pages-for-each-webhook-event-openapi). - -```yaml openapi.yml {6-8, 23-25} +```yaml openapi.yml {6} paths: /payment/updated/: post: summary: Payment Initiated operationId: initiatePayment - tags: - - Payments # Creates dedicated page - x-fern-webhook: true # Defines webhooks + x-fern-webhook: true requestBody: content: application/json: @@ -97,15 +47,11 @@ paths: properties: amount: type: number - example: 99.99 currency: $ref: '#/components/schemas/Currency' required: - amount - - currency - example: # Full payload example for docs - amount: 99.99 - currency: "USD" + - currency ``` diff --git a/fern/products/api-def/openrpc-def.yml b/fern/products/api-def/openrpc-def.yml deleted file mode 100644 index f1522a99..00000000 --- a/fern/products/api-def/openrpc-def.yml +++ /dev/null @@ -1,5 +0,0 @@ -navigation: - - page: OpenRPC Definition Redirect Page - path: ./pages/openrpc-empty.mdx - slug: empty-page - hidden: true diff --git a/fern/products/api-def/openrpc-pages/extensions/availability.mdx b/fern/products/api-def/openrpc-pages/extensions/availability.mdx deleted file mode 100644 index 218d9fa7..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/availability.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Availability -description: Mark features as available in specific SDK versions using `x-fern-availability` extension ---- - -Mark features as available in specific SDK versions: - -```yaml title="openrpc.yml" {4-6} -methods: - - name: beta.advancedSearch - summary: Advanced search functionality - x-fern-availability: - status: beta - message: "This feature is in beta and may change" - params: - - name: searchQuery - schema: - $ref: '#/components/schemas/AdvancedSearchQuery' - result: - name: searchResults - schema: - $ref: '#/components/schemas/SearchResults' -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/base-path.mdx b/fern/products/api-def/openrpc-pages/extensions/base-path.mdx deleted file mode 100644 index 22cb0d7b..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/base-path.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Base path -description: Configure base paths for generated SDK clients using `x-fern-base-path` extension ---- - -Configure base paths for generated SDK clients: - -```yaml title="openrpc.yml" {3-4} -info: - title: My JSON-RPC API - version: 1.0.0 - x-fern-base-path: /api/v1/rpc - description: JSON-RPC API with custom base path -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/error-handling.mdx b/fern/products/api-def/openrpc-pages/extensions/error-handling.mdx deleted file mode 100644 index 41c4297e..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/error-handling.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Error handling -description: Configure error handling for methods using `x-fern-error-handling` extension ---- - -Configure error handling for methods: - -```yaml title="openrpc.yml" {10-20} -methods: - - name: order.create - summary: Create a new order - params: - - name: orderData - schema: - $ref: '#/components/schemas/CreateOrderRequest' - errors: - - code: -32001 - message: Insufficient inventory - x-fern-error-handling: - error_name: InsufficientInventoryError - retry_after_seconds: 60 - - code: -32002 - message: Payment failed - x-fern-error-handling: - error_name: PaymentFailedError - user_friendly_message: "Payment could not be processed. Please check your payment information." - result: - name: order - schema: - $ref: '#/components/schemas/Order' -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/examples.mdx b/fern/products/api-def/openrpc-pages/extensions/examples.mdx deleted file mode 100644 index aa667633..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/examples.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Request + response examples -description: Provide additional examples for better SDK documentation using `x-fern-examples` extension ---- - -Provide additional examples for better SDK documentation: - -```yaml title="openrpc.yml" {8-25} -methods: - - name: user.create - summary: Create a new user - params: - - name: userData - schema: - $ref: '#/components/schemas/CreateUserRequest' - required: true - x-fern-examples: - - name: StandardUser - description: Create a regular user account - params: - userData: - email: "john@example.com" - name: "John Doe" - role: "user" - result: - id: "user_123" - email: "john@example.com" - name: "John Doe" - role: "user" - createdAt: "2024-01-15T10:30:00Z" - - name: AdminUser - description: Create an admin user account - params: - userData: - email: "admin@example.com" - name: "Admin User" - role: "admin" - permissions: ["read", "write", "delete"] - result: - id: "user_456" - email: "admin@example.com" - name: "Admin User" - role: "admin" - createdAt: "2024-01-15T10:30:00Z" - result: - name: user - schema: - $ref: '#/components/schemas/User' -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/ignore.mdx b/fern/products/api-def/openrpc-pages/extensions/ignore.mdx deleted file mode 100644 index 59df1f37..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/ignore.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Ignoring methods or schemas -description: Skip reading specific OpenRPC elements using `x-fern-ignore` extension ---- - -Use `x-fern-ignore` to exclude specific methods or schemas from SDK generation: - -```yaml title="openrpc.yml" {4-5, 12-13} -methods: - - name: debug.internalMethod - summary: Internal debugging method - x-fern-ignore: true - params: - - name: debugData - schema: - type: object - result: - name: debugResult - schema: - type: object - - name: test.experimentalFeature - summary: Experimental feature (not ready for public use) - x-fern-ignore: true - params: [] - result: - name: result - schema: - type: string -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/others.mdx b/fern/products/api-def/openrpc-pages/extensions/others.mdx new file mode 100644 index 00000000..365ae046 --- /dev/null +++ b/fern/products/api-def/openrpc-pages/extensions/others.mdx @@ -0,0 +1,302 @@ +--- +title: Other Extensions +subtitle: Additional Fern extensions for OpenRPC specifications +--- + +Fern supports various extensions to enhance your OpenRPC specifications and improve the generated SDKs and documentation. + +## `x-fern-ignore` + +Use `x-fern-ignore` to exclude specific methods or schemas from SDK generation: + +```yaml title="openrpc.yml" {4-5, 12-13} +methods: + - name: debug.internalMethod + summary: Internal debugging method + x-fern-ignore: true + params: + - name: debugData + schema: + type: object + result: + name: debugResult + schema: + type: object + - name: test.experimentalFeature + summary: Experimental feature (not ready for public use) + x-fern-ignore: true + params: [] + result: + name: result + schema: + type: string +``` + +## `x-fern-examples` + +Provide additional examples for better SDK documentation: + +```yaml title="openrpc.yml" {8-25} +methods: + - name: user.create + summary: Create a new user + params: + - name: userData + schema: + $ref: '#/components/schemas/CreateUserRequest' + required: true + x-fern-examples: + - name: StandardUser + description: Create a regular user account + params: + userData: + email: "john@example.com" + name: "John Doe" + role: "user" + result: + id: "user_123" + email: "john@example.com" + name: "John Doe" + role: "user" + createdAt: "2024-01-15T10:30:00Z" + - name: AdminUser + description: Create an admin user account + params: + userData: + email: "admin@example.com" + name: "Admin User" + role: "admin" + permissions: ["read", "write", "delete"] + result: + id: "user_456" + email: "admin@example.com" + name: "Admin User" + role: "admin" + createdAt: "2024-01-15T10:30:00Z" + result: + name: user + schema: + $ref: '#/components/schemas/User' +``` + +## `x-fern-pagination` + +Configure pagination for methods that return multiple results: + +```yaml title="openrpc.yml" {6-11} +methods: + - name: user.list + summary: List users with pagination + params: + - name: pagination + schema: + type: object + properties: + cursor: + type: string + limit: + type: integer + default: 20 + x-fern-pagination: + cursor: pagination.cursor + results: users + next_cursor: pagination.nextCursor + has_next_page: pagination.hasMore + result: + name: userList + schema: + type: object + properties: + users: + type: array + items: + $ref: '#/components/schemas/User' + pagination: + type: object + properties: + nextCursor: + type: string + hasMore: + type: boolean +``` + +## `x-fern-retry` + +Configure retry behavior for methods: + +```yaml title="openrpc.yml" {6-10} +methods: + - name: payment.process + summary: Process payment with retry logic + params: + - name: paymentData + schema: + $ref: '#/components/schemas/PaymentRequest' + x-fern-retry: + max_attempts: 3 + exponential_backoff: true + initial_delay: 1000 + max_delay: 30000 + result: + name: paymentResult + schema: + $ref: '#/components/schemas/PaymentResult' +``` + +## `x-fern-timeout` + +Configure timeout settings for methods: + +```yaml title="openrpc.yml" {6-8} +methods: + - name: report.generate + summary: Generate large report (may take time) + params: + - name: reportConfig + schema: + $ref: '#/components/schemas/ReportConfig' + x-fern-timeout: + seconds: 300 + description: "Report generation can take up to 5 minutes" + result: + name: report + schema: + $ref: '#/components/schemas/Report' +``` + +## `x-fern-error-handling` + +Configure error handling for methods: + +```yaml title="openrpc.yml" {10-20} +methods: + - name: order.create + summary: Create a new order + params: + - name: orderData + schema: + $ref: '#/components/schemas/CreateOrderRequest' + errors: + - code: -32001 + message: Insufficient inventory + x-fern-error-handling: + error_name: InsufficientInventoryError + retry_after_seconds: 60 + - code: -32002 + message: Payment failed + x-fern-error-handling: + error_name: PaymentFailedError + user_friendly_message: "Payment could not be processed. Please check your payment information." + result: + name: order + schema: + $ref: '#/components/schemas/Order' +``` + +## `x-fern-availability` + +Mark features as available in specific SDK versions: + +```yaml title="openrpc.yml" {4-6} +methods: + - name: beta.advancedSearch + summary: Advanced search functionality + x-fern-availability: + status: beta + message: "This feature is in beta and may change" + params: + - name: searchQuery + schema: + $ref: '#/components/schemas/AdvancedSearchQuery' + result: + name: searchResults + schema: + $ref: '#/components/schemas/SearchResults' +``` + +## `x-fern-streaming` + +Mark methods as streaming for appropriate SDK generation: + +```yaml title="openrpc.yml" {4-6} +methods: + - name: logs.stream + summary: Stream log events + x-fern-streaming: + type: server_sent_events + termination: client_closes + params: + - name: filters + schema: + type: object + properties: + level: + type: string + enum: [debug, info, warn, error] + service: + type: string + # Note: Streaming methods typically don't have a traditional result +``` + +## `x-fern-server-name` + +Specify custom names for servers: + +```yaml title="openrpc.yml" {3-4} +servers: + - name: production + url: https://api.yourcompany.com/rpc + x-fern-server-name: Production + description: Production JSON-RPC server + - name: staging + url: https://staging-api.yourcompany.com/rpc + x-fern-server-name: Staging + description: Staging environment +``` + +## `x-fern-base-path` + +Configure base paths for generated SDK clients: + +```yaml title="openrpc.yml" {3-4} +info: + title: My JSON-RPC API + version: 1.0.0 + x-fern-base-path: /api/v1/rpc + description: JSON-RPC API with custom base path +``` + +## `x-fern-sdk-group-name` + +Group related methods in the SDK: + +```yaml title="openrpc.yml" {4-5, 12-13} +methods: + - name: user.create + summary: Create user + x-fern-sdk-group-name: users + params: [...] + result: {...} + + - name: user.get + summary: Get user + x-fern-sdk-group-name: users + params: [...] + result: {...} + + - name: order.create + summary: Create order + x-fern-sdk-group-name: orders + params: [...] + result: {...} +``` + +This generates SDKs with grouped methods: + +```typescript +client.users.create(...) +client.users.get(...) +client.orders.create(...) +``` + +These extensions help you create more robust and user-friendly SDKs while maintaining full control over the generated code structure and behavior. \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/overview.md b/fern/products/api-def/openrpc-pages/extensions/overview.md deleted file mode 100644 index 50e6b82e..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Overview of OpenRPC extensions -description: Learn about Fern's OpenRPC extensions for generating higher-quality SDKs ---- - -Fern supports a variety of OpenRPC extensions that enhance your API specification and generate higher-quality SDKs. - -You can apply these extensions in two ways: by overlaying them in separate override files or by embedding them directly in your OpenRPC specification. See [Overrides](/api-definitions/overview/overrides) for more information. - -## Available extensions - -The table below shows all available extensions and links to detailed documentation for each one. - -| Extension | Description | -| --- | --- | -| [`x-fern-ignore`](./ignoring-elements) | Skip reading specific methods or schemas | -| [`x-fern-examples`](./request-response-examples) | Provide additional examples for better SDK documentation | -| [`x-fern-pagination`](./pagination) | Configure pagination for methods that return multiple results | -| [`x-fern-retry`](./retry-behavior) | Configure retry behavior for methods | -| [`x-fern-timeout`](./timeout-settings) | Configure timeout settings for methods | -| [`x-fern-error-handling`](./error-handling) | Configure error handling for methods | -| [`x-fern-availability`](./availability) | Mark features as available in specific SDK versions | -| [`x-fern-streaming`](./streaming-operations) | Mark methods as streaming for appropriate SDK generation | -| [`x-fern-server-name`](./server-names) | Specify custom names for servers | -| [`x-fern-base-path`](./base-path) | Configure base paths for generated SDK clients | -| [`x-fern-sdk-group-name`](./sdk-group-names) | Group related methods in the SDK | - - - If there's an extension you want that doesn't already exist, file an [issue](https://github.com/fern-api/fern/issues/new) to start a discussion about it. - \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/pagination.mdx b/fern/products/api-def/openrpc-pages/extensions/pagination.mdx deleted file mode 100644 index 8b26b213..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/pagination.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Pagination -description: Configure pagination for methods that return multiple results using `x-fern-pagination` extension ---- - -Configure pagination for methods that return multiple results: - -```yaml title="openrpc.yml" {6-11} -methods: - - name: user.list - summary: List users with pagination - params: - - name: pagination - schema: - type: object - properties: - cursor: - type: string - limit: - type: integer - default: 20 - x-fern-pagination: - cursor: pagination.cursor - results: users - next_cursor: pagination.nextCursor - has_next_page: pagination.hasMore - result: - name: userList - schema: - type: object - properties: - users: - type: array - items: - $ref: '#/components/schemas/User' - pagination: - type: object - properties: - nextCursor: - type: string - hasMore: - type: boolean -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/retry.mdx b/fern/products/api-def/openrpc-pages/extensions/retry.mdx deleted file mode 100644 index ee4083db..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/retry.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Retry behavior -description: Configure retry behavior for methods using `x-fern-retry` extension ---- - -Configure retry behavior for methods: - -```yaml title="openrpc.yml" {6-10} -methods: - - name: payment.process - summary: Process payment with retry logic - params: - - name: paymentData - schema: - $ref: '#/components/schemas/PaymentRequest' - x-fern-retry: - max_attempts: 3 - exponential_backoff: true - initial_delay: 1000 - max_delay: 30000 - result: - name: paymentResult - schema: - $ref: '#/components/schemas/PaymentResult' -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/sdk-group-name.mdx b/fern/products/api-def/openrpc-pages/extensions/sdk-group-name.mdx deleted file mode 100644 index 9e210701..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/sdk-group-name.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: SDK group names -description: Group related methods in the SDK using `x-fern-sdk-group-name` extension ---- - -Group related methods in the SDK: - -```yaml title="openrpc.yml" {4-5, 12-13} -methods: - - name: user.create - summary: Create user - x-fern-sdk-group-name: users - params: [...] - result: {...} - - - name: user.get - summary: Get user - x-fern-sdk-group-name: users - params: [...] - result: {...} - - - name: order.create - summary: Create order - x-fern-sdk-group-name: orders - params: [...] - result: {...} -``` - -This generates SDKs with grouped methods: - -```typescript -client.users.create(...) -client.users.get(...) -client.orders.create(...) -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/server-name.mdx b/fern/products/api-def/openrpc-pages/extensions/server-name.mdx deleted file mode 100644 index d8d127b3..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/server-name.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Server names -description: Specify custom names for servers using `x-fern-server-name` extension ---- - -Specify custom names for servers: - -```yaml title="openrpc.yml" {3-4} -servers: - - name: production - url: https://api.yourcompany.com/rpc - x-fern-server-name: Production - description: Production JSON-RPC server - - name: staging - url: https://staging-api.yourcompany.com/rpc - x-fern-server-name: Staging - description: Staging environment -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/streaming.mdx b/fern/products/api-def/openrpc-pages/extensions/streaming.mdx deleted file mode 100644 index 305d3ec6..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/streaming.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Streaming operations -description: Mark methods as streaming for appropriate SDK generation using `x-fern-streaming` extension ---- - -Mark methods as streaming for appropriate SDK generation: - -```yaml title="openrpc.yml" {4-6} -methods: - - name: logs.stream - summary: Stream log events - x-fern-streaming: - type: server_sent_events - termination: client_closes - params: - - name: filters - schema: - type: object - properties: - level: - type: string - enum: [debug, info, warn, error] - service: - type: string - # Note: Streaming methods typically don't have a traditional result -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/extensions/timeout.mdx b/fern/products/api-def/openrpc-pages/extensions/timeout.mdx deleted file mode 100644 index d1979fa8..00000000 --- a/fern/products/api-def/openrpc-pages/extensions/timeout.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Timeout settings -description: Configure timeout settings for methods using `x-fern-timeout` extension ---- - -Configure timeout settings for methods: - -```yaml title="openrpc.yml" {6-8} -methods: - - name: report.generate - summary: Generate large report (may take time) - params: - - name: reportConfig - schema: - $ref: '#/components/schemas/ReportConfig' - x-fern-timeout: - seconds: 300 - description: "Report generation can take up to 5 minutes" - result: - name: report - schema: - $ref: '#/components/schemas/Report' -``` \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/overrides.mdx b/fern/products/api-def/openrpc-pages/overrides.mdx new file mode 100644 index 00000000..a3ae23e5 --- /dev/null +++ b/fern/products/api-def/openrpc-pages/overrides.mdx @@ -0,0 +1,274 @@ +--- +title: Overlay Customizations +subtitle: Use overlay files to modify your OpenRPC specification without editing the original +--- + +Overlays allow you to modify your OpenRPC specification without directly editing the original file. This is useful for: +- Adding Fern-specific extensions +- Customizing documentation +- Adding examples and descriptions +- Overriding specific properties + +## Configure overlays + +To use overlays, add them to your `generators.yml` file: + +```yaml title="generators.yml" {3-5} +api: + specs: + - spec: openrpc.yml + overlays: + - overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + +## Overlay file structure + +Overlay files follow the [OpenAPI Overlay Specification](https://spec.openapis.org/overlay/v1.0.0) format: + +```yaml title="overlay.yml" +overlay: 1.0.0 +info: + title: OpenRPC Fern Extensions + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'user.create')] + update: + x-fern-sdk-method-name: create + summary: Create a new user account + - target: $.methods[?(@.name == 'order.list')] + update: + description: Retrieve orders with optional filtering and pagination + x-fern-audiences: + - public +``` + +## Add method names + +Override SDK method names for better developer experience: + +```yaml title="overlay.yml" {7-9} +overlay: 1.0.0 +info: + title: SDK Method Names + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'user.getById')] + update: + x-fern-sdk-method-name: getUser + summary: Retrieve user by ID with enhanced details + - target: $.methods[?(@.name == 'order.createNew')] + update: + x-fern-sdk-method-name: create + summary: Create order with automatic validation +``` + +## Add examples + +Enhance your specification with examples: + +```yaml title="overlay.yml" {7-20} +overlay: 1.0.0 +info: + title: Method Examples + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'user.create')] + update: + examples: + - name: StandardUser + description: Create a regular user + params: + userData: + email: "john@example.com" + name: "John Doe" + role: "user" + result: + id: "user_123" + email: "john@example.com" + name: "John Doe" + createdAt: "2024-01-15T10:30:00Z" +``` + +## Filter with audiences + +Add audience filtering to methods: + +```yaml title="overlay.yml" {7-9, 12-14} +overlay: 1.0.0 +info: + title: Audience Filtering + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'admin.getUsers')] + update: + x-fern-audiences: + - admin + - target: $.methods[?(@.name == 'debug.getSystemInfo')] + update: + x-fern-audiences: + - internal +``` + +## Add documentation + +Enhance descriptions and documentation: + +```yaml title="overlay.yml" {7-14} +overlay: 1.0.0 +info: + title: Enhanced Documentation + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'payment.process')] + update: + description: | + Process a payment transaction with comprehensive validation and fraud detection. + + This method supports multiple payment methods including credit cards, + digital wallets, and bank transfers. All transactions are processed + securely with PCI DSS compliance. + + Returns a payment result with transaction details or error information. + summary: Process payment with fraud detection +``` + +## Server configurations + +Add server-specific configurations: + +```yaml title="overlay.yml" {7-12} +overlay: 1.0.0 +info: + title: Server Extensions + version: 1.0.0 +actions: + - target: $.servers[?(@.name == 'production')] + update: + x-fern-server-name: Production + description: Production environment with high availability and monitoring + variables: + region: + default: us-east-1 + enum: [us-east-1, us-west-2, eu-west-1] + description: AWS region for the API server +``` + +## Add parameter customizations + +Customize parameter names and descriptions: + +```yaml title="overlay.yml" {7-18} +overlay: 1.0.0 +info: + title: Parameter Customizations + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'user.search')].params[?(@.name == 'search_criteria')] + update: + x-fern-parameter-name: searchCriteria + description: | + Search criteria for finding users. Supports multiple filters: + - name: Partial name matching (case-insensitive) + - email: Exact or partial email matching + - role: Filter by user role + - status: Filter by account status + - dateRange: Filter by creation date range + schema: + type: object + properties: + name: + type: string + description: Partial name search (minimum 2 characters) + email: + type: string + description: Email search pattern + role: + type: string + enum: [user, admin, moderator] + status: + type: string + enum: [active, inactive, suspended] +``` + +## Add error documentation + +Enhance error handling information: + +```yaml title="overlay.yml" {7-25} +overlay: 1.0.0 +info: + title: Error Documentation + version: 1.0.0 +actions: + - target: $.methods[?(@.name == 'order.create')] + update: + errors: + - code: -32001 + message: Insufficient inventory + data: + type: object + properties: + productId: + type: string + availableQuantity: + type: integer + requestedQuantity: + type: integer + - code: -32002 + message: Payment authorization failed + data: + type: object + properties: + paymentMethod: + type: string + errorCode: + type: string + retryAllowed: + type: boolean +``` + +## Multiple overlays + +You can apply multiple overlay files in sequence: + +```yaml title="generators.yml" {4-8} +api: + specs: + - spec: openrpc.yml + overlays: + - base-overlay.yml + - sdk-overlay.yml + - docs-overlay.yml + - examples-overlay.yml +``` + +## Environment-specific overlays + +Use different overlays for different environments: + +```yaml title="generators.yml" {4-7, 12-15} +groups: + production: + audiences: [public] + specs: + - spec: openrpc.yml + overlays: + - production-overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 + internal: + audiences: [admin, internal] + specs: + - spec: openrpc.yml + overlays: + - internal-overlay.yml + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.8.8 +``` + +Overlays are applied in order, allowing you to build up customizations incrementally while keeping your original OpenRPC specification clean and focused on the core API definition. \ No newline at end of file diff --git a/fern/products/api-def/openrpc-pages/overview.mdx b/fern/products/api-def/openrpc-pages/overview.mdx index cb9a03cb..17341b14 100644 --- a/fern/products/api-def/openrpc-pages/overview.mdx +++ b/fern/products/api-def/openrpc-pages/overview.mdx @@ -1,12 +1,14 @@ --- title: What is an OpenRPC Specification? -description: OpenRPC is a standard for documenting JSON-RPC APIs +subtitle: OpenRPC is a standard for documenting JSON-RPC APIs --- The OpenRPC Specification is a framework used by developers to document JSON-RPC APIs. The specification is written in JSON or YAML and contains all of your methods, parameters, schemas, and server configurations. Fern is compatible with OpenRPC specification [v1.3.2](https://spec.open-rpc.org/) and [v1.2.6](https://github.com/open-rpc/spec/releases/tag/1.2.6). + Considering options to generate an OpenRPC spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) + Below is an example of an OpenRPC file: ```yaml openrpc.yml @@ -142,9 +144,7 @@ components: - timestamp ``` -## Set up your fern folder - - Considering options to generate an OpenRPC spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email) +## Setup your fern folder Start by initializing your fern folder with an OpenRPC spec diff --git a/fern/products/api-def/pages/asyncapi-empty.mdx b/fern/products/api-def/pages/asyncapi-empty.mdx deleted file mode 100644 index ce8d9a62..00000000 --- a/fern/products/api-def/pages/asyncapi-empty.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: AsyncAPI Definition Redirect Page -description: This is an empty page used to redirect to the AsyncAPI Definition pages. ---- - -This page is empty. Please visit the [AsyncAPI Definition](/api-definitions/asyncapi/overview) page for more information. \ No newline at end of file diff --git a/fern/products/api-def/pages/ferndef-empty.mdx b/fern/products/api-def/pages/ferndef-empty.mdx deleted file mode 100644 index 3e724c36..00000000 --- a/fern/products/api-def/pages/ferndef-empty.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Fern Definition Redirect Page -description: This is an empty page used to redirect to the Fern Definition pages. ---- - -This page is empty. Please visit the [Fern Definition](/api-definitions/ferndef/overview) page for more information. \ No newline at end of file diff --git a/fern/products/api-def/pages/grpc-empty.mdx b/fern/products/api-def/pages/grpc-empty.mdx deleted file mode 100644 index 5c515348..00000000 --- a/fern/products/api-def/pages/grpc-empty.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: gRPC Definition Redirect Page -description: This is an empty page used to redirect to the gRPC Definition pages. ---- - -This page is empty. Please visit the [gRPC Definition](/api-definitions/grpc/overview) page for more information. \ No newline at end of file diff --git a/fern/products/api-def/pages/openapi-empty.mdx b/fern/products/api-def/pages/openapi-empty.mdx deleted file mode 100644 index 34787423..00000000 --- a/fern/products/api-def/pages/openapi-empty.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: OpenAPI Definition Redirect Page -description: This is an empty page used to redirect to the OpenAPI Definition pages. ---- - -This page is empty. Please visit the [OpenAPI Definition](/api-definitions/openapi/overview) page for more information. \ No newline at end of file diff --git a/fern/products/api-def/pages/openrpc-empty.mdx b/fern/products/api-def/pages/openrpc-empty.mdx deleted file mode 100644 index 2e110f76..00000000 --- a/fern/products/api-def/pages/openrpc-empty.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: OpenRPC Definition Redirect Page -description: This is an empty page used to redirect to the OpenRPC Definition pages. ---- - -This page is empty. Please visit the [OpenRPC Definition](/api-definitions/openrpc/overview) page for more information. \ No newline at end of file diff --git a/fern/products/api-def/pages/overrides.mdx b/fern/products/api-def/pages/overrides.mdx deleted file mode 100644 index b1b03a59..00000000 --- a/fern/products/api-def/pages/overrides.mdx +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: Overrides -description: Customize your API definition using a separate overrides file. ---- - -Use an overrides file to customize your OpenAPI, AsyncAPI, or OpenRPC definition without modifying the original spec. This is useful when: - -* Your API specification is auto-generated from server code -* You need different configurations for SDKs versus documentation - -Overrides are available for OpenAPI, AsyncAPI, and OpenRPC specifications. They are not needed for [Fern Definition](/api-definitions/ferndef/overview) since you can directly edit those files. - - -While you can also embed [Fern extensions](/api-definitions/overview/overrides#definition-specific-extensions) directly in your API specification, using overrides files is the recommended approach as it keeps your original spec clean and separates concerns. - - -## Implement overrides - - - - -[Create an `overrides.yml` file](/cli-api-reference/cli-reference/commands#fern-write-overrides) in the folder that contains your API definition: - -```bash {6} -fern/ - ├─ fern.config.json - ├─ generators.yml - └─ spec-folder/ - ├─ spec-file.yml # API definition - └─ overrides.yml -``` - - The format of the overrides file is independent from the spec. For example, even if your OpenAPI spec is in JSON format, you can write the overrides in yaml. - - - - -For OpenAPI, AsyncAPI, and OpenRPC, you can use [Fern's extensions](/api-definitions/overview/overrides#definition-specific-extensions) to apply customizations. - -```yml title="overrides.yml" {4-5} -paths: - /users: - post: - x-fern-sdk-group-name: users - x-fern-sdk-method-name: create -``` - - - - -```yaml title="generators.yml" -api: - specs: - - openapi: spec-file.yml - overrides: ./overrides.yml -``` - - -Now when you run `fern generate`, Fern combines your original API specification with the overrides file: - - -```yml openapi.yml -paths: - /users: - post: - description: Create a User - operationId: users_post - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/User' -``` -```yml title="overrides.yml" {4-5} -paths: - /users: - post: - x-fern-sdk-group-name: users - x-fern-sdk-method-name: create -``` -```yml title="combined" {4-5} -paths: - /users/post: - post: - x-fern-sdk-group-name: users - x-fern-sdk-method-name: create - description: Create a User - operationId: users_post - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/User' -``` - - - - -## Separate overrides for SDKs and Docs - -For separate SDK and documentation configurations, you can use different override files in separate folders with their own `generators.yml` files. - -```bash -fern/ - ├─ fern.config.json - ├─ generators.yml - └─ apis/ - ├─ docs/ # Documentation configuration - │ ├─ generators.yml - │ └─ docs-overrides.yml # Documentation-specific overrides - ├─ sdks/ # SDK configuration - │ ├─ generators.yml - │ └─ sdk-overrides.yml # SDK-specific overrides - └─ openapi/ - └─ openapi.yml # Original API specification -``` - -Both `generators.yml` files can be identical except for pointing to different override files: - - - - -```yaml title="docs/generators.yml" -api: - specs: - - openapi: ../openapi/openapi.yml - overrides: ./docs-overrides.yml -``` - - -```yaml title="sdks/generators.yml" -api: - specs: - - openapi: ../openapi/openapi.yml - overrides: ./sdk-overrides.yml -``` - - - -## Overrides for different environments - -You can configure different override files for different environments. Overrides are applied in order, allowing you to build up customizations incrementally while keeping your original specification clean and focused. - -```yaml title="generators.yml" {4-7, 12-15} -groups: - production: - audiences: [public] - specs: - - openrpc: openrpc.yml - overrides: - - production-override.yml - generators: - - name: fernapi/fern-typescript-node-sdk - version: 0.8.8 - internal: - audiences: [admin, internal] - specs: - - openrpc: openrpc.yml - override: - - internal-override.yml - generators: - - name: fernapi/fern-typescript-node-sdk - version: 0.8.8 -``` - -## Definition-specific extensions - -Learn more about the Fern extensions you can use to customize your definition: - - - - - - - - - diff --git a/fern/products/api-def/pages/project-structure.mdx b/fern/products/api-def/pages/project-structure.mdx index a79cc521..ad2c09bd 100644 --- a/fern/products/api-def/pages/project-structure.mdx +++ b/fern/products/api-def/pages/project-structure.mdx @@ -1,13 +1,11 @@ --- -title: Project structure +title: The Fern Folder description: Describes the Fern folder structure --- -Configuring fern starts with the `fern` folder, which contains your API definitions, +Configuring fern starts with the `fern` folder. The fern folder contains your API definitions, SDK generators, and your CLI version. -Fern recommends a multi-repository structure with your fern folder in a source repository (containing your API definitions and generation configuration) and [each generated SDK in its own separate repository](/sdks/overview/project-structure). - ## Directory structure When you run `fern init` (for the Fern Definition) or `fern init --spec-type path/to/spec` (for other specs), your fern folder is initialized with the following files: @@ -17,19 +15,22 @@ fern/ ├─ fern.config.json # Root-level config for entire Fern project ├─ generators.yml # Defines SDKs and docs to generate └─ spec-folder/ # definition, openapi, asyncapi, etc. - └─ spec-file.yml # API definition file + └─ spec-file.yml # API specification file ``` - - Beyond the core files, you can optionally use an overrides file to customize your API definition without modifying the original spec. See [Overrides](/api-definitions/overview/overrides) for instructions. - + + For Fern Definition, your API configuration is split across two files: `api.yml` for API-wide configuration and separate `.yml` files for your actual endpoint and type definitions. See [What is a Fern Definition?](/api-definitions/ferndef/overview) for more information. + + For the other specification formats ([OpenAPI](/api-definitions/openapi/overview), [AsyncAPI](/api-definitions/asyncapi/overview), [OpenRPC](/api-definitions/openrpc/overview), and [gRPC](/api-definitions/grpc/overview)), you'll have a single self-contained specification file. + -### `fern.config.json file` + + Every fern folder has a single `fern.config.json` file. This file stores the organization and the version of the Fern CLI that you are using. -```json title="fern.config.json" +```json { "organization": "your-organization", "version": "0.31.2" @@ -38,29 +39,35 @@ the version of the Fern CLI that you are using. Every time you run a fern CLI command, the CLI downloads itself at the correct version to ensure determinism. + + -### `generators.yml` +The `generators.yml` file includes information about where your API definition file is located. It also configures the SDKs you're generating for your API. -The `generators.yml` file includes information about where your API definition file is located. It also [configures the SDKs](/sdks/overview/project-structure) you're generating for your API. - -```yaml title="generators.yml" -api: - specs: - - openapi: spec-file.yml +```yaml +api: + path: ./path/to/openapi.yml ``` + + -### API definition file - - For Fern Definition, your API configuration is split across two files: `api.yml` for API-wide configuration and separate `.yml` files for your actual endpoint and type definitions. See [What is a Fern Definition?](/api-definitions/ferndef/overview) for more information. +## Multiple APIs - For the other specification formats ([OpenAPI](/api-definitions/openapi/overview), [AsyncAPI](/api-definitions/asyncapi/overview), [OpenRPC](/api-definitions/openrpc/overview), and [gRPC](/api-definitions/grpc/overview)), you'll have a single self-contained specification file. +The fern folder can house multiple API definitions. When you have multiple APIs, nest your definition files within an `apis` folder. +Each API must also have a separate `generators.yml` file that specifies the location of the API definition and configures SDK generation. -## Multiple API definitions - - - -### Docs configuration - -APIs in docs are specified by [setting the `api-name` property](/docs/api-references/generate-api-ref#include-more-than-one-api-reference). - +```bash +fern/ + ├─ fern.config.json + ├─ generators.yml # Optional: top-level configuration for all APIs + └─ apis/ + └─ first-api/ # First API + ├─ generators.yml # Required: points to API spec + └─ openapi/ + ├─ openapi.yml # API Definition file + └─ second-api/ # Second API + ├─ generators.yml # Required: points to API spec + └─ openapi/ + ├─ openapi.yml # API Definition file +``` diff --git a/fern/products/ask-fern/ask-fern.yml b/fern/products/ask-fern/ask-fern.yml index 42e2acd0..12b71784 100644 --- a/fern/products/ask-fern/ask-fern.yml +++ b/fern/products/ask-fern/ask-fern.yml @@ -1,5 +1,5 @@ navigation: - - section: Getting started + - section: Getting Started contents: - page: What is Ask Fern? path: ./pages/getting-started/what-is-ask-fern.mdx @@ -7,22 +7,17 @@ navigation: href: https://buildwithfern.com/showcase#ask-fern-customers - section: Configuration contents: - - page: Custom prompts + - page: Custom prompting path: ./pages/configuration/custom-prompting.mdx - - page: Guidance - path: ./pages/features/guidance.mdx - - page: Documents - path: ./pages/features/documents.mdx - section: Features contents: - page: Citations path: ./pages/features/citations.mdx - - page: Insights - path: ./pages/features/insights.mdx - - page: Evaluation - path: ./pages/features/evals.mdx - - api: API reference + - page: Custom FAQs + path: ./pages/features/custom-faqs.mdx + - api: API Reference api-name: fai + icon: fa-regular fa-pro paginated: true audiences: - customers diff --git a/fern/products/ask-fern/pages/features/custom-faqs.mdx b/fern/products/ask-fern/pages/features/custom-faqs.mdx new file mode 100644 index 00000000..6a2fd120 --- /dev/null +++ b/fern/products/ask-fern/pages/features/custom-faqs.mdx @@ -0,0 +1,10 @@ +--- +title: Custom FAQs +subtitle: Fine-tune your AI search responses. +--- + + + +You can add custom FAQs to your documentation to "override" Ask Fern's responses to specific user queries. This is useful for content that you may not wish to display publically, such as billing information, legal terms, and other sensitive content. + +Fern offers an internal CMS (content management system) that allows you to add and edit FAQ documents as needed. \ No newline at end of file diff --git a/fern/products/ask-fern/pages/features/documents.mdx b/fern/products/ask-fern/pages/features/documents.mdx deleted file mode 100644 index dd30266d..00000000 --- a/fern/products/ask-fern/pages/features/documents.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Documents -subtitle: Add custom data sources to Ask Fern. ---- - -## Overview - -You can index custom documents beyond your core documentation to improve Ask Fern's capabilities. -Adding content such as help desk tickets, internal company FAQs, and other resources can help provide better answers to developers. - -Fern offers an internal CMS (content management system) via the `documents` API that allows you to add, update, -and delete documents as needed. - -See the [API reference](/learn/ask-fern/api-reference/document/create-document) for more details - -## Usage - -Here's an example of a document that can be uploaded via the `documents` API: - -```json -{ - "document": "Ferns are plants native to the tropical and subtropical regions of the world. They are characterized by their fronds, which are large, leaf-like structures that are often found in the understory of forests.", - "title": "What are ferns?", - "url": "https://en.wikipedia.org/wiki/Fern" -} -``` - -This document will be indexed and made available to Ask Fern as context when users ask questions about ferns. - diff --git a/fern/products/ask-fern/pages/features/evals.mdx b/fern/products/ask-fern/pages/features/evals.mdx deleted file mode 100644 index da241cc3..00000000 --- a/fern/products/ask-fern/pages/features/evals.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Evals -description: Benchmark Ask Fern's accuracy against your documentation. ---- - - - -Fern evaluates how accurately Ask Fern answers questions on your documentation site compared to competitor AI search solutions. - -Fern first generates evaluation questions from your documentation files, then runs those questions through both Ask Fern and competitor systems. -Finally, Fern evaluates each answer against the original documentation for accuracy. You receive detailed performance metrics and comparative analysis. - -## Availability - -Evals are currently provided as custom analysis delivered directly by the Fern team. \ No newline at end of file diff --git a/fern/products/ask-fern/pages/features/guidance.mdx b/fern/products/ask-fern/pages/features/guidance.mdx deleted file mode 100644 index 94352ae0..00000000 --- a/fern/products/ask-fern/pages/features/guidance.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Guidance -subtitle: Fine-tune your Ask Fern responses. ---- - -## Overview - -You can add custom guidance to "override" Ask Fern's responses to specific user queries. This is useful for content that you -may not want to display explicitly in your documentation, such as billing information, legal terms, and other sensitive content. - -Guidance documents consist of a list of `context` texts and a `document` text. The `context` texts will be indexed -to match against user queries. The `document` text will used as a prescribed response to the user query. - -## API - -Fern offers an internal CMS (content management system) via the `guidance` API that allows you to add, -update, and delete guidance as needed. You will need to provide your `domain` to specify which deployment of Ask Fern -the updates will be applied to. - -See the [API reference](/learn/ask-fern/api-reference/guidance/create-guidance) for more details. - -## Usage - -Below is an example of a guidance document that can be uploaded via the `guidance` API: - -```json -{ - "context": [ - "What billing options are available for enterprise customers with 10-50 seats?", - "How do I upgrade the number of seats for my enterprise plan?" - ], - "document": "Please reach out to support@yourcompany.com for more information." -} -``` - -During the retrieval step, when users ask questions that fuzzy-match against any of the `context` texts, the `document` text will be returned -in the tool response and provided to the Agent as context in the form: - -``` - -In response to the following query: -What billing options are available for enterprise customers with 10-50 seats? - -You will return an answer based on the following guidance: -Please reach out to support@yourcompany.com for more information. - -``` - -Ask Fern prioritizes guidance response over other document responses, allowing you to override the default RAG responses. diff --git a/fern/products/ask-fern/pages/features/insights.mdx b/fern/products/ask-fern/pages/features/insights.mdx deleted file mode 100644 index a1c0049b..00000000 --- a/fern/products/ask-fern/pages/features/insights.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Insights -description: Fern identifies documentation gaps and improvement opportunities from your user queries. ---- - - - -Fern analyzes Ask Fern query patterns to surface actionable recommendations for improving your documentation. After collecting sufficient query data over a month, Fern processes this through specialized models that analyze query-response pairs to identify documentation gaps, extract common themes, and generate specific suggestions for enhancing your docs. - -## Availability - -Insights are currently provided as a monthly report delivered directly by the Fern team. diff --git a/fern/products/ask-fern/pages/getting-started/what-is-ask-fern.mdx b/fern/products/ask-fern/pages/getting-started/what-is-ask-fern.mdx index 0213788c..48044234 100644 --- a/fern/products/ask-fern/pages/getting-started/what-is-ask-fern.mdx +++ b/fern/products/ask-fern/pages/getting-started/what-is-ask-fern.mdx @@ -1,21 +1,19 @@ --- -title: What is Ask Fern? +title: AI Search Overview subtitle: Let your customers find answers in your documentation instantly. --- -Ask Fern is available on the [Pro plan](https://buildwithfern.com/pricing#Docs) of Fern Docs. Billing is by usage. - ## Overview Accessing AI Search -Ask Fern is Fern's AI Search feature that indexes your documentation and provides an interface for your users to ask questions and get answers. It helps our customers +Fern AI Search indexes your documentation and provides an interface for your users to ask questions and get answers. We've found that it helps our customers: -- **Decrease the time to find needed information** – Help users quickly locate crucial documentation without navigating through a maze of tabs and endpoints. -- **Integrate your product faster** – Accelerate implementation with ready-to-use code samples that demonstrate practical applications. -- **Surface where your docs have gaps** – Identify documentation weaknesses through user feedback and search patterns. +- **Decrease the time to find needed information** - Help users quickly locate crucial documentation without navigating through a maze of tabs and endpoints. +- **Integrate your product faster** - Accelerate implementation with ready-to-use code samples that demonstrate practical applications. +- **Surface where your docs have gaps** - Identify documentation weaknesses through user feedback and search patterns. Preview of AI Search @@ -27,41 +25,25 @@ Ask Fern is Fern's AI Search feature that indexes your documentation and provide - Tailor Ask Fern behavior to your users' needs. + Tailor AI Search results to your users' needs. Point users to the exact source of the answer. - - Add custom FAQs to Ask Fern. - - - - Add custom documents to Ask Fern. - - - Users can "Ask AI" or search your docs directly with Algolia. + Offer flexibility to have users 'Ask AI' or search your docs directly with Algolia. - Create seamless UX by offering a one-stop-shop for all API questions. + Create seamless UX by offering a 'one-stop-shop' for all docs questions. -## How it works - -Ask Fern is a **Retrieval Augmented Generation (RAG)** system built on top of your documentation site that transforms your documentation into an intelligent, searchable knowledge base. The main parts of the Ask Fern system are: - -* **Content indexing** – Fern automatically processes your documentation pages, - breaking them into semantic chunks and converting each chunk into a vector - using sentence embedding models. They're stored in a database that serves as - Ask Fern's search index. -* **Query processing** – When users ask questions, Ask Fern vectorizes their - query and searches the database to find the most relevant documentation - chunks. -* **Response generation** – Ask Fern uses the retrieved chunks as context to - generate accurate answers with [citations](/ask-fern/features/citations) for the user. If the initial context isn't sufficient, it performs an additional keyword search. - -### Life of a query - -Each Ask Fern user query follows these steps: +## Pricing -```mermaid -sequenceDiagram - autonumber - participant U as User - participant C as /chat Endpoint - participant V as Documentation Database - participant A as Ask Fern - - U->>C: Submit question via Ask Fern searchbox - C->>C: Convert query to vector - C->>V: Search for relevant chunks - V->>C: Return matching documents - C->>A: Send query + context - A->>V: Perform additional keyword search if needed - V->>A: Return additional chunks - A->>A: Generate response - A->>U: Return answer with citations -``` \ No newline at end of file +Ask Fern is available on the [Pro plan](https://buildwithfern.com/pricing#Docs) of Fern Docs. Billing is by usage. \ No newline at end of file diff --git a/fern/products/cli-api-reference/cli-api-reference.yml b/fern/products/cli-api-reference/cli-api-reference.yml index 20a46c18..a97fe348 100644 --- a/fern/products/cli-api-reference/cli-api-reference.yml +++ b/fern/products/cli-api-reference/cli-api-reference.yml @@ -1,16 +1,16 @@ navigation: - section: CLI Reference contents: - - page: Get started with Fern CLI + - page: Get Started with Fern CLI path: ./pages/cli-get-started.mdx slug: overview - - page: Global options + - page: Global Options path: ./pages/global-options.mdx slug: options - page: Commands path: ./pages/commands.mdx - changelog: ./cli-changelog - - api: API reference + - api: API Reference api-name: public-api icon: fa-regular fa-pro paginated: true diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-09.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-09.mdx index 01736a03..56557ce7 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-09.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-09.mdx @@ -3,12 +3,12 @@ ## 0.57.19 -**`(fix):`** Fix an issue in the OpenAPI parser where array references were not being properly resolved. The parser now correctly resolves references +**`(fix):`** Fix an issue in the OpenAPI parser where array references were not being properly resolved. The parser now correctly resolves references within array schemas, ensuring that arrays of referenced types are properly handled throughout the API definition. ## 0.57.18 -**`(fix):`** Improve the ReadMe migrator to respect the original navigation structure when creating the file hierarchy. Previously, nested navigation groups were +**`(fix):`** Improve the ReadMe migrator to respect the original navigation structure when creating the file hierarchy. Previously, nested navigation groups were flattened, but now the file structure will mirror the navigation hierarchy, preserving the original organization of documentation. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-12.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-12.mdx index 7b99ca42..00bdfa31 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-12.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-12.mdx @@ -1,5 +1,5 @@ ## 0.57.24 -**`(fix):`** Fix an issue in the OpenAPI importer where discriminated unions with literal discriminant values in the variants would render the discriminant property twice. +**`(fix):`** Fix an issue in the OpenAPI importer where discriminated unions with literal discriminant values in the variants would render the discriminant property twice. The importer now correctly checks if union variants contain the discriminant property as a literal value and handles them appropriately. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-21.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-21.mdx index 71427451..04c2da0a 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-21.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-21.mdx @@ -6,13 +6,13 @@ Single element type arrays will resolve to the single element in the example. ## 0.57.33 -**`(feat):`** Improve OpenRPC response example generation by wrapping example payloads in JSON-RPC 2.0 format with metadata +**`(feat):`** Improve OpenRPC response example generation by wrapping example payloads in JSON-RPC 2.0 format with metadata (jsonrpc version and request id). This ensures generated examples match the actual JSON-RPC response format. ## 0.57.32 -**`(feat):`** Improve server handling in OpenAPI imports by exploding servers with enum variables into multiple servers, -one for each enum value. For example, a server with URL "https://{region}.example.com" where region +**`(feat):`** Improve server handling in OpenAPI imports by exploding servers with enum variables into multiple servers, +one for each enum value. For example, a server with URL "https://{region}.example.com" where region is an enum ["us", "eu"] will be exploded into two servers: "https://us.example.com" and "https://eu.example.com". diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-22.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-22.mdx index 16fe7fc0..a395899c 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-22.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-22.mdx @@ -1,7 +1,7 @@ ## 0.57.35 -**`(feat):`** Improve OpenAPI response handling for 204 status codes by respecting schema definitions. -When a 204 (No Content) response includes a schema, the importer now properly processes -and preserves this schema information, ensuring accurate API documentation and SDK generation +**`(feat):`** Improve OpenAPI response handling for 204 status codes by respecting schema definitions. +When a 204 (No Content) response includes a schema, the importer now properly processes +and preserves this schema information, ensuring accurate API documentation and SDK generation even for endpoints that don't return content in successful responses. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-24.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-24.mdx index 0bda5e8f..3c7f3cf5 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-24.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-24.mdx @@ -8,8 +8,8 @@ multiple API Definitions that have overlapping schema names or operation names. ## 0.57.37 -**`(feat):`** Improve OpenRPC request example generation by not wrapping request payloads in JSON-RPC 2.0 format. -This ensures generated request examples match the expected format for the API's method parameters +**`(feat):`** Improve OpenRPC request example generation by not wrapping request payloads in JSON-RPC 2.0 format. +This ensures generated request examples match the expected format for the API's method parameters without the additional JSON-RPC envelope. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-26.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-26.mdx index 6eef8417..01bf1d79 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-26.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-26.mdx @@ -1,7 +1,7 @@ ## 0.58.2 -**`(feat):`** Enhance example generation to consider default values when generating examples for primitive types. -When a string primitive type has a default value specified, the example generator now uses this -default value instead of a generic example. This produces more realistic and contextually +**`(feat):`** Enhance example generation to consider default values when generating examples for primitive types. +When a string primitive type has a default value specified, the example generator now uses this +default value instead of a generic example. This produces more realistic and contextually appropriate examples in generated SDKs and documentation. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-27.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-27.mdx index 6f4057af..46c561d1 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-27.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-27.mdx @@ -1,8 +1,8 @@ ## 0.58.3 -**`(feat):`** Enhance OpenAPI security scheme handling in the parser to support both global and endpoint-level security requirements. -The parser now properly converts security schemes from OpenAPI's `securitySchemes` component into appropriate authentication -headers, supporting bearer tokens, basic auth, and custom API key headers. Global security requirements defined at the -document level are applied to all endpoints, while endpoint-specific security requirements override or supplement the +**`(feat):`** Enhance OpenAPI security scheme handling in the parser to support both global and endpoint-level security requirements. +The parser now properly converts security schemes from OpenAPI's `securitySchemes` component into appropriate authentication +headers, supporting bearer tokens, basic auth, and custom API key headers. Global security requirements defined at the +document level are applied to all endpoints, while endpoint-specific security requirements override or supplement the global configuration, ensuring accurate authentication representation in generated SDKs. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-29.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-29.mdx index 244334bd..723199a1 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-29.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-29.mdx @@ -3,7 +3,7 @@ ## 0.59.1 -**`(feat):`** Enhance OpenAPI -> IR parser to better handle inlined oneOf schemas. The parser now uses the schema ID when +**`(feat):`** Enhance OpenAPI -> IR parser to better handle inlined oneOf schemas. The parser now uses the schema ID when generating names for oneOf variants, resulting in more predictable and consistent type names in the generated SDKs. @@ -13,8 +13,8 @@ This command is in-development; changes are expected. ## 0.58.6 -**`(feat):`** Add support for schema conversion in OpenRPC importer. The importer now properly converts schemas defined in the -OpenRPC document's components section into Fern types, enabling full type definitions for request and response +**`(feat):`** Add support for schema conversion in OpenRPC importer. The importer now properly converts schemas defined in the +OpenRPC document's components section into Fern types, enabling full type definitions for request and response objects. This enhancement allows for more complete and accurate SDK generation from OpenRPC specifications. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-04-30.mdx b/fern/products/cli-api-reference/cli-changelog/2025-04-30.mdx index 8d82887c..53dc1183 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-04-30.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-04-30.mdx @@ -1,12 +1,12 @@ ## 0.59.4 -**`(fix):`** Enhance OpenAPI -> IR conversion to properly handle default values in schemas. The converter now correctly extracts -and preserves default values from OpenAPI schemas, ensuring they are properly represented in the generated SDKs. +**`(fix):`** Enhance OpenAPI -> IR conversion to properly handle default values in schemas. The converter now correctly extracts +and preserves default values from OpenAPI schemas, ensuring they are properly represented in the generated SDKs. This improvement allows API providers to specify meaningful defaults that will be respected in client implementations. ## 0.59.3 -**`(fix):`** Improve OpenRPC importer to generate more unique schema IDs for request parameters by combining method name, -"Param" keyword, and parameter name. This prevents naming conflicts when different methods have parameters +**`(fix):`** Improve OpenRPC importer to generate more unique schema IDs for request parameters by combining method name, +"Param" keyword, and parameter name. This prevents naming conflicts when different methods have parameters with the same name, resulting in more reliable and consistent type generation in the SDKs. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-01.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-01.mdx index 5274cf97..c4f8dd2f 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-01.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-01.mdx @@ -16,9 +16,9 @@ parameters are properly handled during example generation, resulting in cleaner ## 0.59.6 -**`(fix):`** Add support for local SDK generation with a Fern token. When a valid Fern token is provided, -users can now generate complete SDKs locally using Docker, without requiring remote generation. -This enhancement improves the development workflow by allowing for faster iteration and testing +**`(fix):`** Add support for local SDK generation with a Fern token. When a valid Fern token is provided, +users can now generate complete SDKs locally using Docker, without requiring remote generation. +This enhancement improves the development workflow by allowing for faster iteration and testing of SDK changes in local environments. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-02.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-02.mdx index dc0cc5e0..b8a10fb9 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-02.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-02.mdx @@ -1,6 +1,6 @@ ## 0.60.7 -**`(feat):`** Add support for auth descriptions in generated documentation. Auth schemes can now include descriptive text that explains authentication requirements, -which is properly displayed in the generated documentation. This enhancement improves API usability by providing clearer guidance on authentication +**`(feat):`** Add support for auth descriptions in generated documentation. Auth schemes can now include descriptive text that explains authentication requirements, +which is properly displayed in the generated documentation. This enhancement improves API usability by providing clearer guidance on authentication methods directly within the documentation. @@ -13,9 +13,9 @@ methods directly within the documentation. ## 0.60.4 -**`(feat):`** Add support for custom parameters in OpenRPC through the `x-fern-parameters` extension. This extension allows OpenRPC -definitions to specify path parameters, query parameters, and headers that aren't natively supported in the OpenRPC -specification. Parameters defined with this extension are properly converted to the Fern IR format and included in +**`(feat):`** Add support for custom parameters in OpenRPC through the `x-fern-parameters` extension. This extension allows OpenRPC +definitions to specify path parameters, query parameters, and headers that aren't natively supported in the OpenRPC +specification. Parameters defined with this extension are properly converted to the Fern IR format and included in endpoint definitions, enabling more complete API representations when importing from OpenRPC sources. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-03.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-03.mdx index a941841d..d6b34806 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-03.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-03.mdx @@ -1,8 +1,8 @@ ## 0.60.8 -**`(feat):`** Add support for environment and auth overrides from generators.yml in the OpenAPI parser. When importing OpenAPI specifications, -the parser now checks for environment and auth configurations in the generators.yml file and uses these settings to override -the environments and authentication schemes defined in the OpenAPI document. This enhancement provides more flexibility in -customizing imported APIs without modifying the original OpenAPI specification, allowing for environment-specific configurations +**`(feat):`** Add support for environment and auth overrides from generators.yml in the OpenAPI parser. When importing OpenAPI specifications, +the parser now checks for environment and auth configurations in the generators.yml file and uses these settings to override +the environments and authentication schemes defined in the OpenAPI document. This enhancement provides more flexibility in +customizing imported APIs without modifying the original OpenAPI specification, allowing for environment-specific configurations and standardized authentication schemes across different API versions. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-09.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-09.mdx index 5192b78b..0b4c6194 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-09.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-09.mdx @@ -3,12 +3,12 @@ ## 0.60.28 -**`(fix):`** Fixed an issue where local generation could produce invalid build files (like pyproject.toml) when +**`(fix):`** Fixed an issue where local generation could produce invalid build files (like pyproject.toml) when GitHub configuration was missing a repository URL. The CLI now ensures a repository URL is always set when possible. ## 0.60.27 -**`(fix):`** Added support for using Podman as a container runner with `fern generate --runner podman`. +**`(fix):`** Added support for using Podman as a container runner with `fern generate --runner podman`. This allows users to run generators locally using Podman instead of Docker. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-14.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-14.mdx index b232e826..730008f9 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-14.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-14.mdx @@ -7,7 +7,7 @@ ## 0.61.8 -**`(fix):`** Fix a bug where the broken link checker would incorrectly flag links to llms.txt and llms-full.txt files as broken. +**`(fix):`** Fix a bug where the broken link checker would incorrectly flag links to llms.txt and llms-full.txt files as broken. The checker now properly recognizes these file paths as valid. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-15.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-15.mdx index be846bee..933caf2e 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-15.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-15.mdx @@ -1,5 +1,5 @@ ## 0.61.16 -**`(fix):`** Fix docs preview server by properly killing the Next.js process on exit and setting +**`(fix):`** Fix docs preview server by properly killing the Next.js process on exit and setting a memory limit (--max-old-space-size=2048) to prevent out-of-memory errors during development. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-16.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-16.mdx index 9c23bc2f..df9783b6 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-16.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-16.mdx @@ -4,14 +4,14 @@ AsyncAPI endpoints now have the correct associated path parameters. ## 0.61.18 -**`(fix):`** Fix OpenRPC converter to use proper breadcrumbs when generating request and response schemas. -This ensures that schemas with the same name but different contexts (such as parameters and results) +**`(fix):`** Fix OpenRPC converter to use proper breadcrumbs when generating request and response schemas. +This ensures that schemas with the same name but different contexts (such as parameters and results) don't overwrite each other during conversion, maintaining the integrity of the API definition. ## 0.61.17 -**`(fix):`** Add support for preserving `maxLines` and `focus` attributes when using `` components in docs. -These attributes are now properly carried over to the generated code blocks, allowing you to control +**`(fix):`** Add support for preserving `maxLines` and `focus` attributes when using `` components in docs. +These attributes are now properly carried over to the generated code blocks, allowing you to control the display of referenced code snippets with features like line limits and syntax highlighting focus. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-17.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-17.mdx index 84f691d6..34267b11 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-17.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-17.mdx @@ -1,6 +1,6 @@ ## 0.61.20 -**`(fix):`** Add logging of filepaths when markdown parsing fails to help with debugging. This includes logging the -absolute filepath of the markdown file being parsed and any associated image paths that were +**`(fix):`** Add logging of filepaths when markdown parsing fails to help with debugging. This includes logging the +absolute filepath of the markdown file being parsed and any associated image paths that were being processed when the error occurred. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-05-21.mdx b/fern/products/cli-api-reference/cli-changelog/2025-05-21.mdx index bc72f3f9..b1ca9b13 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-05-21.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-05-21.mdx @@ -4,7 +4,7 @@ ```yaml - name: fernapi/fern-typescript-sdk version: 0.48.5 - api: + api: auth: bearer ``` @@ -20,7 +20,7 @@ This will override the auth configuration for that specific generator while keep ## 0.62.7 -**`(fix):`** Remove `respect-readonly-schemas` for the legacy OpenAPI parser since it can block docs +**`(fix):`** Remove `respect-readonly-schemas` for the legacy OpenAPI parser since it can block docs generation. Anyone who wants to enable this can turn it on in `generators.yml` or upgrade to the latest OpenAPI parser. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-03.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-03.mdx index 02657de9..065be8db 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-03.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-03.mdx @@ -1,5 +1,5 @@ ## 0.63.29 -**`(fix):`** The v3 OpenAPI parser now appropriately creates inlined types for references to +**`(fix):`** The v3 OpenAPI parser now appropriately creates inlined types for references to inlined schemas like `$ref: /components/schemas/MySchema/properties/foo` diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-11.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-11.mdx index a667187c..e09fbc61 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-11.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-11.mdx @@ -3,22 +3,22 @@ ## 0.64.3 -**`(fix):`** The OpenAPI v3 Parser now uniquely stores schemas across endpoint parameters to prevent overwriting. Previously, -schemas with the same name across different parameters would overwrite each other, leading to potential data loss -and incorrect type definitions. This fix ensures that each parameter's schema is properly preserved and referenced +**`(fix):`** The OpenAPI v3 Parser now uniquely stores schemas across endpoint parameters to prevent overwriting. Previously, +schemas with the same name across different parameters would overwrite each other, leading to potential data loss +and incorrect type definitions. This fix ensures that each parameter's schema is properly preserved and referenced throughout the API specification. ## 0.64.2 -**`(fix):`** The AsyncAPI v3 importer now properly detects query parameters by analyzing the channel address specification. -When a channel address contains a parameter reference in the format `={paramName}`, the importer will automatically -identify it as a query parameter. This allows for more accurate parameter type detection and better handling of +**`(fix):`** The AsyncAPI v3 importer now properly detects query parameters by analyzing the channel address specification. +When a channel address contains a parameter reference in the format `={paramName}`, the importer will automatically +identify it as a query parameter. This allows for more accurate parameter type detection and better handling of WebSocket channel parameters in AsyncAPI v3 specifications. ## 0.64.1 -**`(fix):`** The AsyncAPI importer now supports parameter references and computing location of the parameter based on the address. -This allows for more flexible parameter definitions in AsyncAPI specifications, where parameters can be referenced from other +**`(fix):`** The AsyncAPI importer now supports parameter references and computing location of the parameter based on the address. +This allows for more flexible parameter definitions in AsyncAPI specifications, where parameters can be referenced from other parts of the specification and their location can be dynamically determined based on the channel address. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-12.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-12.mdx index d7094a04..bee17df4 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-12.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-12.mdx @@ -3,12 +3,12 @@ ## 0.64.6 -**`(fix):`** The Readme importer now downloads MDX files from the source documentation. -This allows for better handling of React components and dynamic content in the imported documentation. +**`(fix):`** The Readme importer now downloads MDX files from the source documentation. +This allows for better handling of React components and dynamic content in the imported documentation. The importer will preserve the MDX syntax and structure while converting the content to a format compatible with Fern's documentation system. ## 0.64.5 -**`(fix):`** Relative links between markdown files now works for docs using custom subpaths. +**`(fix):`** Relative links between markdown files now works for docs using custom subpaths. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-19.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-19.mdx index c9170a00..4a14ead8 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-19.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-19.mdx @@ -3,7 +3,7 @@ ## 0.64.13 -**`(fix):`** Respect additional properties in docs example generation by preserving them in generated examples instead of +**`(fix):`** Respect additional properties in docs example generation by preserving them in generated examples instead of stripping unknown properties. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-25.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-25.mdx index ce8812fa..a41340ac 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-25.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-25.mdx @@ -1,6 +1,6 @@ ## 0.64.23 -**`(fix):`** Global headers are now used to create endpoint examples. When building endpoint examples, global headers -are automatically included in the headers section of each example. This ensures that all endpoints have consistent +**`(fix):`** Global headers are now used to create endpoint examples. When building endpoint examples, global headers +are automatically included in the headers section of each example. This ensures that all endpoints have consistent header examples that match the global header configuration. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-06-27.mdx b/fern/products/cli-api-reference/cli-changelog/2025-06-27.mdx index f2da4835..e5043e2f 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-06-27.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-06-27.mdx @@ -3,8 +3,8 @@ ## 0.64.24 -**`(feat):`** Added Server-Sent Events (SSE) support to Java stream implementation. The Java SDK generator now -supports SSE streaming alongside existing JSON streaming, enabling real-time incremental responses +**`(feat):`** Added Server-Sent Events (SSE) support to Java stream implementation. The Java SDK generator now +supports SSE streaming alongside existing JSON streaming, enabling real-time incremental responses for chat applications and live data feeds. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-07-08.mdx b/fern/products/cli-api-reference/cli-changelog/2025-07-08.mdx index 9d4c3238..1084d2c1 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-07-08.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-07-08.mdx @@ -1,6 +1,6 @@ ## 0.65.4 **`(fix):`** Previously if the OpenAPI parser v3 was enabled where the CLI would skip parsing any additional Fern Definitions -along the OpenAPI spec. With the fix, you can use whatever combination of OpenAPI Spec(s) and Fern Definitions that +along the OpenAPI spec. With the fix, you can use whatever combination of OpenAPI Spec(s) and Fern Definitions that you would like. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-07-12.mdx b/fern/products/cli-api-reference/cli-changelog/2025-07-12.mdx index 6d21574a..9566cd63 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-07-12.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-07-12.mdx @@ -1,6 +1,6 @@ ## 0.65.11 -**`(feat):`** The extension `x-fern-global-headers` now supports a type field that can point to -arbitrary schemas. For example you can do the following to describe a header +**`(feat):`** The extension `x-fern-global-headers` now supports a type field that can point to +arbitrary schemas. For example you can do the following to describe a header that is an enum. ```yml diff --git a/fern/products/cli-api-reference/cli-changelog/2025-07-23.mdx b/fern/products/cli-api-reference/cli-changelog/2025-07-23.mdx index 9a820d63..bf6eda0a 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-07-23.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-07-23.mdx @@ -3,7 +3,7 @@ ## 0.65.28 -**`(feat):`** endpoint example creation ignores global auth headers +**`(feat):`** endpoint example creation ignores global auth headers ## 0.65.27 diff --git a/fern/products/cli-api-reference/cli-changelog/2025-07-30.mdx b/fern/products/cli-api-reference/cli-changelog/2025-07-30.mdx index d5951432..a4d813ae 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-07-30.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-07-30.mdx @@ -3,13 +3,13 @@ ## 0.65.37 -**`(feat):`** Add support for snippet.json output as part of self hosted SDK generation. The following config in -`generators.yml` will generate a `snippet.json` file in the relevant director: +**`(feat):`** Add support for snippet.json output as part of self hosted SDK generation. The following config in +`generators.yml` will generate a `snippet.json` file in the relevant director: ``` -groups: - ts-sdk: +groups: + ts-sdk: - name: fernapi/fern-typescript-sdk - snippets: + snippets: path: ../snippets.json ``` diff --git a/fern/products/cli-api-reference/cli-changelog/2025-07-31.mdx b/fern/products/cli-api-reference/cli-changelog/2025-07-31.mdx index 5748b6e4..0774de60 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-07-31.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-07-31.mdx @@ -7,8 +7,8 @@ ## 0.65.39 -**`(fix):`** Fix snippet generation for local file system output mode. Snippets configured with `snippets.path` -in generators.yml were not being generated when using `--local` flag due to missing Docker volume +**`(fix):`** Fix snippet generation for local file system output mode. Snippets configured with `snippets.path` +in generators.yml were not being generated when using `--local` flag due to missing Docker volume mounting for the downloadFiles output mode. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-01.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-01.mdx index b0343734..1babc134 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-01.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-08-01.mdx @@ -1,6 +1,6 @@ ## 0.65.44 -**`(feat):`** Escape $ signs when converting from OpenAPI -> Fern Definition (for enums), because the Fern Definition treats -$ sign examples as references. +**`(feat):`** Escape $ signs when converting from OpenAPI -> Fern Definition (for enums), because the Fern Definition treats +$ sign examples as references. ## 0.65.43 @@ -8,6 +8,6 @@ $ sign examples as references. ## 0.65.42 -**`(fix):`** Allows SDK generation to complete even if an example doesn't correctly generate as part of the IR. +**`(fix):`** Allows SDK generation to complete even if an example doesn't correctly generate as part of the IR. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-11.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-11.mdx index f44c1921..d74fb123 100644 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-11.mdx +++ b/fern/products/cli-api-reference/cli-changelog/2025-08-11.mdx @@ -2,7 +2,7 @@ **`(fix):`** Allow 'securityScheme.scheme' to be case-insensitive. ## 0.66.1 -**`(fix):`** Add 'vendor' to set of reserved keywords for go. +**`(fix):`** Add 'vendor' to set of reservved keywords for go. ## 0.66.01 **`(chore):`** Improved plumbing of the --runner arg for local SDK generation. diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-14.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-14.mdx deleted file mode 100644 index d9009552..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-14.mdx +++ /dev/null @@ -1,58 +0,0 @@ -## 0.66.15 -**`(feat):`** Split OpenAPI endpoints with multiple request bodies into multiple endpoints using `x-fern-sdk-method-name`. -For example, take the following OpenAPI spec: -```yml -paths: - /documents/upload: - post: - summary: Upload document metadata (JSON) or document file - operationId: uploadDocument - requestBody: - content: - application/json: - x-fern-sdk-method-name: uploadJsonDocument - schema: - type: object - properties: - title: - type: string - author: - type: string - tags: - type: array - items: - type: string - application/pdf: - x-fern-sdk-method-name: uploadPdfDocument - schema: - type: string - format: binary -``` - -The OpenAPI spec becomes the following Fern Definition: - -```yml -service: - endpoints: - uploadJsonDocument: - method: POST - path: /documents/upload - request: - body: - properties: - author: optional - tags: optional> - title: optional - content-type: application/json - name: UploadDocumentRequest - ... - uploadPdfDocument: - method: POST - path: /documents/upload - request: - body: bytes - content-type: application/pdf - ... -``` - - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-15.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-15.mdx deleted file mode 100644 index 40cf6eca..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-15.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 0.66.16 -**`(feat):`** Upload generator configuration with dynamic IR for SDK snippets in docs. - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-16.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-16.mdx deleted file mode 100644 index 00a21303..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-16.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 0.66.17 -**`(chore):`** Support IR v59 in the Swift SDK generator. - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-18.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-18.mdx deleted file mode 100644 index 2d9ca92b..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-18.mdx +++ /dev/null @@ -1,26 +0,0 @@ -## 0.66.21 -**`(feat):`** Introduce an OpenAPI setting called `inline-all-of-schemas` which recursively -visits the scheme definitions of allOf schemas and inlines them into the child. - -The benefit of doing this is that a child schema can modify whether or not a parent -property is required. Without this setting, Fern would ignore the child schema's -declaration of optional and prefer the parent schema's instead. - -Add the following to your `generators.yml`: - -```yml generators.yml -api: - settings: - inline-all-of-schemas: true -``` - - -## 0.66.20 -**`(fix):`** Add `kwargs` as a reserved word in python so that generated SDKs continue to compile. - -## 0.66.19 -**`(chore):`** Handle multipart/mixed content types in endpoint responses. - -## 0.66.18 -**`(chore):`** Updated allOf scheme parsing to grab additionalProperties flag - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-22.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-22.mdx deleted file mode 100644 index 49da7efa..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-22.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 0.66.23 -**`(feat):`** Add support for `const` JSON schema keyword, which parses to a single-valued enum. - -## 0.66.22 -**`(fix):`** Nested protobuf types have correct type ids in converted ir. - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-25.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-25.mdx deleted file mode 100644 index d19c16be..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-25.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 0.66.25 -**`(chore):`** Handle object-style examples in OpenAPI spec - -## 0.66.24 -**`(feat):`** Add support for readme config for API Name and disabled features list. - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-26.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-26.mdx deleted file mode 100644 index b9956b6a..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-26.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 0.66.27 -**`(fix):`** Fix readmeConfig.disabledSections type - change from set to list. - -## 0.66.26 -**`(chore):`** Add whiteLabel setting to FernIr.ReadmeConfig based on org properties - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-27.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-27.mdx deleted file mode 100644 index 65dd7e5d..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-27.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 0.66.29 -**`(fix):`** Update docs workspace validator to skip file type validation when running in selfhosted mode - -## 0.66.28 -**`(fix):`** Fix downloadFiles mode to respect organization's selfHostedSdKs flag for Java SDK generation - diff --git a/fern/products/cli-api-reference/cli-changelog/2025-08-29.mdx b/fern/products/cli-api-reference/cli-changelog/2025-08-29.mdx deleted file mode 100644 index 1e68a572..00000000 --- a/fern/products/cli-api-reference/cli-changelog/2025-08-29.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.66.30-rc0 -**`(feat):`** Alpha testing: add support for HTTP proxies - - diff --git a/fern/products/cli-api-reference/pages/commands.mdx b/fern/products/cli-api-reference/pages/commands.mdx index e5dea38d..8f3a0e81 100644 --- a/fern/products/cli-api-reference/pages/commands.mdx +++ b/fern/products/cli-api-reference/pages/commands.mdx @@ -364,7 +364,7 @@ hideOnThisPage: true run: fern generate --docs ``` - See [the full example on GitHub](https://github.com/fern-api/docs/blob/main/.github/workflows/publish-docs.yml). + See [the full example on GitHub](https://github.com/fern-api/fern/blob/main/.github/workflows/publish-docs.yml). diff --git a/fern/products/docs/docs.yml b/fern/products/docs/docs.yml index 04727d2d..f5955e11 100644 --- a/fern/products/docs/docs.yml +++ b/fern/products/docs/docs.yml @@ -1,33 +1,20 @@ navigation: - - section: Getting started + - section: Getting Started contents: - page: Overview path: ./pages/getting-started/overview.mdx - page: Quickstart path: ./pages/getting-started/quickstart.mdx - - page: Project structure + - page: Project Structure path: ./pages/getting-started/project-structure.mdx - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#docs-customers.alldocs-features - changelog: ./pages/changelog icon: fa-regular fa-clock-rotate-left - - section: Configuration - contents: - - page: What is docs.yml? - path: ./pages/customization/what-is-docs-yml.mdx - - page: Navigation - path: ./pages/navigation/overview.mdx - - page: Versions - path: ./pages/navigation/versions.mdx - - page: Products - path: ./pages/navigation/products.mdx - - page: Page-level settings - path: ./pages/customization/frontmatter.mdx - - section: Writing content + - section: Writing Content contents: - - page: Markdown pages + - page: Markdown path: ./pages/component-library/writing-content/markdown.mdx - slug: markdown - section: Components contents: - page: Overview @@ -84,9 +71,6 @@ navigation: - page: Steps path: ./pages/component-library/default-components/steps.mdx icon: fa-duotone fa-list-ol - - page: Sticky tables - path: ./pages/component-library/default-components/sticky-tables.mdx - icon: fa-duotone fa-table - page: Tabs path: ./pages/component-library/default-components/tabs.mdx icon: fa-duotone fa-folder-open @@ -95,22 +79,26 @@ navigation: icon: fa-duotone fa-comment - page: Visual Editor path: ./pages/component-library/writing-content/visual-editor.mdx - - page: Reusable snippets + - page: Reusable Markdown path: ./pages/component-library/custom-components/reusable-markdown.mdx - slug: reusable-markdown - - page: Custom React components + - page: Custom React Components path: ./pages/component-library/custom-components/custom-react-components.mdx - - page: Conditionally rendered content + - page: Conditionally Rendered Content hidden: true path: ./pages/component-library/custom-components/conditional-rendering.mdx - - section: AI features + - section: Configuration contents: - - link: Ask Fern - href: /learn/ask-fern/getting-started/what-is-ask-fern - - page: MCP server for your site - path: ./pages/ai/mcp-server.mdx - slug: mcp-server - - section: Preview & publish + - page: What is docs.yml + path: ./pages/customization/what-is-docs-yml.mdx + - page: Navigation + path: ./pages/navigation/overview.mdx + - page: Versions + path: ./pages/navigation/versions.mdx + - page: Products + path: ./pages/navigation/products.mdx + - page: Page-level settings + path: ./pages/customization/frontmatter.mdx + - section: Preview & Publish collapsed: true contents: - page: Previewing changes locally @@ -124,61 +112,58 @@ navigation: - section: Customization collapsed: true contents: - - page: Announcement banner + - page: Announcement Banner path: ./pages/navigation/announcement-banner.mdx - page: Changelogs path: ./pages/navigation/changelogs.mdx - - page: Hiding content + - page: Hiding Content path: ./pages/navigation/hiding-content.mdx - page: Search path: ./pages/customization/search.mdx - - page: User feedback + - page: User Feedback path: ./pages/customization/user-feedback.mdx - page: Custom CSS & JS path: ./pages/component-library/custom-components/custom-css-js.mdx - - section: API references + - section: API References collapsed: true contents: - - page: Generate API reference + - page: Generate API Reference path: ./pages/api-references/generate-api-ref.mdx slug: generate-api-ref - - page: SDK snippets + - page: SDK Snippets path: ./pages/api-references/sdk-snippets.mdx - - page: HTTP snippets + - page: HTTP Snippets path: ./pages/api-references/http-snippets.mdx - section: API Explorer slug: api-explorer contents: - page: Overview path: ./pages/api-references/api-explorer.mdx - - page: Auto-populate API keys + - page: Auto-populate API Keys path: ./pages/api-references/autopopulate-api-key.mdx - - page: Endpoint errors + - page: Endpoint Errors path: ./pages/api-references/endpoint-errors.mdx - page: Audiences path: ./pages/api-references/audiences.mdx - - page: Customize API reference layout + - page: Customize API Reference Layout path: ./pages/api-references/customize-api-ref.mdx - - page: Write Markdown in API reference + - page: Write Markdown in API Reference path: ./pages/api-references/api-ref-content.mdx - - page: Generate Webhook reference + - page: Generate Webhook Reference path: ./pages/api-references/generate-webhook-ref.mdx - - page: Multiple server URLs + - page: Multiple Server URLs path: ./pages/api-references/server-urls.mdx slug: server-urls - - page: Generate WebSocket reference + - page: Generate WebSocket Reference path: ./pages/api-references/generate-websocket-ref.mdx slug: generate-websocket-ref - - page: Generate OpenRPC reference + - page: Generate OpenRPC Reference path: ./pages/api-references/generate-openrpc-ref.mdx slug: generate-openrpc-ref - - section: SEO & GEO - slug: seo + - section: SEO collapsed: true contents: - - page: Setting SEO metadata - path: ./pages/seo/metadata.mdx - - page: Configuring slugs + - page: Configuring Slugs path: ./pages/seo/configuring-slugs.mdx - page: Redirects path: ./pages/seo/redirects.mdx @@ -192,11 +177,11 @@ navigation: - page: Role based access control (RBAC) path: ./pages/authentication/rbac.mdx slug: rbac - - page: API key injection + - page: API Key Injection path: ./pages/api-references/autopopulate-api-key.mdx - page: SSO path: ./pages/authentication/sso.mdx - - section: Self-hosted + - section: Self-Hosted collapsed: true contents: - page: Overview @@ -229,9 +214,9 @@ navigation: path: ./pages/integrations/support/intercom.mdx - page: Postman path: ./pages/integrations/postman.mdx - - page: LaunchDarkly feature flags + - page: LaunchDarkly Feature Flags path: ./pages/integrations/feature-flags.mdx - - section: Developer tools + - section: Developer Tools collapsed: true contents: - page: Cursor diff --git a/fern/products/docs/pages/ai/mcp-server.mdx b/fern/products/docs/pages/ai/mcp-server.mdx deleted file mode 100644 index e3d6e32e..00000000 --- a/fern/products/docs/pages/ai/mcp-server.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: MCP server for your site -description: Learn how to use the Model Context Protocol (MCP) to integrate AI capabilities with your Fern documentation ---- - - - -[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard by Anthropic that enables AI applications to connect with external data sources and tools. - -Fern can build a production-ready MCP server for your documentation site. This enables developers using AI clients (like Claude Desktop, Cursor, and Windsurf) to get instant answers about your product directly within their development environment. - -## How it works - -Fern analyzes your docs site structure and content, then creates an MCP server. - -Developers can access your MCP server by visiting `your-documentation-site.com/mcp` and copying the configuration snippet to add to their AI client settings. Once integrated, developers can ask their AI client questions about your products. The AI client will search through your documentation and provide accurate answers. \ No newline at end of file diff --git a/fern/products/docs/pages/api-references/audiences.mdx b/fern/products/docs/pages/api-references/audiences.mdx index 19bc1732..5d1140a4 100644 --- a/fern/products/docs/pages/api-references/audiences.mdx +++ b/fern/products/docs/pages/api-references/audiences.mdx @@ -4,7 +4,7 @@ subtitle: Use audiences to filter the endpoints, schemas, and properties that ar --- Audiences are a useful tool for segmenting your API for different consumers. Common examples of audiences include `public` -and `beta`. You can configure audiences in both [the OpenAPI Specification](/learn/api-definitions/openapi/extensions/audiences) as well as [the Fern Definition](/learn/api-definition/fern/audiences). +and `beta`. You can configure audiences in both [the OpenAPI Specification](/learn/api-definition/openapi/audiences) as well as [the Fern Definition](/learn/api-definition/fern/audiences). Once you've added audiences to your API Specification, you can filter to that audience by adding the `audience` property to the `api` object in your `docs.yml` navigation. diff --git a/fern/products/docs/pages/api-references/customize-api-ref.mdx b/fern/products/docs/pages/api-references/customize-api-ref.mdx index 60c652f9..c3ff98a9 100644 --- a/fern/products/docs/pages/api-references/customize-api-ref.mdx +++ b/fern/products/docs/pages/api-references/customize-api-ref.mdx @@ -9,7 +9,7 @@ When you [include an API in your `docs.yml` file](/learn/docs/api-references/gen If you are using an OpenAPI Specification, sections are created based on the `tags` property, converted to `lowerCamelCase` convention (e.g., createUser). If you are using a Fern Definition, sections are created based on the [`service`](/learn/api-definition/fern/endpoints#service-definition) file names. -If you would like to only display a subset of endpoints, read more about the Audiences property for [OpenAPI Specifications](/learn/api-definitions/openapi/extensions/audiences) or [Fern Definitions](/learn/api-definition/fern/audiences). +If you would like to only display a subset of endpoints, read more about the Audiences property for [OpenAPI Specifications](/learn/api-definition/openapi/audiences) or [Fern Definitions](/learn/api-definition/fern/audiences). ## Ordering the API Reference diff --git a/fern/products/docs/pages/api-references/generate-api-ref.mdx b/fern/products/docs/pages/api-references/generate-api-ref.mdx index b14c1caa..d0d1b995 100644 --- a/fern/products/docs/pages/api-references/generate-api-ref.mdx +++ b/fern/products/docs/pages/api-references/generate-api-ref.mdx @@ -35,50 +35,14 @@ navigation: More on customizing your API Reference [here](/learn/docs/api-references/customize-api-reference-layout). ### Include more than one API Reference - To include multiple, distinct API definitions in your documentation, you can indicate which to include using the `api-name` property. The `api-name` corresponds to the name of the folder where your API definition is housed. -For example, your file structure might look like this: - -```bash -fern/ - ├─ fern.config.json - ├─ docs.yml - ├─ plant-api/ - │ └─ api.yml # API definition - └─ garden-api/ - └─ api.yml # API definition -``` - -For a simple setup without tabs, you can include multiple API references directly in your navigation: - ```yaml title="docs.yml" navigation: - api: Plant Store - api-name: plant-api # Matches folder name containing your API definition + api-name: plant-api - api: Garden - api-name: garden-api # Matches folder name containing your API definition + api-name: garden-api ``` -When using tabs, each API reference must be placed within a tab's `layout`: -```yaml title="docs.yml" {12, 17} -tabs: - plant-api: - display-name: Plant Store API - icon: leaf - garden-api: - display-name: Garden API - icon: tree -navigation: - - tab: plant-api # References the tab defined above - layout: - - api: Plant Store API - api-name: plant-api # Matches folder name containing your API definition - skip-slug: true - - tab: garden-api # References the tab defined above - layout: - - api: Garden API - api-name: garden-api # Matches folder name containing your API definition - skip-slug: true -``` diff --git a/fern/products/docs/pages/api-references/generate-webhook-ref.mdx b/fern/products/docs/pages/api-references/generate-webhook-ref.mdx index 43798975..6e8021cd 100644 --- a/fern/products/docs/pages/api-references/generate-webhook-ref.mdx +++ b/fern/products/docs/pages/api-references/generate-webhook-ref.mdx @@ -55,7 +55,7 @@ api: path: openapi/openapi.yml ``` -You can read more about how to define webhooks in your OpenAPI specification [here](/learn/api-definitions/openapi/endpoints/webhooks). +You can read more about how to define webhooks in your OpenAPI specification [here](/learn/api-definition/openapi/webhooks). ```bash @@ -98,16 +98,3 @@ fern/ │ └── openapi.yml # Order webhook OpenAPI spec └── generators.yml ``` - -### Create individual documentation pages for each webhook event (OpenAPI) - -To display each webhook event as an individual page with rich examples, you need to define `tags` and `example` [in your webhook specification](/api-definitions/openapi/endpoints/webhooks) (or [overrides file](/api-definitions/overview/overrides)). - -Then, reference individual webhook pages using the `subpackage_{tag}.{webhook-event-name}` format, where: -- `{tag}` is the first tag (lowercase) from your webhook definition -- `{webhook-event-name}` is the `operationId` from your webhook definition - -```yaml title="docs.yml" -navigation: - - subpackage_plants.newPlantWebhook -``` diff --git a/fern/products/docs/pages/api-references/generate-websocket-ref.mdx b/fern/products/docs/pages/api-references/generate-websocket-ref.mdx index 5d446e66..2afccd1a 100644 --- a/fern/products/docs/pages/api-references/generate-websocket-ref.mdx +++ b/fern/products/docs/pages/api-references/generate-websocket-ref.mdx @@ -5,6 +5,8 @@ description: Learn how to generate and customize WebSocket API reference documen Fern generates WebSocket API reference documentation from your AsyncAPI specification or Fern Definition. The AsyncAPI specification describes message-driven APIs in a machine-readable format. Fern supports the [v2](https://www.asyncapi.com/docs/reference/specification/v2.x) and [v3](https://www.asyncapi.com/docs/reference/specification/v3.0.0) specifications. +See [Deepgram's configuration](https://github.com/deepgram/deepgram-fern-config/blob/9a3d281d87963165df7cbb89c4883d5058abaf2e/fern/generators.yml#L5-L7) for a complete example. + Example of how a WebSocket API Reference renders in Fern}> WebSocket API Reference Example diff --git a/fern/products/docs/pages/api-references/sdk-snippets.mdx b/fern/products/docs/pages/api-references/sdk-snippets.mdx index 2803c27f..f0aa1802 100644 --- a/fern/products/docs/pages/api-references/sdk-snippets.mdx +++ b/fern/products/docs/pages/api-references/sdk-snippets.mdx @@ -3,9 +3,7 @@ title: Display SDK snippets description: Enable SDK code examples in TypeScript, Python, Go, and more from the request and response examples documented in your API definition. Once enabled, Fern Docs will automatically populate the snippets within your API Reference. --- -When you use Fern's SDK Generator, you can automatically display SDK code snippets in your API Reference. These snippets appear in a language selector dropdown, with cURL as the default option. - - Fern supports SDK snippets for TypeScript, Python, Ruby, Go, and .NET/C#. +If you use Fern's SDK Generator, you can automatically show SDK code snippets in your API Reference. SDK languages appear in a drop-down. By default, cURL snippets will be displayed to users. ![SDK code snippet selector](https://fern-image-hosting.s3.amazonaws.com/sdk-code-snippets.png) @@ -13,9 +11,7 @@ When you use Fern's SDK Generator, you can automatically display SDK code snippe ## Configuring SDK Snippets -To configure SDK snippets, you'll need to name your SDKs in `generators.yml` and then reference that name in `docs.yml`. - - +To configure SDK snippets, you'll need to name your SDKs in `generators.yml` and then reference that name in `docs.yml`. In the following example, we'll use `your-organization` as the package name because it is a common practice. For example, Stripe calls their npm package `stripe` and Twilio calls their PyPI package `twilio`. ### Add examples to your API definition @@ -24,7 +20,7 @@ In order to generate code snippets, Fern needs to read request examples from you ### Define a package name for your SDK(s) Configure package names in your `generators.yml` file: -* For **Python, TypeScript, Ruby, and .NET/C#**, add `package-name: your-package-name` to the `output` section. +* For **Python/TypeScript/Ruby**, add `package-name: your-package-name` to the `output` section. * For **Go**, add `repository: your-organization/your-repository` to the `github` section. @@ -33,32 +29,26 @@ groups: production: generators: - name: fernapi/fern-python-sdk - version: + version: 2.8.0 output: location: pypi token: ${PYPI_TOKEN} package-name: your-package-name # <--- add this field ... - name: fernapi/fern-typescript-node-sdk - version: + version: 0.20.9 output: location: npm token: ${NPM_TOKEN} package-name: your-package-name # <--- add this field - name: fernapi/fern-ruby-sdk - version: + version: 0.6.3 output: location: rubygems token: ${RUBYGEMS_TOKEN} package-name: your-package-name # <--- add this field - - name: fernapi/fern-csharp-sdk - version: - output: - location: nuget - api-key: ${NUGET_API_KEY} - package-name: your-package-name # <--- add this field - name: fernapi/fern-go-sdk - version: + version: 0.22.0 github: repository: your-organization/your-repository # <--- add this field ... @@ -72,7 +62,7 @@ groups: ### Add the package name to your docs configuration Add the package name for the corresponding SDK to your `docs.yml` file: - * **For Python, TypeScript, Ruby, and .NET/C#**, `your-package-name` must match the `your-package-name` that you configured in your `generators.yml` file. + * **For Python, TypeScript, and Ruby**, `your-package-name` must match the `your-package-name` that you configured in your `generators.yml` file. * **For Go**, use the exact URL where the SDK repository is located, including the `https://github.com/`. @@ -83,21 +73,27 @@ navigation: python: your-package-name # <--- needs to match the naming in generators.yml typescript: your-package-name # <--- needs to match the naming in generators.yml ruby: your-package-name # <--- needs to match the naming in generators.yml - csharp: your-package-name # <--- needs to match the naming in generators.yml go: https://github.com/your-organization/your-repository # <--- needs the https://github.com/ prefix ``` - - To display different package names for SDK users versus documentation users, [use overrides files](/api-definitions/overview/overrides#separate-overrides-for-sdks-and-docs). - - ### Trigger generation As the final step, trigger your docs generation by running `fern generate --docs` locally or in CI/CD (i.e., GitHub Actions). The SDK snippets will now appear via a drop-down! ### Set default snippet language +SDK code snippets support several languages. Our development work is driven by customer requests, so please request support for languages not listed here by [opening an issue](https://github.com/fern-api/fern/issues/new/choose). + +* csharp +* curl +* go +* java +* javascript +* python +* ruby +* typescript + To set the default snippet language, use the `default-language` key at the top indentation level of `docs.yml`. @@ -112,8 +108,6 @@ navigation: ``` - - ## Access via API If you'd like to bring SDK snippets into your own documentation, you can use the [Snippets API](/learn/api-reference/snippets/get). API access requires a [SDK Business plan](https://buildwithfern.com/pricing) or above. diff --git a/fern/products/docs/pages/authentication/sso.mdx b/fern/products/docs/pages/authentication/sso.mdx index 6c362121..97f2c85e 100644 --- a/fern/products/docs/pages/authentication/sso.mdx +++ b/fern/products/docs/pages/authentication/sso.mdx @@ -12,7 +12,7 @@ Fern’s Single Sign-On (SSO) is an enterprise feature that lets your team secur When SSO is enabled for your organization, authenticated users of Fern can: - **Use the Visual Editor**: Make edits to your docs from the browser -- **Send Authenticated Preview Links** Only authenticated users can view [preview links](/learn/docs/preview-publish/previewing-changes-locally) +- **Send Authenticated Preview Links** Only authenticated users can view [preview links](docs/preview-publish/previewing-changes-locally) ## How it works diff --git a/fern/products/docs/pages/changelog/2025-01-14.mdx b/fern/products/docs/pages/changelog/2025-01-14.mdx index 005e6ac2..60d322be 100644 --- a/fern/products/docs/pages/changelog/2025-01-14.mdx +++ b/fern/products/docs/pages/changelog/2025-01-14.mdx @@ -6,7 +6,7 @@ We're excited to announce compatibility with the `/llms.txt` [emerging standard] Both `/llms.txt` and `/llms-full.txt` are designed to be token-efficient, ensuring faster processing and cost-effective LLM interactions without sacrificing valuable info. -If you use Fern Docs, this feature is auto-enabled like /robots.txt and /sitemap.xml. [Learn more](https://buildwithfern.com/learn/docs/seo/llms-txt) +If you use Fern Docs, this feature is auto-enabled like /robots.txt and /sitemap.xml. [Learn more](https://buildwithfern.com/learn/docs/developer-tools/llms-txt) ![LLMs.txt Splash Image](./llms-txt.png) diff --git a/fern/products/docs/pages/changelog/2025-05-23.mdx b/fern/products/docs/pages/changelog/2025-05-23.mdx index 81e8211a..c0cf2075 100644 --- a/fern/products/docs/pages/changelog/2025-05-23.mdx +++ b/fern/products/docs/pages/changelog/2025-05-23.mdx @@ -2,4 +2,4 @@ We've added a `max-toc-depth` frontmatter option to control the depth of the table of contents. Use this to limit the heading ranks included in the table of contents. -You can read more about this feature in the [frontmatter documentation](/learn/docs/configuration/page-level-settings#max-depth). \ No newline at end of file +You can read more about this feature in the [frontmatter documentation](/learn/docs/content/frontmatter#max-depth). \ No newline at end of file diff --git a/fern/products/docs/pages/component-library/custom-components/custom-css-js.mdx b/fern/products/docs/pages/component-library/custom-components/custom-css-js.mdx index dacb29ad..396b1519 100644 --- a/fern/products/docs/pages/component-library/custom-components/custom-css-js.mdx +++ b/fern/products/docs/pages/component-library/custom-components/custom-css-js.mdx @@ -56,7 +56,7 @@ css: For customizing the background, logo, font, and layout of your Docs via Fern's built-in styling, -check out the [Global Configuration](/learn/docs/configuration/what-is-docs-yml). +check out the [Global Configuration](/learn/docs/getting-started/global-configuration). ### Common use cases diff --git a/fern/products/docs/pages/component-library/default-components/accordions.mdx b/fern/products/docs/pages/component-library/default-components/accordions.mdx index f4e58e41..6ba3278b 100644 --- a/fern/products/docs/pages/component-library/default-components/accordions.mdx +++ b/fern/products/docs/pages/component-library/default-components/accordions.mdx @@ -5,6 +5,18 @@ description: 'Expand or collapse to reveal more information' The Accordion component allows you to create expandable sections in your documentation. Content within accordions is searchable using browser search (cmd+f) even when collapsed. The component is optimized for SEO with server-side HTML generation, ensuring search engines can properly index all content within accordions. +## Properties + + + The title shown in the accordion header + + + + The content to be displayed when the accordion is expanded. Can include text, markdown, and components. + + +
+ @@ -20,14 +32,3 @@ The Accordion component allows you to create expandable sections in your documen -## Properties - - - The title shown in the accordion header - - - - The content to be displayed when the accordion is expanded. Can include text, markdown, and components. - - - diff --git a/fern/products/docs/pages/component-library/default-components/callouts.mdx b/fern/products/docs/pages/component-library/default-components/callouts.mdx index a59399d2..26bf2360 100644 --- a/fern/products/docs/pages/component-library/default-components/callouts.mdx +++ b/fern/products/docs/pages/component-library/default-components/callouts.mdx @@ -5,6 +5,50 @@ description: 'Highlight important information, warnings, or tips in your documen Callouts help highlight important information, warnings, or tips in your documentation. They provide visual emphasis through distinct styling and icons to make key messages stand out to readers. +## Properties + +Customize your Callouts using the following properties: + + + The type of callout. Available options: `info`, `warning`, `success`, `error`, `note`, `launch`, `tip`, `check` + + + + The title of your Callout + + + + The icon of your Callout. Can be: + - A [Font Awesome](https://fontawesome.com/icons) icon name + - A React element + - If not specified, uses a default icon based on the intent: + - info: InfoCircle + - warning: Bell + - success: CheckCircle + - error: WarningTriangle + - note: Pin + - launch: Rocket + - tip: Star + - check: Check + + +
+ + + + +This Callout uses a title and a custom icon. + + + +```markdown + +This Callout uses a title and a custom icon. + +``` + + + ## Callout varieties ### Note callouts @@ -71,48 +115,3 @@ Callouts help highlight important information, warnings, or tips in your documen ```jsx This brings us a checked status ``` - -## Properties - -Customize your Callouts using the following properties: - - - The type of callout. Available options: `info`, `warning`, `success`, `error`, `note`, `launch`, `tip`, `check` - - - - The title of your Callout - - - - The icon of your Callout. Can be: - - A [Font Awesome](https://fontawesome.com/icons) icon name - - A React element - - If not specified, uses a default icon based on the intent: - - info: InfoCircle - - warning: Bell - - success: CheckCircle - - error: WarningTriangle - - note: Pin - - launch: Rocket - - tip: Star - - check: Check - - -
- - - - -This Callout uses a title and a custom icon. - - - -```markdown - -This Callout uses a title and a custom icon. - -``` - - - diff --git a/fern/products/docs/pages/component-library/default-components/card-groups.mdx b/fern/products/docs/pages/component-library/default-components/card-groups.mdx index 2b4252a0..bed9214b 100644 --- a/fern/products/docs/pages/component-library/default-components/card-groups.mdx +++ b/fern/products/docs/pages/component-library/default-components/card-groups.mdx @@ -5,6 +5,13 @@ description: 'Show cards side by side in a grid format' The `CardGroup` component lets you organize multiple `Card` components in a responsive grid layout. +## Properties + + + The number of columns to display in the grid + + +
@@ -41,9 +48,3 @@ The `CardGroup` component lets you organize multiple `Card` components in a resp ``` - -## Properties - - - The number of columns to display in the grid - diff --git a/fern/products/docs/pages/component-library/default-components/cards.mdx b/fern/products/docs/pages/component-library/default-components/cards.mdx index 7ae739fd..1ec55c07 100644 --- a/fern/products/docs/pages/component-library/default-components/cards.mdx +++ b/fern/products/docs/pages/component-library/default-components/cards.mdx @@ -5,19 +5,16 @@ description: 'Use cards to display content in a box' Cards are container components that group related content and actions together. They provide a flexible way to present information with optional elements like icons, titles, and links in a visually distinct box. +## Properties + +| Property | Type | Description | +|----------|------|-------------| +| `title` | `string` | The title text to display in the card | +| `icon` | `string \| img` | Either a [Font Awesome](https://fontawesome.com/icons) icon class (e.g. 'brands python') or a custom image | +| `href` | `string` | Optional URL that makes the entire card clickable | + +### Basic - - - - The icon field references a Font Awesome icon. - - - -```jsx The icon field references a Font Awesome icon. -``` - - - - -} - href="https://github.com/fern-api/fern/tree/main/generators/python" -> - Pass in an image tag to use a custom icon. - - - -```jsx +### Custom icon + } @@ -48,53 +32,51 @@ Cards are container components that group related content and actions together. > Pass in an image tag to use a custom icon. -``` - - - - - - You can set the icon position as `left` or `top`. - - - -```jsx +### Icon position + - You can set the icon position as `left` or `top`. + You can set the icon position as `left` or `top`. Default is `top`. -``` - - - -## Properties - - The title text to display in the card - - - Either a [Font Awesome](https://fontawesome.com/icons) icon class (e.g. 'brands python') or a custom image - - - Optional URL that makes the entire card clickable - - - The position of icon relative to the text. - - - Hex color value for the icon (e.g. `#FF0F00`). Ignored if `lightModeColor` and `darkModeColor` are both set - - - Hex color value for the icon in dark mode (e.g. `#FF0F00`) - - - Hex color value for the icon in light mode (e.g. `#FF0F00`) - + diff --git a/fern/products/docs/pages/component-library/default-components/code-blocks.mdx b/fern/products/docs/pages/component-library/default-components/code-blocks.mdx index 91a3b387..3cb11585 100644 --- a/fern/products/docs/pages/component-library/default-components/code-blocks.mdx +++ b/fern/products/docs/pages/component-library/default-components/code-blocks.mdx @@ -121,10 +121,8 @@ a `maxLines` attribute after the language identifier. The `maxLines` attribute should be a number representing the maximum number of lines to display. By default, the code block will display up to 20 lines. -When you use `maxLines`, an expand button automatically appears on hover in the top-right corner, allowing users to view the full code content in an expanded overlay that displays over the page. - - + ```python maxLines=10 def is_prime(num): """Check if a number is prime.""" @@ -184,15 +182,6 @@ When you use `maxLines`, an expand button automatically appears on hover in the -To hide the expand button or add custom styling, target the `.fern-expand-button` selector: - -```css -/* Hide the expand button */ -.fern-expand-button { - display: none; -} -``` - ## Wrap overflow By default, long lines that exceed the width of the code block become scrollable: @@ -317,16 +306,9 @@ The `CodeBlocks` component allows you to display multiple code blocks in a tabbe
-## Language synchronization - -Multiple `CodeBlocks` on a documentation site automatically synchronize. This -means when a user selects a `CodeBlock` with a specific language, all other -`CodeBlocks` across your documentation site with the same language will -automatically sync and switch to match. Language preferences are stored in -client-side local storage and persist across browser sessions. +## Example of Synchronized Blocks -The example below demonstrates language sync in action – choosing a language in -either set of code blocks will automatically update both sets to match: +Multiple `CodeBlocks` on a page automatically synchronize, showing the same language across all blocks. ```python title="Python" @@ -380,10 +362,6 @@ either set of code blocks will automatically update both sets to match: ``` - - `CodeBlocks` automatically synchronize with [`` components that have a `language` property](/docs/writing-content/components/tabs#language-synchronization). - - ### Override synchronization You can override the synchronization of code blocks by setting the `for` prop. diff --git a/fern/products/docs/pages/component-library/default-components/endpoint-schema-snippet.mdx b/fern/products/docs/pages/component-library/default-components/endpoint-schema-snippet.mdx index f5023a5e..f4e921ad 100644 --- a/fern/products/docs/pages/component-library/default-components/endpoint-schema-snippet.mdx +++ b/fern/products/docs/pages/component-library/default-components/endpoint-schema-snippet.mdx @@ -123,5 +123,5 @@ to specify the path to the schema you want to reference. The available selectors The EndpointSchemaSnippet component does not yet support rendering markdown-rich field descriptions. - See [request.endpoint.path](/learn/docs/writing-content/components/schema-snippet#request.endpoint.path) above for an example of a markdown-rich description that does not yet render as markdown. + See [request.endpoint.path](/docs/content/components/schema-snippet#request.endpoint.path) above for an example of a markdown-rich description that does not yet render as markdown. diff --git a/fern/products/docs/pages/component-library/default-components/frames.mdx b/fern/products/docs/pages/component-library/default-components/frames.mdx index ea12d459..05f43c5f 100644 --- a/fern/products/docs/pages/component-library/default-components/frames.mdx +++ b/fern/products/docs/pages/component-library/default-components/frames.mdx @@ -5,8 +5,19 @@ description: 'Wrap images in a container with the frame component' The Frame component provides a container for images and other media with optional captions and backgrounds. +## Properties + + + Caption text to display below the frame + + + + Adds a subtle background to the frame + + +
- + Sample photo of mountains @@ -20,8 +31,10 @@ The Frame component provides a container for images and other media with optiona +## With Subtle Background + - + Sample photo of mountains @@ -34,14 +47,3 @@ The Frame component provides a container for images and other media with optiona ``` - -## Properties - - - Caption text to display below the frame - - - - Adds a subtle background to the frame - - diff --git a/fern/products/docs/pages/component-library/default-components/icons.mdx b/fern/products/docs/pages/component-library/default-components/icons.mdx index 95c07f75..260dcd47 100644 --- a/fern/products/docs/pages/component-library/default-components/icons.mdx +++ b/fern/products/docs/pages/component-library/default-components/icons.mdx @@ -5,6 +5,8 @@ description: 'Use Font Awesome icons in your documentation' Add Font Awesome icons to your docs with customizable styles, colors and sizes using the `Icon` component. All Font Awesome Pro styles are supported. +## Examples +
diff --git a/fern/products/docs/pages/component-library/default-components/parameter-fields.mdx b/fern/products/docs/pages/component-library/default-components/parameter-fields.mdx index 6117582b..6c90fd9f 100644 --- a/fern/products/docs/pages/component-library/default-components/parameter-fields.mdx +++ b/fern/products/docs/pages/component-library/default-components/parameter-fields.mdx @@ -3,47 +3,7 @@ title: 'Parameters' description: 'Display API parameter information with metadata like type, requirements, and descriptions' --- -The `ParamField` component documents API parameters and properties with consistent formatting. It displays the parameter name, type, requirements, and description in a structured layout. - - - - - - The user's display name - - - - Maximum number of items to return - - - - Use OAuth authentication instead - - - - The current status of the user account - - - - ```jsx - - The user's display name - - - - Maximum number of items to return - - - - Use OAuth authentication instead - - - - The current status of the user account - - ``` - - +The `ParamField` component helps document API parameters and properties with consistent formatting. It displays the parameter name, type, requirements, and description in a structured layout. ## Properties @@ -64,5 +24,39 @@ The `ParamField` component documents API parameters and properties with consiste - Marks the parameter as deprecated. + Marks the parameter as deprecated. Shows a "Deprecated" warning when true. + + diff --git a/fern/products/docs/pages/component-library/default-components/steps.mdx b/fern/products/docs/pages/component-library/default-components/steps.mdx index a07f52bf..ddb281bd 100644 --- a/fern/products/docs/pages/component-library/default-components/steps.mdx +++ b/fern/products/docs/pages/component-library/default-components/steps.mdx @@ -3,7 +3,7 @@ title: 'Steps' description: 'Display a sequence of instructions or tasks with automatic numbering and anchor links.' --- -The Steps component helps organize sequential content with automatic numbering, anchor links, and clickable step numbers that copy direct URLs to that step with visual feedback. Hover interactions reveal helpful link icons, making it ideal for tutorials, walkthroughs, or any content that needs to be followed in order. +The Steps component helps organize sequential content with automatic numbering, anchor links, and copy-to-clipboard functionality. It's ideal for tutorials, walkthroughs, or any content that needs to be followed in order. @@ -27,15 +27,15 @@ The Steps component helps organize sequential content with automatic numbering, - + Initial instructions. - + More instructions. - + Final Instructions @@ -43,15 +43,15 @@ The Steps component helps organize sequential content with automatic numbering, ```jsx - + Initial instructions. - + More instructions. - + Final Instructions @@ -61,15 +61,15 @@ The Steps component helps organize sequential content with automatic numbering, ## Properties -### Steps Properties - - - Whether to include the steps in the table of contents. Defaults to `false`. - - -### Step Properties - Optional title for the step +
+ +## Features + +- Each step is automatically numbered in sequence +- Clicking the step number copies a direct URL to that step +- Hovering over a step's title or number reveals a link icon +- Visual feedback when step URL is copied diff --git a/fern/products/docs/pages/component-library/default-components/sticky-tables.mdx b/fern/products/docs/pages/component-library/default-components/sticky-tables.mdx deleted file mode 100644 index 40b31b18..00000000 --- a/fern/products/docs/pages/component-library/default-components/sticky-tables.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: Sticky tables -description: Display tables with sticky headers that remain visible while scrolling through table data. ---- - -The `StickyTable` component provides a way to display tabular data with a fixed header that remains visible while scrolling through table rows. This is particularly useful for longer tables where users need to reference column headers while viewing data further down the table. - -Below is an example of a **normal Markdown table**. As you scroll down the page, the entire table, including the header, scrolls out of view. - -| Plant | Light Requirements | Water | -|-------|-------------------|-------| -| Fern | Partial shade | Weekly | -| Snake Plant | Low to bright indirect | Bi-weekly | -| Monstera | Bright indirect | Weekly | -| Pothos | Low to bright indirect | Weekly | -| Fiddle Leaf Fig | Bright indirect | Weekly | -| Peace Lily | Low to medium indirect | Weekly | -| Rubber Plant | Bright indirect | Weekly | -| ZZ Plant | Low to bright indirect | Bi-weekly | -| Philodendron | Medium to bright indirect | Weekly | -| Aloe Vera | Bright direct | Bi-weekly | -| Boston Fern | Partial shade | 2-3x weekly | -| Spider Plant | Medium to bright indirect | Weekly | -| Dracaena | Medium indirect | Weekly | -| Bird of Paradise | Bright indirect to direct | Weekly | -| Calathea | Medium indirect | Weekly | - - -Below is an example of a **sticky table**. As you scroll down the page, the header row remains frozen at the top of the table. - - -| Plant | Light Requirements | Water | -|-------|-------------------|-------| -| Fern | Partial shade | Weekly | -| Snake Plant | Low to bright indirect | Bi-weekly | -| Monstera | Bright indirect | Weekly | -| Pothos | Low to bright indirect | Weekly | -| Fiddle Leaf Fig | Bright indirect | Weekly | -| Peace Lily | Low to medium indirect | Weekly | -| Rubber Plant | Bright indirect | Weekly | -| ZZ Plant | Low to bright indirect | Bi-weekly | -| Philodendron | Medium to bright indirect | Weekly | -| Aloe Vera | Bright direct | Bi-weekly | -| Boston Fern | Partial shade | 2-3x weekly | -| Spider Plant | Medium to bright indirect | Weekly | -| Dracaena | Medium indirect | Weekly | -| Bird of Paradise | Bright indirect to direct | Weekly | -| Calathea | Medium indirect | Weekly | - - -## Create a sticky table - -### Using Markdown - -Simply wrap any Markdown table with `` tags to make the header sticky. No changes to your table syntax are needed. - - - - -```markdown - - -| Plant | Light Requirements | Water | -|-------|-------------------|-------| -| Fern | Partial shade | Weekly | -| Snake Plant | Low to bright indirect | Bi-weekly | - - -``` - - - -| Plant | Light Requirements | Water | -|-------|-------------------|-------| -| Fern | Partial shade | Weekly | -| Snake Plant | Low to bright indirect | Bi-weekly | - - - -### Using HTML - -Simply add the `sticky` attribute to the opening `` tag. No further changes to your table syntax are needed. - - - - -```markdown -
- - - - - - - - - - - - - - - - - - - -
PlantLight RequirementsWater
FernPartial shadeWeekly
Snake PlantLow to bright indirectBi-weekly
-``` - -
- - - - - - - - - - - - - - - - - - - - - -
PlantLight RequirementsWater
FernPartial shadeWeekly
Snake PlantLow to bright indirectBi-weekly
-
-
- -## Style a sticky table - -Sticky tables can be styled independently from regular tables. To add custom styling, target the `.fern-table.sticky` selector: - -```css -.fern-table.sticky { - //custom css here -} -``` diff --git a/fern/products/docs/pages/component-library/default-components/tabs.mdx b/fern/products/docs/pages/component-library/default-components/tabs.mdx index 1290970e..9c79372f 100644 --- a/fern/products/docs/pages/component-library/default-components/tabs.mdx +++ b/fern/products/docs/pages/component-library/default-components/tabs.mdx @@ -1,188 +1,55 @@ --- -title: Tabs -description: The Tabs component allows you to display related content in a tabbed view with support for language synchronization. +title: 'Tabs' +description: 'The Tabs component allows you to display related content in a tabbed view.' --- -The Tabs component organizes content into separate tabs that users can switch between. Each tab can contain different types of content like examples, code snippets, or documentation sections. - - - - ☝️ Welcome to the content that you can only see inside the first Tab. - - - ✌️ Here's content that's only inside the second Tab. - - - 💪 Here's content that's only inside the third Tab. - - - - -```jsx - - - ☝️ Welcome to the content that you can only see inside the first Tab. - - - ✌️ Here's content that's only inside the second Tab. - - - 💪 Here's content that's only inside the third Tab. - - -``` - +The Tabs component organizes content into separate tabs that users can switch between. Each tab can contain different types of content like examples or code snippets. ## Properties - The title displayed in the tab header - The language associated with the code block. Any arbitrary string may be used. + The language associated with the code block. Any arbitrary string may be used. - When specified, enables global language synchronization across all tabs and code blocks with the same language value. + When a user selects a tab with a specific language, all other tabs assigned to the same language will automatically sync and switch to match. The content to be displayed when the tab is selected. Can include text, markdown, and components. -## Language synchronization - -Multiple `Tabs` with a `language` property automatically synchronize. This means -when a user selects a tab with a specific language, all other tabs across your -documentation site with the same language will automatically sync and switch to -match. Language preferences are stored in client-side local storage and persist -across browser sessions. - -In the example below, choosing a language in either set of tabs will automatically update both sets to match: - - - - ```typescript - console.log("First code block!"); - ``` - - - ```python - print("First code block!") - ``` - - - ```java - System.out.println("First code block!"); - ``` - - - - - - ```typescript - console.log("Second code block – language syncs with the one above!"); - ``` - - - ```python - print("Second code block – language syncs with the one above!") - ``` - - - ```java - System.out.println("Second code block – language syncs with the one above!"); - ``` - - +
- -````jsx - - ```typescript - console.log("Content inside the TypeScript tab"); - ``` - - - ```python - print("Content inside the Python tab") - ``` - - - ```java - System.out.println("Content inside the Java tab"); - ``` - - -```` - - - - Language-enabled `Tabs` automatically synchronize with [`CodeBlocks` in that same language](/docs/writing-content/components/code-blocks#language-synchronization). - - - - -Tabs **without** the `language` property don't stay in sync with other tabs on your site. In the below example, choosing a language in -either set of tabs doesn't affect the other set of tabs: - - - - ```typescript - console.log("First code block!"); - ``` + + ☝️ Welcome to the content that you can only see inside the first Tab. - - ```python - print("First code block!") - ``` + + ✌️ Here's content that's only inside the second Tab. - - ```java - System.out.println("First code block!"); - ``` + + 💪 Here's content that's only inside the third Tab. - - - ```typescript - console.log("Second code block – this won't sync with the one above!"); - ``` - - - ```python - print("Second code block – this won't sync with the one above!") - ``` - - - ```java - System.out.println("Second code block – this won't sync with the one above!"); - ``` - - + diff --git a/fern/products/docs/pages/component-library/default-components/tooltips.mdx b/fern/products/docs/pages/component-library/default-components/tooltips.mdx index f94de698..50f55e20 100644 --- a/fern/products/docs/pages/component-library/default-components/tooltips.mdx +++ b/fern/products/docs/pages/component-library/default-components/tooltips.mdx @@ -1,16 +1,22 @@ --- -title: Tooltips -description: Add interactive tooltips to your documentation. +title: 'Tooltips' +description: 'Add interactive tooltips to your documentation.' --- The Tooltips component provides a way to display additional information when users hover over an element. This is particularly useful for providing context or explanations without cluttering the interface. -## Tooltips in code +## Properties -The code tooltip component allows you to provide contextual information for variables and -values within your code examples. When users hover over highlighted code, they -can see explanations, documentation links, or additional context without leaving -the code example. + + Key-value pairs where the values are displayed in your code blocks. + + + + Key-value pairs where the values are displayed in the tooltips. The Key for `tooltips` must match the Key for `data`. + + + +## Examples @@ -129,80 +135,3 @@ const api = axios.create({ ````` - -### Properties - - - Key-value pairs where the values are displayed in your code blocks. - - - - Key-value pairs where the values are displayed in the tooltips. The Key for `tooltips` must match the Key for `data`. - - -### Style a code tooltip - -To customize code tooltips, target the `.fern-mdx-tooltip-content` selector. You can override CSS variables or add any custom styles: - -```css -.fern-mdx-tooltip-content { - --tooltip-padding-x: 1.5rem; /* Horizontal padding inside tooltip */ - /* Add custom styles here */ -} -``` - -## Tooltips for text - -The text tooltip component allows you to provide contextual information for any text element in your documentation. When users hover over them, they can see definitions or additional context without leaving the current page. - - - -Documentation becomes more interactive when you add tooltips to key terms. You can include Rich Content

Supports HTML formatting, external links, and inline code
} side="right">rich content with custom positioning for more detailed explanations. -
- -```tsx -Documentation becomes more interactive when you add tooltips to key terms. - -You can include - Rich Content -

- Supports HTML formatting, external links, and inline code - - } - side="right" ->rich content
with custom positioning for more detailed explanations. -``` -
-
- -### Properties - - - The content to display in the tooltip. Can be a simple string or React component for more complex content. - - - - Controls which side of the element the tooltip appears on. - - - - The distance in pixels between the tooltip and the trigger element. - - - -### Style a text tooltip - -To customize text tooltips, target the `.fern-mdx-tooltip-trigger` selector. You can override CSS variables for common customizations or add any custom styles: - -```css -.fern-mdx-tooltip-trigger { - --tooltip-underline-color: blue; /* Color of the underline in default state */ - --tooltip-underline-hover-color: green; /* Color of the underline on hover */ - --tooltip-underline-thickness: 2px; /* Thickness of the underline */ - --tooltip-underline-offset: 2px; /* Distance between text and underline */ - --tooltip-transition-duration: 0.10s; /* Hover transition speed */ - /* Add custom styles here */ -} -``` \ No newline at end of file diff --git a/fern/products/docs/pages/component-library/writing-content/markdown.mdx b/fern/products/docs/pages/component-library/writing-content/markdown.mdx index 9bb455eb..3269b920 100644 --- a/fern/products/docs/pages/component-library/writing-content/markdown.mdx +++ b/fern/products/docs/pages/component-library/writing-content/markdown.mdx @@ -189,7 +189,7 @@ You can embed videos from YouTube, Loom, Vimeo, and other streaming platforms us -See an example of [how it renders](https://elevenlabs.io/docs/conversational-ai/guides/integrations/zendesk#demo-video) on the corresponding docs page from the ElevenLabs documentation. +See an example of [Markdown](https://github.com/elevenlabs/elevenlabs-docs/blob/6dba2b35a68edd8285762e18b4c7684c04bdf1ca/fern/conversational-ai/pages/guides/zendesk.mdx?plain=1#L14-L23) used for embedding videos and [how it renders](https://elevenlabs.io/docs/conversational-ai/guides/integrations/zendesk#demo-video) on the corresponding docs page from the ElevenLabs documentation. ## LaTeX diff --git a/fern/products/docs/pages/customization/frontmatter.mdx b/fern/products/docs/pages/customization/frontmatter.mdx index e8a6599f..3279c8f4 100644 --- a/fern/products/docs/pages/customization/frontmatter.mdx +++ b/fern/products/docs/pages/customization/frontmatter.mdx @@ -15,7 +15,6 @@ title: Customize content using frontmatter subtitle: Set titles, add meta descriptions, and more slug: frontmatter description: Use frontmatter to set the page title, subtitle, slug, meta description, its OpenGraph image, and a URL to suggest edits. -keywords: frontmatter, seo, customization, metadata og:sitename: Your Company Inc. og:title: SEO Metadata Title --- @@ -245,8 +244,112 @@ Currently, relative paths are _not_ supported for this field. ## SEO metadata - - [Use the metadata field in the `docs.yml` file](/learn/docs/configuration/what-is-docs-yml#seo-metadata-configuration). + +Looking to set metadata across the entire site? [Use the metadata field in the `docs.yml` file](/learn/docs/customization/what-is-docs-yml#metadata-configuration). + +When configuring SEO metadata, ensure your titles and descriptions are unique, descriptive, and relevant to the page content. Keep descriptions between 150-160 characters for optimal display in search results. - \ No newline at end of file + +```mdx +--- +title: PlantStore API Quick Start +headline: "Gett Started with PlantStore API | Developer Documentation" +canonical-url: https://docs.plantstore.dev/welcome +og:site_name: PlantStore Developer Documentation +og:title: "PlantStore API Quick Start Guide" +og:description: "Learn how to integrate with PlantStore's API to manage plant inventory, process orders, and track shipments. Complete with code examples." +og:image: https://plantstore.dev/images/api-docs-banner.png +og:image:width: 1200 +og:image:height: 630 +twitter:card: summary_large_image +twitter:site: "@PlantStoreAPI" +noindex: false +nofollow: false +--- +``` + + +### Document Properties + + When set, the `` tag in the document head will use this value rather than the `title` property. This property changes the title that search engines see when crawling this page, and can be used to address Duplicate Title issues in your SEO report. +</ParamField> + +<ParamField path="canonical-url" type="string" required={false}> + Overrides the canonical URL for this page. Must be a full URL including the protocol (i.e. `https://buildwithfern.com/learn/docs/content/frontmatter`) +</ParamField> + +### OpenGraph Properties +<ParamField path="og:site_name" type="string" required={false}> + The name of your website as it should appear when your content is shared. +</ParamField> + +<ParamField path="og:title" type="string" required={false}> + The title of your page as it should appear when your content is shared. +</ParamField> + +<ParamField path="og:description" type="string" required={false}> + The description of your page as it should appear when your content is shared. +</ParamField> + +<ParamField path="og:url" type="string" required={false}> + The URL of your page. +</ParamField> + +<ParamField path="og:image" type="string" required={false}> + The URL or identifier of the image that will be displayed when your content is shared. +</ParamField> + +<ParamField path="og:image:width" type="number" required={false}> + The width of the image in pixels. +</ParamField> + +<ParamField path="og:image:height" type="number" required={false}> + The height of the image in pixels. +</ParamField> + +<ParamField path="og:locale" type="string" required={false}> + The locale of the page, typically in the format `language_TERRITORY` (e.g., `en_US`). +</ParamField> + +<ParamField path="og:logo" type="string" required={false}> + The URL or identifier of the logo image of your website that will be displayed when your content is shared. +</ParamField> + +### Twitter Properties +<ParamField path="twitter:title" type="string" required={false}> + The title of your page as it should appear in a tweet. +</ParamField> + +<ParamField path="twitter:description" type="string" required={false}> + The description of your page as it should appear in a tweet. +</ParamField> + +<ParamField path="twitter:handle" type="string" required={false}> + The Twitter handle of the page creator or site. +</ParamField> + +<ParamField path="twitter:image" type="string" required={false}> + The URL or identifier of the image that will be displayed in a tweet. +</ParamField> + +<ParamField path="twitter:site" type="string" required={false}> + The name of your website as it should appear in a tweet. +</ParamField> + +<ParamField path="twitter:url" type="string" required={false}> + The URL of your page. +</ParamField> + +<ParamField path="twitter:card" type="string" required={false}> + The type of card to be used for sharing on Twitter. Options: `summary`, `summary_large_image`, `app`, `player` +</ParamField> + +### Indexing Properties +<ParamField path="noindex" type="boolean" required={false} default={false}> + If set to `true`, the page will not be indexed by search engines. +</ParamField> + +<ParamField path="nofollow" type="boolean" required={false} default={false}> + If set to `true`, a search engine will not follow any links present on the page. +</ParamField> diff --git a/fern/products/docs/pages/customization/global-configuration.mdx b/fern/products/docs/pages/customization/global-configuration.mdx index d18a3633..916486cf 100644 --- a/fern/products/docs/pages/customization/global-configuration.mdx +++ b/fern/products/docs/pages/customization/global-configuration.mdx @@ -122,7 +122,7 @@ instances: </ParamField> <ParamField path="instances.custom-domain" type="string or list of strings" required={false}> - The custom domain where your documentation is hosted. Learn more about [setting up a custom domain](/learn/docs/preview-publish/setting-up-your-domain). + The custom domain where your documentation is hosted. Learn more about [setting up a custom domain](/learn/docs/building-your-docs/custom-domain). </ParamField> <ParamField path="instances.edit-this-page" type="object" required={false}> diff --git a/fern/products/docs/pages/customization/search.mdx b/fern/products/docs/pages/customization/search.mdx index dbf424bc..8395817b 100644 --- a/fern/products/docs/pages/customization/search.mdx +++ b/fern/products/docs/pages/customization/search.mdx @@ -23,7 +23,7 @@ If you are using the AI Search feature, the search box also functions as your si </Frame> <Note> - **Note:** If an article includes the `nofollow` or `noindex` [frontmatter](/learn/docs/configuration/page-level-settings#indexing-properties), it will not be indexed by Algolia DocSearch and won't appear in search results. + **Note:** If an article includes the `nofollow` or `noindex` [frontmatter](/learn/docs/content/frontmatter#indexing-properties), it will not be indexed by Algolia DocSearch and won't appear in search results. </Note> ## Integrating with Algolia diff --git a/fern/products/docs/pages/customization/user-feedback.mdx b/fern/products/docs/pages/customization/user-feedback.mdx index d5a2becf..5d375b5a 100644 --- a/fern/products/docs/pages/customization/user-feedback.mdx +++ b/fern/products/docs/pages/customization/user-feedback.mdx @@ -16,7 +16,7 @@ By default, every Markdown page of your docs contains a feedback component at th The feedback can be sent to you in real-time via the method of your choosing (e.g. Slack, email). -To disable this feature on a page, set `hide-feedback: true` in the frontmatter of that page. You can read more about the frontmatter configuration [here](/learn/docs/configuration/page-level-settings#on-page-feedback). +To disable this feature on a page, set `hide-feedback: true` in the frontmatter of that page. You can read more about the frontmatter configuration [here](/learn/docs/content/frontmatter#on-page-feedback). ## Edit this page Allow users to open directly to the current page in your GitHub repository and suggest changes. @@ -25,7 +25,7 @@ Allow users to open directly to the current page in your GitHub repository and s <img src="./edit-this-page.png" /> </Frame> -You can configure this feature for the entire site in the [global configuration](/learn/docs/getting-started/global-configuration#instances-configuration), or for an individual page in the [frontmatter of that page](/learn/docs/configuration/page-level-settings#edit-this-page). +You can configure this feature for the entire site in the [global configuration](/learn/docs/getting-started/global-configuration#instances-configuration), or for an individual page in the [frontmatter of that page](/learn/docs/content/frontmatter#edit-this-page). <Note> This feature works in preview links but does not work in local development. diff --git a/fern/products/docs/pages/customization/what-is-docs-yml.mdx b/fern/products/docs/pages/customization/what-is-docs-yml.mdx index 802c0a45..945a33a2 100644 --- a/fern/products/docs/pages/customization/what-is-docs-yml.mdx +++ b/fern/products/docs/pages/customization/what-is-docs-yml.mdx @@ -100,7 +100,7 @@ navbar-links: <ParamField path="metadata" type="object" required={false}> Configure SEO metadata for your documentation website. Learn more about the - [`metadata` configuration](/learn/docs/getting-started/global-configuration#seo-metadata-configuration). + [`metadata` configuration](/learn/docs/getting-started/global-configuration#metadata-configuration). </ParamField> ## Instances configuration @@ -122,7 +122,7 @@ instances: </ParamField> <ParamField path="instances.custom-domain" type="string or list of strings" required={false}> - The custom domain where your documentation is hosted. Learn more about [setting up a custom domain](/learn/docs/preview-publish/setting-up-your-domain). + The custom domain where your documentation is hosted. Learn more about [setting up a custom domain](/learn/docs/building-your-docs/custom-domain). </ParamField> <ParamField path="instances.edit-this-page" type="object" required={false}> @@ -523,13 +523,91 @@ landing-page: See [Vapi's landing page live](https://docs.vapi.ai/) and the associated [Markdown file](https://github.com/VapiAI/docs/blob/main/fern/quickstart/introduction.mdx?plain=1). -## SEO metadata configuration +## Metadata configuration -<Note title="Looking to set metadata for a single page?"> - [Use the `keywords` property in a page's frontmatter](/docs/configuration/page-level-settings#seo-metadata). -</Note> +```yaml docs.yml +metadata: + # Core platform identity + og:site_name: "Square Developer Documentation" + og:title: "Square Developer Platform | Payments, Commerce & Banking APIs" + og:description: "Build with Square's suite of APIs and SDKs. Accept payments, manage inventory, create loyalty programs, and access financial services. Complete documentation for developers building the future of commerce." + og:url: "https://developer.squareup.com/docs" + + # Social sharing assets + og:image: "https://developer.squareup.com/images/docs-social-card.png" + og:image:width: 1200 + og:image:height: 630 + og:locale: "en_US" + og:logo: "https://developer.squareup.com/images/square-logo.png" + + # Twitter (I mean X) optimization + twitter:title: "Square Developer Platform Documentation" + twitter:description: "Integrate payments, point-of-sale, inventory, and financial services into your applications with Square's developer platform. Get started with our APIs, SDKs, and comprehensive guides." + twitter:handle: "@SquareDev" + twitter:image: "https://developer.squareup.com/images/twitter-card.png" + twitter:site: "@Square" + twitter:card: "summary_large_image" +``` + +<ParamField path="metadata.og:site_name" type="string" required={false}> + The name of your website for Open Graph tags. +</ParamField> + +<ParamField path="metadata.og:title" type="string" required={false}> + The title shown in social media previews. +</ParamField> + +<ParamField path="metadata.og:description" type="string" required={false}> + The description shown in social media previews. +</ParamField> + +<ParamField path="metadata.og:url" type="string" required={false}> + The canonical URL of your documentation. +</ParamField> + +<ParamField path="metadata.og:image" type="string" required={false}> + The image shown in social media previews. Recommended size is 1200x630 pixels. +</ParamField> + +<ParamField path="metadata.og:image:width" type="number" required={false}> + The width of your Open Graph image in pixels. +</ParamField> + +<ParamField path="metadata.og:image:height" type="number" required={false}> + The height of your Open Graph image in pixels. +</ParamField> -<Markdown src="/snippets/seo-metadata-site.mdx" /> +<ParamField path="metadata.og:locale" type="string" required={false}> + The locale of your content (e.g., "en_US"). +</ParamField> + +<ParamField path="metadata.og:logo" type="string" required={false}> + URL to your company logo. +</ParamField> + +<ParamField path="metadata.twitter:title" type="string" required={false}> + The title shown in Twitter Card previews. +</ParamField> + +<ParamField path="metadata.twitter:description" type="string" required={false}> + The description shown in Twitter Card previews. +</ParamField> + +<ParamField path="metadata.twitter:handle" type="string" required={false}> + Your company's Twitter handle. +</ParamField> + +<ParamField path="metadata.twitter:image" type="string" required={false}> + The image shown in Twitter Card previews. +</ParamField> + +<ParamField path="metadata.twitter:site" type="string" required={false}> + The Twitter handle for your website. +</ParamField> + +<ParamField path="metadata.twitter:card" type="string" required={false}> + The Twitter Card type. Options are `summary`, `summary_large_image`, `app`, or `player`. +</ParamField> ## Analytics configuration diff --git a/fern/products/docs/pages/developer-tools/gitlab.mdx b/fern/products/docs/pages/developer-tools/gitlab.mdx index b9fc49d8..f8fa0003 100644 --- a/fern/products/docs/pages/developer-tools/gitlab.mdx +++ b/fern/products/docs/pages/developer-tools/gitlab.mdx @@ -2,7 +2,7 @@ title: Hosting with GitLab --- -To host your Fern docs using GitLab, you will need to [add a Fern token to your repository variables](/learn/docs/developer-tools/git-lab#add-a-token-to-gitlab). +To host your Fern docs using GitLab, you will need to [add a Fern token to your repository variables](/learn/docs/developer-tools/gitlab#add-a-token-to-gitlab). <Accordion title="GitLab CI/CD configuration"> The following GitLab CI/CD workflow will generate a preview link of your docs on merge request and publish your docs when updates are made to `main`. @@ -105,5 +105,5 @@ When finished, click **Create project access token**. Be sure to save the generated token - it won't be displayed after you leave the page. </Note> ### Add token to repository variables -You can do this using [the steps listed above](/learn/docs/developer-tools/git-lab#add-a-token-to-gitlab). +You can do this using [the steps listed above](/learn/docs/developer-tools/gitlab#add-a-token-to-gitlab). </Steps> diff --git a/fern/products/docs/pages/developer-tools/view-markdown.mdx b/fern/products/docs/pages/developer-tools/view-markdown.mdx index dd34fdb8..54d5a0af 100644 --- a/fern/products/docs/pages/developer-tools/view-markdown.mdx +++ b/fern/products/docs/pages/developer-tools/view-markdown.mdx @@ -3,7 +3,7 @@ title: View Markdown description: Learn how to view the Markdown underlying a documentation page, to help with tool integration and troubleshooting. --- -Adding `.md` or `.mdx` to the end of a documentation page's URL shows its source Markdown, excluding frontmatter. This works for both normal and API reference pages. +Adding `.md` to the end of a documentation page's URL shows its source Markdown, excluding frontmatter. This works for both normal and API reference pages. <Tip>Displaying the page's Markdown helps with troubleshooting layout problems and makes it easier to process page content with external tools or AI agents.</Tip> diff --git a/fern/products/docs/pages/enterprise/self-hosted.mdx b/fern/products/docs/pages/enterprise/self-hosted.mdx index b7672c42..685c0a6e 100644 --- a/fern/products/docs/pages/enterprise/self-hosted.mdx +++ b/fern/products/docs/pages/enterprise/self-hosted.mdx @@ -21,7 +21,7 @@ Unless you have specific requirements that prevent using Fern's default hosting, Self-hosted deployments include core Fern documentation website features like auto-generated API references, interactive documentation, SDK code snippets, search, and customizable branding. -However, features requiring external connections aren't supported, including [Ask Fern](/ask-fern/getting-started/what-is-ask-fern) (AI chat), [analytics](/docs/integrations/overview), [live API key population](/docs/authentication/api-key-injection), and [SSO integrations](/docs/authentication/sso). +However, features requiring external connections aren't supported, including [Ask Fern](/ask-fern/getting-started/what-is-ask-fern) (AI chat), [analytics](/integrations/overview), [live API key population](/docs/authentication/api-key-injection), and [SSO integrations](/docs/authentication/sso). <Info title="Extended feature support"> **PDF export** and **offline AI chat functionality** are not yet available on any plan but are in development for enterprise self-hosted deployments. [Email us](mailto:support@buildwithfern.com) if you're interested in these features. diff --git a/fern/products/docs/pages/getting-started/images/mcp-server-light.png b/fern/products/docs/pages/getting-started/images/mcp-server-light.png new file mode 100644 index 00000000..aa4043b4 Binary files /dev/null and b/fern/products/docs/pages/getting-started/images/mcp-server-light.png differ diff --git a/fern/products/docs/pages/getting-started/images/self-host-light.png b/fern/products/docs/pages/getting-started/images/self-host-light.png new file mode 100644 index 00000000..3b92f1a5 Binary files /dev/null and b/fern/products/docs/pages/getting-started/images/self-host-light.png differ diff --git a/fern/products/docs/pages/getting-started/overview.mdx b/fern/products/docs/pages/getting-started/overview.mdx index 2f080188..51c5d53b 100644 --- a/fern/products/docs/pages/getting-started/overview.mdx +++ b/fern/products/docs/pages/getting-started/overview.mdx @@ -11,7 +11,7 @@ subtitle: A website builder for beautiful agent and developer-friendly docs. <div className="dashed-pattern-right"></div> <h2>Get started</h2> - <p>Build a docs site quickly by importing your existing styling and specs.</p> + <p>Build a docs site quickly by importing your existing syling and specs.</p> <CardGroup cols={2}> <a class="fern-card interactive not-prose relative block p-6 text-base" href="/docs/getting-started/quickstart"> @@ -31,7 +31,7 @@ subtitle: A website builder for beautiful agent and developer-friendly docs. </div> </a> - <a class="fern-card interactive not-prose rounded-3 relative block border p-6 text-base" href="/docs/configuration/what-is-docs-yml"> + <a class="fern-card interactive not-prose rounded-3 relative block border p-6 text-base" href="/docs/customization/what-is-docs-yml"> <div class="flex items-start flex-col space-y-3"> <img class="mx-auto dark:hidden" alt="Configure with ease" src="./images/configure.png" /> <img class="mx-auto hidden dark:block" alt="Configure with ease" src="./images/configure-dark.png" /> @@ -115,7 +115,41 @@ subtitle: A website builder for beautiful agent and developer-friendly docs. <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="text-(color:--grayscale-a11) font-light"> - <p>Get instant answers to questions about your docs from a personalized chatbot.</p> + <p>A personalized chatbot that can answer questions about your documentation.</p> + </div> + </div> + </div> + </a> + + <a class="fern-card interactive not-prose rounded-3 relative block border p-6 text-base" href="/docs/self-hosted/overview"> + <div class="flex items-start flex-col space-y-3"> + <img class="mx-auto dark:hidden" alt="Visual Editor" src="./images/self-host-light.png" /> + <img class="mx-auto hidden dark:block" alt="Visual Editor" src="./images/ask-fern-dark.png" /> + <div class="w-full space-y-1 overflow-hidden"> + <div class="text-(color:--grayscale-a12) text-body text-base font-semibold card-title"> + Self-host your docs + <img src="./images/arrow-right-black.svg" alt="Arrow right light" className="arrow-right dark:hidden m-0" noZoom /> + <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> + </div> + <div class="text-(color:--grayscale-a11) font-light"> + <p>Deploy on your own infrastructure to meet security or compliance requirements.</p> + </div> + </div> + </div> + </a> + + <a class="fern-card interactive not-prose rounded-3 relative block border p-6 text-base" href="/ask-fern/getting-started/what-is-ask-fern"> + <div class="flex items-start flex-col space-y-3"> + <img class="mx-auto dark:hidden" alt="Visual Editor" src="./images/mcp-server-light.png" /> + <img class="mx-auto hidden dark:block" alt="Visual Editor" src="./images/ask-fern-dark.png" /> + <div class="w-full space-y-1 overflow-hidden"> + <div class="text-(color:--grayscale-a12) text-body text-base font-semibold card-title"> + Fern's MCP Server + <img src="./images/arrow-right-black.svg" alt="Arrow right light" className="arrow-right dark:hidden m-0" noZoom /> + <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> + </div> + <div class="text-(color:--grayscale-a11) font-light"> + <p>Add Fern's MCP server to your AI agentic workflows.</p> </div> </div> </div> diff --git a/fern/products/docs/pages/getting-started/preview-changes-locally.mdx b/fern/products/docs/pages/getting-started/preview-changes-locally.mdx index 4a3d72c0..9790d224 100644 --- a/fern/products/docs/pages/getting-started/preview-changes-locally.mdx +++ b/fern/products/docs/pages/getting-started/preview-changes-locally.mdx @@ -10,7 +10,7 @@ Fern offers two ways to preview changes to your documentation: a [local developm Fern enables you to view changes to your documentation in a locally hosted environment. -<Info>**Prerequisite**: Please install Node.js (version 18+) before proceeding.</Info> +<Info>**Prerequisite**: Please install Node.js (version 18) before proceeding.</Info> Follow these steps to install and run the Fern CLI: diff --git a/fern/products/docs/pages/getting-started/project-structure.mdx b/fern/products/docs/pages/getting-started/project-structure.mdx index 3b54e33e..b13373f1 100644 --- a/fern/products/docs/pages/getting-started/project-structure.mdx +++ b/fern/products/docs/pages/getting-started/project-structure.mdx @@ -68,7 +68,7 @@ The `assets` folder contains any images or videos used in your documentation. Yo The `docs.yml` file is the heart of your Fern documentation site. This configuration file controls your documentation's navigation structure, visual design, site functionality, and hosting settings. -For complete configuration options, see the [docs.yml reference](/docs/configuration/what-is-docs-yml). +For complete configuration options, see the [docs.yml reference](/docs/customization/what-is-docs-yml). <CodeBlock title="fern/docs.yml of this website"> ```yml @@ -111,14 +111,10 @@ title: Fern's Documentation <AccordionGroup> <Accordion title="OpenAPI"> The `openapi` folder contains the OpenAPI Specification file for your API Reference section. Fern will read either a YAML or JSON file from this folder to generate the API Reference documentation. If you don't have an API Reference section, you can skip this folder. - - In addition to your specification file, you can optionally [add an overrides file](/api-definitions/overview/overrides) for additional customizations. - <CodeBlock title="fern/openapi"> ```bash openapi - ├─ openapi.yaml # OR openapi.json - └─ overrides.yaml + └─ openapi.yaml # OR openapi.json ``` </CodeBlock> @@ -127,16 +123,12 @@ title: Fern's Documentation </Accordion> <Accordion title="Fern Definition"> The `definition` folder contains the Fern Definition YAML files used to generate the API Reference section. If you don't have an API Reference section, you can skip this folder. - - In addition to your specification file, you can optionally [add an overrides file](/api-definitions/overview/overrides) for additional customizations. - <CodeBlock title="fern/definition"> ```bash definition ├─ pets.yaml ├─ owners.yaml ├─ stores.yaml - ├─ overrides.yaml └─ api.yaml ``` </CodeBlock> @@ -145,18 +137,14 @@ title: Fern's Documentation </Accordion> <Accordion title="Multiple APIs"> - If you have multiple APIs, you can organize them into separate folders within the `apis` folder. Each API should have its own API definition and [(optional) overrides file](/api-definitions/overview/overrides). - - For example: + If you have multiple APIs, you can organize them into separate folders within the `apis` folder. Each API should have its own API definition. For example: <CodeBlock title="fern/apis"> ```bash apis ├─ admin - │ ├─ openapi.json - │ └─ overrides.yaml + │ └─ openapi.json ├─ user - │ ├─ openapi.yaml - │ └─ overrides.yaml + │ └─ openapi.yaml ``` </CodeBlock> @@ -165,18 +153,6 @@ title: Fern's Documentation </Accordion> </AccordionGroup> -<Note> - If you're using Fern for both API Reference documentation and SDKs, you'll use both `docs.yml` (the Docs configuration file) and `generators.yml` ([the SDK configuration file](/sdks/overview/project-structure#generatorsyml)) to configure [how SDK code snippets appear](/docs/api-references/sdk-snippets) in your API reference documentation. - - If you're only using Fern for API Reference docs, not SDKs, your `generators.yml` should simply link to your spec: - - ```yaml title="generators.yml" - api: - specs: - - openapi: ../openapi/openapi.json - ``` -</Note> - ## `fern.config.json` @@ -189,6 +165,4 @@ The `fern.config.json` file specifies your organization name and the version of "version": "<Markdown src="/products/sdks/snippets/fern-config-json-version.mdx"/>" } ``` -</CodeBlock> - - +</CodeBlock> \ No newline at end of file diff --git a/fern/products/docs/pages/integrations/postman.mdx b/fern/products/docs/pages/integrations/postman.mdx index efe30e89..8623cc0d 100644 --- a/fern/products/docs/pages/integrations/postman.mdx +++ b/fern/products/docs/pages/integrations/postman.mdx @@ -1,14 +1,9 @@ --- title: "Postman Integration" description: "Generate a postman collection full of example requests and responses" +subtitle: "Generate a postman collection full of example requests and responses" --- -You can generate a Postman collection full of example requests and responses and -publish your collection to Postman. The configuration for the postman generator -lives in your fern folder, in a file called -[`generators.yml`](/sdks/overview/project-structure#generatorsyml). - - ## Showcase <CardGroup cols={2}> @@ -20,14 +15,93 @@ lives in your fern folder, in a file called icon={<img src="https://cdn.prod.website-files.com/5e9dc792e1210c5325f7ebbc/64b039144f484892355032dd_62146168.png" />} iconSize={12} /> + +<Card + title="MirrorWOrld" + href="https://developer.mirrorworld.fun/" + horizontal + icon={<img src="https://cdn.brandfetch.io/idLEJUb6Vb/w/400/h/400/theme/dark/icon.jpeg" />} + iconSize={12} +/> + </CardGroup> ## Getting started -For information on how to generate a Postman collection, see the [Postman Quickstart](/products/sdks/overview/postman/quickstart.mdx). +The configuration for the postman generator lives in your fern folder, in a file +called [`generators.yml`](/learn/api-definition/introduction/what-is-the-fern-folder#generatorsyml). + +### **Step 1**: Configure your `generators.yml` + +Start by running the following command: + +```sh +fern add fern-postman --group postman +``` + +Once the command completes, you will see the following configuration added: + +```yaml title="generators.yml" {2-8} +groups: + postman: + generators: + - name: fernapi/fern-postman + version: 0.0.45 + output: + location: local-file-system + path: ../postman +``` + +### **Step 2**: Generate a `collection.json` + +Start by running the following command: + +```sh +fern generate --group postman +``` + +This will trigger postman collection on Fern's cloud. Once complete, you'll see a `collection.json`: + +```bash {4-5} +fern/ + ├─ fern.config.json + ├─ generators.yml +postman + ├─ collection.json +``` ## Publishing -For information on how to publish to a specific collection or directly to Postman, see [Publishing to Postman](/products/sdks/overview/postman/publishing-to-postman.mdx). +If you'd like Fern to publish the collection directly to Postman instead, you can modify your `generators.yml` configuration +in the following way: + +```yaml title="generators.yml" {6-9} +generators: + postman: + generators: + - name: fernapi/fern-postman + version: 0.4.0 + output: + location: postman + api-key: ${POSTMAN_API_KEY} + workspace-id: 07e228e5-3f91-4223-8e27-bbfe4a81a601 + config: + collection-name: My collection name +``` +If you'd like to publish to a particular collection, just specify the collection ID. +```yaml title="generators.yml" {10} +generators: + postman: + generators: + - name: fernapi/fern-postman + version: 0.4.0 + output: + location: postman + api-key: ${POSTMAN_API_KEY} + workspace-id: 07e228e5-3f91-4223-8e27-bbfe4a81a601 + collection-id: 21510182-14b07230-46e2-431e-8153-d5c7d217b214 + config: + collection-name: My collection name +``` diff --git a/fern/products/docs/pages/navigation/changelogs.mdx b/fern/products/docs/pages/navigation/changelogs.mdx index 33048f77..335e7634 100644 --- a/fern/products/docs/pages/navigation/changelogs.mdx +++ b/fern/products/docs/pages/navigation/changelogs.mdx @@ -53,7 +53,7 @@ navigation: ``` </CodeBlock> -[View an example](https://elevenlabs.io/docs/changelog) of how this renders in the ElevenLabs Changelog. +[View an example](https://github.com/elevenlabs/elevenlabs-docs/blob/ab509a12b1c7e3db37b6414a76b502e71b580feb/fern/docs.yml#L45-L47) in GitHub of the ElevenLabs `docs.yml` which powers [their Changelog](https://elevenlabs.io/docs/changelog). </Accordion> <Accordion title="Section-level Changelog"> diff --git a/fern/products/docs/pages/navigation/overview.mdx b/fern/products/docs/pages/navigation/overview.mdx index f1398645..2a6f71de 100644 --- a/fern/products/docs/pages/navigation/overview.mdx +++ b/fern/products/docs/pages/navigation/overview.mdx @@ -240,7 +240,7 @@ Here's an example of what the Tabs implementation looks like: <img src="./images/tabs-sidebar.png" alt="Tabs displayed in the sidebar (default)" /> </Frame> -Tabs display in the left sidebar by default. To display them horizontally, set `tabs-placement` to `header` in your [layout configuration](/docs/configuration/what-is-docs-yml#layout-configuration). +Tabs display in the left sidebar by default. To display them horizontally, set `tabs-placement` to `header` in your [layout configuration](/docs/customization/what-is-docs-yml#layout-configuration). <CodeBlock title="docs.yml"> ```yaml @@ -252,25 +252,3 @@ layout: ## Versions If you have multiple versions of your documentation, you can introduce a dropdown version selector by specifying the `versions`. For more information, check out our [documentation on versioning](/learn/docs/building-your-docs/versioning). - -## Product switching - -If you have multiple products in your documentation, you can introduce a dropdown product selector by creating separate product configuration files. Each product can contain its own distinct versions, tabs, sections, pages, and API references, though products can also share content. - -<CodeBlock title="docs.yml"> -```yaml {2-3, 7-8} -products: - - display-name: Product A - path: ./products/product-a.yml - icon: fa-solid fa-leaf # optional - slug: product-a # optional - subtitle: Product A subtitle # optional - - display-name: Product B - path: ./products/product-b/latest.yml # <-- default showing latest - image: ./images/product-b.png # optional - slug: product-b # optional - subtitle: Product B subtitle # optional -``` -</CodeBlock> - -For more information about setting up this up, check out our [documentation on product switching](/learn/docs/configuration/products). \ No newline at end of file diff --git a/fern/products/docs/pages/navigation/products.mdx b/fern/products/docs/pages/navigation/products.mdx index bd574f25..0e043d11 100644 --- a/fern/products/docs/pages/navigation/products.mdx +++ b/fern/products/docs/pages/navigation/products.mdx @@ -164,7 +164,7 @@ products: ``` </CodeBlock> -For more information on setting up versioned products, follow our [versioning docs](/docs/configuration/versions). +For more information on setting up versioned products, follow our [versioning docs](/docs/navigation/versions). </Step> <Step title="Remove extra navigation from docs.yml"> diff --git a/fern/products/docs/pages/navigation/versions.mdx b/fern/products/docs/pages/navigation/versions.mdx index d4ad8391..1ecf958d 100644 --- a/fern/products/docs/pages/navigation/versions.mdx +++ b/fern/products/docs/pages/navigation/versions.mdx @@ -78,7 +78,7 @@ tabs: </CodeBlock> </CodeBlocks> -<Note>You can also have multiple products, some versioned and some unversioned. For more information on setting up multiple products, follow our [product switching docs](/docs/configuration/products).</Note> +<Note>You can also have multiple products, some versioned and some unversioned. For more information on setting up multiple products, follow our [product switching docs](/docs/navigation/products).</Note> </Step> <Step title="Add your version configuration"> diff --git a/fern/products/docs/pages/seo/configuring-slugs.mdx b/fern/products/docs/pages/seo/configuring-slugs.mdx index a0ab3766..2bf63ef4 100644 --- a/fern/products/docs/pages/seo/configuring-slugs.mdx +++ b/fern/products/docs/pages/seo/configuring-slugs.mdx @@ -94,7 +94,7 @@ landing-page: ``` #### Override a page's slug -You can set the exact slug of a page within its frontmatter. [You can read more about the frontmatter configuration here](/learn/docs/configuration/page-level-settings#slug). +You can set the exact slug of a page within its frontmatter. [You can read more about the frontmatter configuration here](/learn/docs/content/frontmatter#slug). ```yaml title="docs.yml" navigation: diff --git a/fern/products/docs/pages/seo/metadata.mdx b/fern/products/docs/pages/seo/metadata.mdx deleted file mode 100644 index 5e84eedc..00000000 --- a/fern/products/docs/pages/seo/metadata.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Configure SEO metadata -description: Configure SEO metadata at the page or site level. ---- - -Optimize your documentation's search visibility and social media presence by configuring SEO metadata at the page or site level. Properly configured metadata helps search engines understand your content and creates compelling previews when your pages are shared on social platforms. - -When configuring SEO metadata, ensure your titles and descriptions are unique, descriptive, and relevant to the page content. Keep descriptions between 150-160 characters for optimal display in search results. - -## Page metadata - -Set SEO properties in each page's [frontmatter](/docs/configuration/page-level-settings) to control how individual pages appear in search results and social media shares. Page-level metadata takes precedence over site-wide settings. - -<Markdown src="/snippets/seo-metadata-page.mdx" /> - -## Website metadata - -Define default SEO properties for your entire documentation site in your [`docs.yml` file](/docs/configuration/what-is-docs-yml). These settings apply to all pages unless overridden by page-specific metadata. - -<Markdown src="/snippets/seo-metadata-site.mdx" /> diff --git a/fern/products/docs/pages/seo/redirects.mdx b/fern/products/docs/pages/seo/redirects.mdx index 3e5eef74..d17d9f66 100644 --- a/fern/products/docs/pages/seo/redirects.mdx +++ b/fern/products/docs/pages/seo/redirects.mdx @@ -14,8 +14,8 @@ The `redirects` object allows you to redirect traffic from one path to another. # Exact path redirects - source: "/old-path" destination: "/new-path" - - source: "/old-folder/path" - destination: "/new-folder/path" +- source: "/old-folder/path" +destination: "/new-folder/path" # Regex-based redirects - source: "/old-folder/:slug" # <- /old-folder/foo, /old-folder/bar, etc. diff --git a/fern/products/home/pages/welcome.mdx b/fern/products/home/pages/welcome.mdx index f0b45579..78aa7526 100644 --- a/fern/products/home/pages/welcome.mdx +++ b/fern/products/home/pages/welcome.mdx @@ -8,7 +8,7 @@ layout: custom import { FernFooter } from "../../../components/FernFooter"; -<div className="absolute inset-0 z-[-1] box-border block"> +{/* <div className="absolute inset-0 z-[-1] box-border block"> <div style={{ inset: 0, @@ -21,7 +21,7 @@ import { FernFooter } from "../../../components/FernFooter"; <div className="bg-gradient-blue-left box-border block" /> <div className="bg-gradient-green-right box-border block" /> <div className="bg-gradient-blue-right box-border block" /> -</div> +</div> */} <div className="lp-page-container"> {/* Main Content */} @@ -34,7 +34,7 @@ import { FernFooter } from "../../../components/FernFooter"; {/* Hero Section */} <div className="hero-section"> <div className="hero-title-container"> - <h1 className="hero-title"> + <h1 className="hero-title" data-state="closed"> Build with Fern </h1> <p className="hero-description"> @@ -133,7 +133,7 @@ import { FernFooter } from "../../../components/FernFooter"; {/* Rive Animation */} <a href="/docs/getting-started/overview" style="cursor: pointer; text-decoration: none;"> - <div class="rive-container fade-bottom"> + <div class="docs-rive rive-container fade-bottom"> <canvas id="docs-rive-canvas"></canvas> </div> </a> @@ -192,7 +192,7 @@ import { FernFooter } from "../../../components/FernFooter"; {/* Rive Animation */} <a href="/ask-fern/getting-started/what-is-ask-fern" style="cursor: pointer; text-decoration: none;"> - <div class="rive-container fade-bottom"> + <div class="ask-fern-rive rive-container fade-bottom"> <canvas id="ai-rive-canvas"></canvas> </div> </a> @@ -203,7 +203,7 @@ import { FernFooter } from "../../../components/FernFooter"; <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="dark:hidden" noZoom /> <img src="./images/arrow-right-black.svg" alt="Arrow right light" className="hidden dark:block" noZoom /> </a> - <a className="fern-button minimal normal gap-1 a-btn" href="/ask-fern/configuration/custom-prompts"> + <a className="fern-button minimal normal gap-1 a-btn" href="/ask-fern/configuration/custom-prompting"> Configure <img src="./images/arrow-right-black.svg" alt="Arrow right light" className="dark:hidden" noZoom /> <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="hidden dark:block" noZoom /> @@ -225,10 +225,12 @@ import { FernFooter } from "../../../components/FernFooter"; <div className="community-grid"> <div className="community-card"> - <img className="m-0 dark:hidden" src="./images/changelog-light.svg" alt="Changelog Preview" noZoom /> - <img className="m-0 hidden dark:block" src="./images/changelog-dark.svg" alt="Changelog Preview" noZoom /> + <div className="community-card-header"> + <img className="m-0 dark:hidden" src="./images/changelog-light.svg" alt="Changelog Preview" noZoom /> + <img className="m-0 hidden dark:block" src="./images/changelog-dark.svg" alt="Changelog Preview" noZoom /> - <h3 className="community-card-title">Changelog</h3> + <h3 className="community-card-title">Changelog</h3> + </div> <p className="community-card-description"> See our most recent product updates. </p> @@ -266,11 +268,13 @@ import { FernFooter } from "../../../components/FernFooter"; </div> </div> - <div className="community-card"> - <img className="m-0 dark:hidden" src="./images/github-light.svg" alt="Github Preview" noZoom/> - <img className="m-0 hidden dark:block" src="./images/github-dark.svg" alt="Github Preview" noZoom /> + <div className="community-card"> + <div className="community-card-header"> + <img className="m-0 dark:hidden" src="./images/github-light.svg" alt="Github Preview" noZoom/> + <img className="m-0 hidden dark:block" src="./images/github-dark.svg" alt="Github Preview" noZoom /> - <h3 className="community-card-title">Github</h3> + <h3 className="community-card-title">Github</h3> + </div> <p className="community-card-description"> Follow progress and contribute to the codebase. </p> @@ -280,10 +284,12 @@ import { FernFooter } from "../../../components/FernFooter"; </div> <div className="community-card"> - <img className="m-0 dark:hidden" src="./images/slack-light.svg" alt="Slack Preview" noZoom /> - <img className="m-0 hidden dark:block" src="./images/slack-dark.svg" alt="Slack Preview" noZoom /> + <div className="community-card-header"> + <img className="m-0 dark:hidden" src="./images/slack-light.svg" alt="Slack Preview" noZoom /> + <img className="m-0 hidden dark:block" src="./images/slack-dark.svg" alt="Slack Preview" noZoom /> - <h3 className="community-card-title">Slack</h3> + <h3 className="community-card-title">Slack</h3> + </div> <p className="community-card-description"> Connect with the Fern community. </p> @@ -293,12 +299,14 @@ import { FernFooter } from "../../../components/FernFooter"; </div> <div className="community-card"> - <img className="m-0 dark:hidden" src="./images/x-light.svg" alt="Twitter Preview" noZoom /> - <img className="m-0 hidden dark:block" src="./images/x-dark.svg" alt="Twitter Preview" noZoom /> + <div className="community-card-header"> + <img className="m-0 dark:hidden" src="./images/x-light.svg" alt="Twitter Preview" noZoom /> + <img className="m-0 hidden dark:block" src="./images/x-dark.svg" alt="Twitter Preview" noZoom /> - <h3 className="community-card-title"> - <span className="twitter-strikethrough">Twitter</span> X - </h3> + <h3 className="community-card-title"> + <span className="twitter-strikethrough">Twitter</span> X + </h3> + </div> <p className="community-card-description"> Get updates on the Fern platform. </p> diff --git a/fern/products/sdks/fern-folder.mdx b/fern/products/sdks/fern-folder.mdx index feaf0b92..2074a8ab 100644 --- a/fern/products/sdks/fern-folder.mdx +++ b/fern/products/sdks/fern-folder.mdx @@ -29,6 +29,6 @@ your API definitions, generators, and your CLI version. ### Next: Set up your repository structure - Now that you have your `fern` folder initialized, [learn how to organize your repositories for SDK generation](/sdks/overview/project-structure). + Now that you have your `fern` folder initialized, [learn how to organize your repositories for SDK generation](/sdks/overview/github). </Steps> diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx new file mode 100644 index 00000000..d9f3a4a8 --- /dev/null +++ b/fern/products/sdks/github-setup.mdx @@ -0,0 +1,160 @@ +--- +title: Project structure +description: An overview of the file and folder structure of a Fern SDKs project +--- + +Before generating SDKs with Fern, set up the proper GitHub repository structure to house your API definitions and SDK code so it's intuitive for you and your users to access, maintain, and update code. + +## Repository architecture + +Fern recommends a parent-child repository structure containing: + +- **Parent repository**: Contains your API definitions and SDK generation configuration +- **Child repositories**: Separate repositories for each SDK (TypeScript, Python, Go, etc.) + +```bash +├─ company-repo # Parent repository +│ └─ fern/ +│ ├─ fern.config.json +│ ├─ apis/ +│ │ └─ sdks/ +│ │ └─ generators.yml # References child repos +├─ typescript-sdk-repo # Child repository +├─ python-sdk-repo # Child repository +└─ go-sdk-repo # Child repository +``` + +This separation allows you to manage API definitions centrally while keeping each SDK in its own repository for independent versioning and distribution. + +<Info> + For an example of this structure, see Cohere's [fern folder](https://github.com/cohere-ai/cohere-developer-experience/tree/23d6c541a01eb6b54dd9bb3588c805bb0e307713/fern) and [TypeScript](https://github.com/cohere-ai/cohere-typescript) and [Python](https://github.com/cohere-ai/cohere-python) child repositories. +</Info> + +## Core configuration files + +[Initializing your `fern` folder](/sdks/overview/quickstart) creates two key configuration files: + +### `fern.config.json` + +This file stores your organization name and Fern CLI version: + +```json +{ + "organization": "your-organization", + "version": "<Markdown src="/products/sdks/snippets/fern-config-json-version.mdx"/>" +} +``` + +### `generators.yml` + +The `generators.yml` file specifies which SDKs to generate and where to publish them. It acts as the bridge between your API definitions and your SDK repositories. + +<Info> +For examples, see Cohere's [`generators.yml` +file](https://github.com/cohere-ai/cohere-developer-experience/blob/23d6c541a01eb6b54dd9bb3588c805bb0e307713/fern/apis/sdks/generators.yml) +and Vapi's [`generators.yml` +file](https://github.com/VapiAI/docs/blob/9c674c2b16ba03e864e26673c5290c88048c9a7a/fern/apis/api/generators.yml). +</Info> + + +<Info> + See the [`generators.yml` reference page](/sdks/reference/generators-yml) for complete configuration options. +</Info> + +## Parent repository structure + +The parent repository contains your API definitions and the `generators.yml` file that references your child SDK repositories. + +<CodeBlock title="Parent repository structure"> +```bash +company-repo/ +├─ fern/ +│ ├─ fern.config.json +│ ├─ apis/ +│ │ └─ sdks/ +│ │ └─ generators.yml # SDK generation configuration +``` +</CodeBlock> + +Your `generators.yml` file contains a group for each SDK and points to the corresponding child repository: + +```yaml title="generators.yml" +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/version-number-ts.mdx"/> + github: + repository: your-organization/typescript-sdk-repo + + python-sdk: + generators: + - name: fernapi/fern-python-sdk + version: <Markdown src="/snippets/version-number-python.mdx"/> + github: + repository: your-organization/python-sdk-repo +``` + +## Child repository structure + +Each SDK has its own repository with the following structure: + +<CodeBlock title="Child repository structure"> +```bash +typescript-sdk-repo/ # Individual SDK repository +├─ .github/workflows/ # Publishing workflows +├─ scripts/ +├─ src/ +├─ tests/ +└─ .fernignore # Files Fern shouldn't modify +``` +</CodeBlock> + +Fern generates most of these files automatically, including preserving any custom code you've added. + +## Setup instructions + +1. **Create repositories**: Set up your parent repository and one child repository for each SDK +2. **Install Fern GitHub App**: Install the [Fern GitHub App](https://github.com/apps/fern-api) on all repositories (parent and children) +3. **Configure generators.yml**: Add each child repository to your `generators.yml` file + +## Multiple API definitions + +For multiple APIs, organize them in separate folders within the `apis` directory: + +<Tabs> +<Tab title="OpenAPI Definition"> +```bash +fern/ + ├─ fern.config.json + ├─ generators.yml + └─ apis/ + └─ imdb/ + ├─ generators.yml + └─ openapi/ + ├─ openapi.yml + └─ disney/ + ├─ generators.yml + └─ openapi/ + ├─ openapi.yml +``` +</Tab> +<Tab title="Fern Definition"> +```bash +fern/ + ├─ fern.config.json + ├─ generators.yml + └─ apis/ + └─ imdb/ + ├─ generators.yml + └─ definition/ + ├─ api.yml + └─ imdb.yml + └─ disney/ + ├─ generators.yml + └─ definition/ + ├─ api.yml + └─ disney.yml +``` +</Tab> +</Tabs> \ No newline at end of file diff --git a/fern/products/sdks/guides/self-host-fern-generators.mdx b/fern/products/sdks/guides/self-host-fern-generators.mdx new file mode 100644 index 00000000..1cf63889 --- /dev/null +++ b/fern/products/sdks/guides/self-host-fern-generators.mdx @@ -0,0 +1,7 @@ +--- +title: Self host Fern's SDK generators +--- + +Fern supports self-hosting so that you can run Fern's SDK generators on your own infrastructure. + +<Warning>Docs are coming soon for this page.<br/><br/>Please [book a demo](https://buildwithfern.com/book-demo) or [reach out to us](https://buildwithfern.com/book-demo) to get set up with this feature. </Warning> diff --git a/fern/products/sdks/guides/self-hosted.mdx b/fern/products/sdks/guides/self-hosted.mdx deleted file mode 100644 index 1090861f..00000000 --- a/fern/products/sdks/guides/self-hosted.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Self-Hosted SDKs -description: Fern supports self-hosting SDK generation so that you can run SDK generation - on your own infrastructure. ---- - -<Note>Self-hosted SDK generation is only available for the enterprise plan.</Note> - -Fern SDK generation runs on Fern's infrastructure by default. Self-hosting allows you to run SDK generation on your own infrastructure to meet specific security or compliance requirements. - -## When to use self-hosting - -Self-hosting is typically required for organizations that operate without internet access, have strict compliance requirements, or need full control over their SDK generation process. - -When you self-host, you're responsible for server setup, security, maintenance, and deciding how to distribute your generated SDKs. Self-hosted SDK generation includes [all Fern SDK features](/learn/sdks/overview/capabilities). - -<Warning> -Unless you have specific requirements that prevent using Fern's default hosting, we recommend **using our managed cloud generation solution** for easier setup and maintenance. -</Warning> - -## How it works - -When you run `fern generate`, Fern uses Docker containers to execute SDK generation logic. By default, Fern runs **cloud generation** by allocating compute space and running the container remotely. With **self-hosted (local) generation**, you download and run the same Docker container on your own infrastructure. - -Both approaches generate partial SDK files to your configured output location, then Fern verifies your organization registration and completes the SDK by adding package distribution files. - -The self-hosted process works as follows: - -1. **Download the Docker image** - Fern provides the location of the most up-to-date Docker image containing the SDK generation logic -1. **Upload your fern folder** - Add your API definition and other configuration files to the container -1. **Run the container** - Execute SDK generation using standard Docker commands -1. **Partial SDK output** - Core SDK files are generated and saved to your configured output location (local file system, GitHub repository, package registry, etc.) -1. **Organization verification** - Fern verifies your organization registration and completes SDK generation by adding package distribution files like `pyproject.toml`, READMEs, and dependency configurations -1. **Receive updated Docker images** - Fern releases new versions of the Docker image that your team can evaluate and deploy when ready - -### Architecture diagram - -```mermaid -sequenceDiagram - autonumber - participant F as Fern - participant C as Customer - participant S as Customer Server - F->>C: Provides Docker image - C->>S: Uploads fern folder - C->>S: Runs Docker command - S->>S: Output partial SDK - F->>F: Checks organization registration - F->>S: Completes SDK generation - F->>C: Releases updated Docker image - C->>C: Evaluates new version - C->>S: Deploys updated image -``` \ No newline at end of file diff --git a/fern/products/sdks/introduction.mdx b/fern/products/sdks/introduction.mdx index 940a76e5..48a04b75 100644 --- a/fern/products/sdks/introduction.mdx +++ b/fern/products/sdks/introduction.mdx @@ -3,6 +3,50 @@ title: SDKs Overview description: Generate idiomatic SDKs in multiple programming languages --- +<style> + {` + .changelog-button { + display: flex; + padding: 0.25rem 0.5rem; + align-items: center; + justify-content: center; + border-radius: 0.5rem; + transition: background-color 0.15s ease-in-out; + position: relative; + height: 2rem; + text-decoration: none !important; + + img { + flex-shrink: 0; + width: 16px; + height: 16px; + position: relative; + } + + div { + font-size: 1rem; + white-space: nowrap; + max-width: 0; + opacity: 0; + overflow: hidden; + transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); + width: 0; + } + + &:hover { + gap: 0.25rem; + background-color: var(--grayscale-a3); + + div { + max-width: 200px; + opacity: 1; + width: fit-content; + } + } + } + `} +</style> + <div className="sdks-homepage"> {/* Dashed Pattern - Left Side */} <div className="dashed-pattern-left"> @@ -51,7 +95,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-python.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/python/changelog"> @@ -76,7 +120,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-go.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/go/changelog"> @@ -101,7 +145,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-java.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/java/changelog"> @@ -126,7 +170,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-csharp.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/csharp/changelog"> @@ -151,7 +195,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-php.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/php/changelog"> @@ -176,7 +220,7 @@ description: Generate idiomatic SDKs in multiple programming languages <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a10) text-body text-base font-light"> + <div class="text-(color:--grayscale-a12) text-body text-base font-light"> v<Markdown src="/snippets/version-number-ruby.mdx"/> </div> <a class="changelog-button text-(color:--grayscale-a12) text-body text-base font-light" href="/sdks/generators/ruby/changelog"> @@ -220,17 +264,12 @@ description: Generate idiomatic SDKs in multiple programming languages <div class="flex items-start flex-col space-y-3"> <img class="mx-auto dark:hidden" alt="Request Swift" src="./images/swift-card.png" /> <img class="mx-auto hidden dark:block" alt="Request Swift" src="./images/swift-card-dark.png" /> - <div class="w-full space-y-1 overflow-hidden flex justify-between items-center"> + <div class="w-full space-y-1 overflow-hidden"> <div class="text-(color:--grayscale-a12) text-body text-base font-semibold card-title"> Swift <img src="./images/arrow-right-black.svg" alt="Arrow right light" className="arrow-right dark:hidden m-0" noZoom /> <img src="./images/arrow-right-white.svg" alt="Arrow right light" className="arrow-right hidden dark:block m-0" noZoom /> </div> - <div class="flex items-center gap-2"> - <div class="text-(color:--grayscale-a12) text-body text-base font-light"> - v<Markdown src="/snippets/version-number-swift.mdx"/> - </div> - </div> </div> </div> </a> diff --git a/fern/products/sdks/overview/csharp/changelog/2025-05-01.mdx b/fern/products/sdks/overview/csharp/changelog/2025-05-01.mdx index 9c97e3d4..399275d5 100644 --- a/fern/products/sdks/overview/csharp/changelog/2025-05-01.mdx +++ b/fern/products/sdks/overview/csharp/changelog/2025-05-01.mdx @@ -1,4 +1,4 @@ ## 1.17.2 -**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. +**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. diff --git a/fern/products/sdks/overview/csharp/changelog/2025-08-04.mdx b/fern/products/sdks/overview/csharp/changelog/2025-08-04.mdx index 94ae8b70..7a43119e 100644 --- a/fern/products/sdks/overview/csharp/changelog/2025-08-04.mdx +++ b/fern/products/sdks/overview/csharp/changelog/2025-08-04.mdx @@ -1,6 +1,6 @@ ## 2.1.7 **`(fix):`** Improve generation so that all expected tests/samples correctly -generate and compile. +generate and compile. **`(fix):`** In `RawClient.cs` namespace references are prefixed with `global::` @@ -9,7 +9,7 @@ and client class are used that could cause it to collide. **`(fix):`** Set csharpier version to `1.1.*` to avoid inadvertently picking up -`1.0.3` which has an inconsistency in formatting. +`1.0.3` which has an inconsistency in formatting. ## 2.1.6 diff --git a/fern/products/sdks/overview/csharp/changelog/2025-08-18.mdx b/fern/products/sdks/overview/csharp/changelog/2025-08-18.mdx deleted file mode 100644 index 327808c4..00000000 --- a/fern/products/sdks/overview/csharp/changelog/2025-08-18.mdx +++ /dev/null @@ -1,10 +0,0 @@ -## 2.1.12 -**`(fix):`** Add support for configuration 'experimental-fully-qualified-namespaces' to -generate fully qualified typenames and namespaces. -Add support for `experimental-dotnet-format` to have `dotnet format` reduce -namespaces and namespace prefixes. (this can take a large amount of memory) -This creates code that is much cleaner, and can easily support -multiple endpoints with identical names in the generated code without -name or namespace collisions. - - diff --git a/fern/products/sdks/overview/csharp/changelog/2025-08-19.mdx b/fern/products/sdks/overview/csharp/changelog/2025-08-19.mdx deleted file mode 100644 index ceee15d6..00000000 --- a/fern/products/sdks/overview/csharp/changelog/2025-08-19.mdx +++ /dev/null @@ -1,5 +0,0 @@ -## 2.1.13 -**`(fix):`** Ensure `experimental-fully-qualified-namespaces` to have -'global::' prefix. - - diff --git a/fern/products/sdks/overview/csharp/changelog/2025-08-25.mdx b/fern/products/sdks/overview/csharp/changelog/2025-08-25.mdx deleted file mode 100644 index c9bb0cde..00000000 --- a/fern/products/sdks/overview/csharp/changelog/2025-08-25.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 2.1.15 -**`(fix):`** Ensure dynamic snippet method calls can use literal values - -## 2.1.14 -**`(fix):`** Create link in README.MD file to the REFERENCE.MD file - diff --git a/fern/products/sdks/overview/csharp/configuration.mdx b/fern/products/sdks/overview/csharp/configuration.mdx index 38d9dea7..3d61dce7 100644 --- a/fern/products/sdks/overview/csharp/configuration.mdx +++ b/fern/products/sdks/overview/csharp/configuration.mdx @@ -5,9 +5,16 @@ description: Configuration options for the Fern .NET SDK. You can customize the behavior of the C#/.NET SDK generator in `generators.yml`: +<<<<<<< HEAD +```yml {7-8} +default-group: local +groups: + local: +======= ```yml {6-7} title="generators.yml" groups: csharp-sdk: +>>>>>>> origin/main generators: - name: fernapi/fern-csharp-sdk version: <Markdown src="/snippets/version-number-csharp.mdx"/> @@ -18,77 +25,63 @@ groups: ## SDK configuration options <ParamField path="additional-properties" type="boolean" required={false} toc={true}> -When enabled, allows handling of additional properties not explicitly defined in the API specification. This provides flexibility for APIs that may include extra fields in responses. </ParamField> <ParamField path="base-api-exception-class-name" type="string" required={false} toc={true}> -Customizes the name of the base API exception class that all API-specific exceptions will inherit from. This allows you to define a custom base exception class name for better integration with your existing error handling patterns. </ParamField> <ParamField path="base-exception-class-name" type="string" required={false} toc={true}> -Specifies the name of the base exception class that all generated exceptions will inherit from. This provides a common parent class for all SDK exceptions, enabling consistent exception handling patterns. </ParamField> <ParamField path="client-class-name" type="string" required={false} toc={true}> -Sets the name of the generated API client class. This determines the primary client type name that users will interact with in the generated .NET SDK. </ParamField> <ParamField path="custom-pager-name" type="string" required={false} toc={true}> -Customizes the name of the pagination helper class used for handling paginated API responses. This allows you to specify a custom name that fits your naming conventions. </ParamField> <ParamField path="enable-forward-compatible-enums" type="boolean" required={false} toc={true}> -When enabled, generates enum types that can handle unknown values gracefully. This allows the SDK to process new enum values that may be added to the API without breaking existing client code, improving forward compatibility. </ParamField> <ParamField path="environment-class-name" type="string" required={false} toc={true}> -Specifies the name of the environment configuration class used for managing different API environments (e.g., development, staging, production). </ParamField> <ParamField path="explicit-namespaces" type="boolean" required={false} toc={true}> -When enabled, generates code with explicit namespace declarations throughout the SDK. This can help avoid naming conflicts and improve code clarity in larger projects. </ParamField> <ParamField path="exported-client-class-name" type="string" required={false} toc={true}> -Sets the name of the exported client class that will be used in code examples and documentation. This is useful for customizing how the client appears in generated documentation. </ParamField> <ParamField path="generate-error-types" type="boolean" required={false} toc={true}> -When enabled, generates specific error type classes for different API errors. This provides strongly-typed error handling instead of using generic exception types. </ParamField> <ParamField path="generate-mock-server-tests" type="boolean" required={false} toc={true}> -When enabled, generates mock server tests alongside the SDK code. This helps with testing and validation of the SDK functionality during development. </ParamField> <ParamField path="include-exception-handler" type="boolean" required={false} toc={true}> -When enabled, includes built-in exception handling utilities in the generated SDK. This provides convenience methods for common error handling scenarios. </ParamField> <ParamField path="inline-path-parameters" type="boolean" required={false} toc={true}> -When enabled, path parameters are included as properties in the request object instead of being passed as separate method parameters. This creates a more unified request structure where all parameters are grouped together. </ParamField> <ParamField path="namespace" type="string" required={false} toc={true}> -Specifies the root namespace for all generated .NET code. This determines the namespace hierarchy that users will import when using the SDK. </ParamField> +<<<<<<< HEAD +<ParamField path="package-id" type="string" required={false} toc={true}> +======= <ParamField path="package-name" type="string" required={false} toc={true}> Sets the NuGet package identifier for the generated SDK. This is used when publishing the SDK to NuGet or other package repositories. +>>>>>>> origin/main </ParamField> <ParamField path="read-only-memory-types" type="List<string>" required={false} toc={true}> -Specifies a list of types that should be generated using ReadOnlyMemory<T> instead of regular arrays or collections. This can improve performance for large data transfers by reducing memory allocations. </ParamField> <ParamField path="root-client-class-access" type="'public' | 'internal'" required={false} toc={true}> -Controls the access modifier for the root client class. Use 'public' to make the client accessible from other assemblies, or 'internal' to restrict access within the same assembly. </ParamField> <ParamField path="root-namespace-for-core-classes" type="boolean" required={false} toc={true}> -When enabled, places core SDK classes (like base client classes and utilities) in the root namespace instead of nested namespaces. This can simplify imports for commonly used types. </ParamField> <ParamField path="use-discriminated-unions" type="boolean" required={false} toc={true}> -When enabled, generates discriminated union types for API responses that can contain multiple different object types. This provides type-safe handling of polymorphic responses. </ParamField> \ No newline at end of file diff --git a/fern/products/sdks/overview/csharp/quickstart.mdx b/fern/products/sdks/overview/csharp/quickstart.mdx index 33cd7df2..c3f1d3b7 100644 --- a/fern/products/sdks/overview/csharp/quickstart.mdx +++ b/fern/products/sdks/overview/csharp/quickstart.mdx @@ -39,19 +39,11 @@ This command adds the following `group` to `generators.yml`: ``` ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group csharp-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group csharp-sdk --api your-api-name - ``` -</Note> + fern generate --group csharp-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/go/changelog/2025-05-01.mdx b/fern/products/sdks/overview/go/changelog/2025-05-01.mdx index 01ca7dd7..b1b6d50d 100644 --- a/fern/products/sdks/overview/go/changelog/2025-05-01.mdx +++ b/fern/products/sdks/overview/go/changelog/2025-05-01.mdx @@ -1,4 +1,4 @@ ## 0.37.3 -**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. +**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. diff --git a/fern/products/sdks/overview/go/changelog/2025-08-01.mdx b/fern/products/sdks/overview/go/changelog/2025-08-01.mdx index cf228108..c2296954 100644 --- a/fern/products/sdks/overview/go/changelog/2025-08-01.mdx +++ b/fern/products/sdks/overview/go/changelog/2025-08-01.mdx @@ -1,5 +1,5 @@ ## 1.5.4 -**`(fix):`** If enum values contain a slash, the go generator now effectively escapes these and makes sure that the +**`(fix):`** If enum values contain a slash, the go generator now effectively escapes these and makes sure that the Go SDK will still compile. diff --git a/fern/products/sdks/overview/go/changelog/2025-08-20.mdx b/fern/products/sdks/overview/go/changelog/2025-08-20.mdx deleted file mode 100644 index 137d6a3f..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-20.mdx +++ /dev/null @@ -1,12 +0,0 @@ -## 1.6.1 -**`(feat):`** Add reference.md doc generation - - -## 1.6.0 -**`(feat):`** Add support for specifying a custom subdirectory to generate into. - - -## 1.5.8 -**`(fix):`** Fix named string literals in undiscriminated unions. - - diff --git a/fern/products/sdks/overview/go/changelog/2025-08-21.mdx b/fern/products/sdks/overview/go/changelog/2025-08-21.mdx deleted file mode 100644 index 536cbf2a..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-21.mdx +++ /dev/null @@ -1,9 +0,0 @@ -## 1.6.3 -**`(fix):`** Update the dynamic snippet generator to handle list values in the request body. -Previously, it would throw an error. - - -## 1.6.2 -**`(feat):`** Add support for handling `default`s for query parameters. - - diff --git a/fern/products/sdks/overview/go/changelog/2025-08-22.mdx b/fern/products/sdks/overview/go/changelog/2025-08-22.mdx deleted file mode 100644 index 29cb9dbc..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-22.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 1.6.4-rc0 -**`(fix):`** Redesign the client to share RequestOptions across all subclients. - - diff --git a/fern/products/sdks/overview/go/changelog/2025-08-25.mdx b/fern/products/sdks/overview/go/changelog/2025-08-25.mdx deleted file mode 100644 index 28952589..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-25.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 1.6.5-rc0 -**`(fix):`** Fix certain instances of fmt.Sprintf'd values failing to be dereferenced. - - diff --git a/fern/products/sdks/overview/go/changelog/2025-08-26.mdx b/fern/products/sdks/overview/go/changelog/2025-08-26.mdx deleted file mode 100644 index 1d9bf799..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-26.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 1.6.6-rc0 -**`(fix):`** Fixes the ignoring of a default for `page` in pagination requests. - - diff --git a/fern/products/sdks/overview/go/changelog/2025-08-27.mdx b/fern/products/sdks/overview/go/changelog/2025-08-27.mdx deleted file mode 100644 index 2a401600..00000000 --- a/fern/products/sdks/overview/go/changelog/2025-08-27.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 1.6.7 -**`(fix):`** Removes legacy logic for flat package layout. - - diff --git a/fern/products/sdks/overview/go/configuration.mdx b/fern/products/sdks/overview/go/configuration.mdx index 9630d443..6497a41b 100644 --- a/fern/products/sdks/overview/go/configuration.mdx +++ b/fern/products/sdks/overview/go/configuration.mdx @@ -5,7 +5,12 @@ description: Configuration options for the Fern Go SDK. You can customize the behavior of the Go SDK generator in `generators.yml`: +<<<<<<< HEAD +```yaml {7-8} +default-group: local +======= ```yaml {6-7} title="generators.yml" +>>>>>>> origin/main groups: go-sdk: generators: @@ -21,19 +26,15 @@ groups: ## SDK Configuration Options <ParamField path="alwaysSendRequiredProperties" type="boolean" required={false} toc={true}> -When enabled, ensures that all required properties are always included in API requests, even if they have default values or are otherwise optional in the implementation. </ParamField> <ParamField path="clientConstructorName" type="string" required={false} toc={true}> -Customizes the name of the client constructor function. This allows you to specify a custom name for the function that users will call to create a new instance of the client. </ParamField> <ParamField path="clientName" type="string" required={false} toc={true}> -Specifies the name of the generated client struct. This determines the primary client type name that users will interact with in the generated Go SDK. </ParamField> <ParamField path="exportedClientName" type="string" required={false} toc={true}> -Sets the name of the exported client that will be used in code snippets and documentation examples. This is useful for customizing how the client appears in generated documentation. </ParamField> <ParamField path="importPath" type="string" required={false} toc={true}> @@ -63,18 +64,15 @@ with the relevant elements in your `go.mod` path. In this case, the generated Go </ParamField> <ParamField path="includeLegacyClientOptions" type="boolean" required={false} toc={true}> -When enabled, includes legacy client options for backward compatibility with older versions of the SDK. This is useful for maintaining compatibility when upgrading SDK versions. </ParamField> <ParamField path="inlineFileProperties" type="boolean" required={false} toc={true}> -Controls whether file upload properties are generated as inline request properties instead of separate parameters. When enabled, file upload fields become part of the request struct rather than being passed as individual function parameters. </ParamField> <ParamField path="inlinePathParameters" type="boolean" required={false} toc={true}> -When enabled, path parameters are inlined into request types rather than being passed as separate function parameters. This creates a more unified request structure where path parameters are included in the request object. </ParamField> -<ParamField path="module" type="object" required={false} toc={true}> +<ParamField path="module" type="ModuleConfigSchema" required={false} toc={true}> Use this option if you plan to distribute the generated Go SDK as a separate, published Go module. <Note>If you only plan to use the generated SDK within your own Go module, use the `importPath` configuration option instead.</Note> @@ -133,17 +131,13 @@ replace "github.com/your/sdk" v0.0.0 => "path/to/generated/sdk" </ParamField> <ParamField path="packageLayout" type="'flat' | 'nested'" required={false} toc={true}> -Controls the organization of the generated package structure. Choose 'flat' for a flatter package structure with fewer nested directories, or 'nested' for a more hierarchical organization that mirrors your API structure. </ParamField> <ParamField path="packageName" type="string" required={false} toc={true}> -Specifies the package name for the generated Go code. This determines the package declaration that will appear at the top of generated Go files and affects how users import the SDK. </ParamField> <ParamField path="union" type="'v0' | 'v1'" required={false} toc={true}> -Controls the union type generation strategy. Use 'v0' for the legacy union implementation or 'v1' for the newer, more robust union handling approach that provides better type safety and discriminated union support. </ParamField> <ParamField path="useReaderForBytesRequest" type="boolean" required={false} toc={true}> -When enabled, uses `io.Reader` interface for handling byte request bodies instead of byte slices. This is more memory-efficient for large payloads and follows Go best practices for streaming data. </ParamField> \ No newline at end of file diff --git a/fern/products/sdks/overview/go/quickstart.mdx b/fern/products/sdks/overview/go/quickstart.mdx index 997629ee..a2a92058 100644 --- a/fern/products/sdks/overview/go/quickstart.mdx +++ b/fern/products/sdks/overview/go/quickstart.mdx @@ -39,19 +39,11 @@ This command adds the following `group` to `generators.yml`: ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group go-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group go-sdk --api your-api-name - ``` -</Note> + fern generate --group go-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/java/changelog/2025-05-01.mdx b/fern/products/sdks/overview/java/changelog/2025-05-01.mdx index 4e9e3dc8..5933cb62 100644 --- a/fern/products/sdks/overview/java/changelog/2025-05-01.mdx +++ b/fern/products/sdks/overview/java/changelog/2025-05-01.mdx @@ -1,9 +1,9 @@ ## 2.35.3 -**`(fix):`** Rerelease with the latest generator-cli. +**`(fix):`** Rerelease with the latest generator-cli. ## 2.35.2 -**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. +**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. ## 2.35.1 diff --git a/fern/products/sdks/overview/java/changelog/2025-07-18.mdx b/fern/products/sdks/overview/java/changelog/2025-07-18.mdx index 4e67c0f5..306a9fc7 100644 --- a/fern/products/sdks/overview/java/changelog/2025-07-18.mdx +++ b/fern/products/sdks/overview/java/changelog/2025-07-18.mdx @@ -1,4 +1,4 @@ ## 2.38.5 -**`(chore):`** Remove internal OkHttp utility dependency and use a more robust file closing method. +**`(chore):`** Remove internal OkHttp utility dependency and use a more robust file closing method. diff --git a/fern/products/sdks/overview/java/changelog/2025-08-15.mdx b/fern/products/sdks/overview/java/changelog/2025-08-15.mdx deleted file mode 100644 index 8d563482..00000000 --- a/fern/products/sdks/overview/java/changelog/2025-08-15.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 2.41.1 -**`(fix):`** Fix integer overflow when processing OpenAPI specs with large integer values in examples. Values exceeding Java's Integer range are automatically converted to long type to prevent generation failures. - - diff --git a/fern/products/sdks/overview/java/changelog/2025-08-19.mdx b/fern/products/sdks/overview/java/changelog/2025-08-19.mdx deleted file mode 100644 index 96b36417..00000000 --- a/fern/products/sdks/overview/java/changelog/2025-08-19.mdx +++ /dev/null @@ -1,9 +0,0 @@ -## 2.41.3 -**`(feat):`** Add convenient `addHeader()` method to SDK builders for adding custom headers without requiring -OkHttpClient customization or inheritance. - - -## 2.41.2 -**`(feat):`** Link reference.md in the README.md. - - diff --git a/fern/products/sdks/overview/java/changelog/2025-08-25.mdx b/fern/products/sdks/overview/java/changelog/2025-08-25.mdx deleted file mode 100644 index 1ff5b39a..00000000 --- a/fern/products/sdks/overview/java/changelog/2025-08-25.mdx +++ /dev/null @@ -1,11 +0,0 @@ -## 2.42.0 -**`(feat):`** Add support for semantic distinction between `nullable<T>` and `optional<T>` types via `use-nullable-annotation` flag. -When enabled, `nullable<T>` generates as raw type `T` with `@Nullable` annotation, while `optional<T>` remains as `Optional<T>`. -This provides proper API semantics for fields that can be null vs those that may be absent from requests. - -```yaml -customConfig: - use-nullable-annotation: true -``` - - diff --git a/fern/products/sdks/overview/java/changelog/2025-08-27.mdx b/fern/products/sdks/overview/java/changelog/2025-08-27.mdx deleted file mode 100644 index 9e7a39fc..00000000 --- a/fern/products/sdks/overview/java/changelog/2025-08-27.mdx +++ /dev/null @@ -1,5 +0,0 @@ -## 2.42.1 -**`(fix):`** Fix nullable fields incorrectly requiring non-null values in staged builders when -use-nullable-annotation is enabled. - - diff --git a/fern/products/sdks/overview/java/configuration.mdx b/fern/products/sdks/overview/java/configuration.mdx index 5f38e12e..4285bb2b 100644 --- a/fern/products/sdks/overview/java/configuration.mdx +++ b/fern/products/sdks/overview/java/configuration.mdx @@ -4,7 +4,12 @@ description: Configuration options for the Fern Java SDK. --- You can customize the behavior of the Java SDK generator in `generators.yml`: +<<<<<<< HEAD +```yaml {7-9} +default-group: local +======= ```yaml {7-9} title="generators.yml" +>>>>>>> origin/main groups: java-sdk: generators: @@ -17,11 +22,9 @@ groups: ## SDK Configuration Options <ParamField path="base-api-exception-class-name" type="string" required={false} toc={true}> -Customizes the name of the base API exception class that all API-specific exceptions will extend. This allows you to define a custom base exception class name for better integration with your existing error handling patterns. </ParamField> <ParamField path="base-exception-class-name" type="string" required={false} toc={true}> -Specifies the name of the base exception class that all generated exceptions will inherit from. This provides a common parent class for all SDK exceptions, enabling consistent exception handling patterns. </ParamField> <ParamField path="client-class-name" type="string" default="<Organization>ApiClient" required={false} toc={true}> @@ -43,7 +46,6 @@ Example: </ParamField> <ParamField path="disable-required-property-builder-checks" type="boolean" default="false" required={false} toc={true}> -When enabled, disables validation checks in builder patterns for required properties. This removes compile-time checks that ensure all required fields are set before building an object, providing more flexibility but less safety. </ParamField> <ParamField path="enable-extensible-builders" type="boolean" default="false" required={false} toc={true}> @@ -52,11 +54,9 @@ When enabled, generates extensible builder classes that support customization th </ParamField> <ParamField path="enable-forward-compatible-enums" type="boolean" default="false" required={false} toc={true}> -When enabled, generates enum classes that can handle unknown values gracefully. This allows the SDK to process new enum values that may be added to the API without breaking existing client code, improving forward compatibility. </ParamField> <ParamField path="enable-inline-types" type="boolean" default="false" required={false} toc={true}> -When enabled, generates inline types for nested schemas instead of creating separate classes. This results in cleaner type definitions where nested objects are defined within their parent types, reducing the number of generated files. </ParamField> <ParamField path="enable-public-constructors" type="boolean" default="false" required={false} toc={true}> @@ -65,23 +65,18 @@ When enabled, generates public constructors for model types. </ParamField> <ParamField path="generate-unknown-as-json-node" type="boolean" default="false" required={false} toc={true}> -When enabled, generates unknown or untyped properties as structured JSON objects instead of raw Object types. This provides better type safety and easier manipulation of dynamic JSON content while maintaining flexibility for unknown data structures. </ParamField> <ParamField path="inline-file-properties" type="boolean" default="false" required={false} toc={true}> -Controls whether file upload properties are generated as inline request properties instead of separate method parameters. When enabled, file fields become part of the request object rather than being passed as individual function arguments. </ParamField> <ParamField path="inline-path-parameters" type="boolean" default="false" required={false} toc={true}> -When enabled, path parameters are included as properties in the request object instead of being passed as separate method parameters. This creates a more unified request structure where all parameters are grouped together. </ParamField> <ParamField path="json-include" type="'non-empty' | 'non-absent'" default="non-absent" required={false} toc={true}> -Controls Jackson's JSON serialization behavior for optional fields. Use 'non-empty' to exclude null and empty values, or 'non-absent' to only exclude null values while preserving empty collections and strings. </ParamField> <ParamField path="package-layout" type="'nested' | 'flat'" default="nested" required={false} toc={true}> -Determines the organization of generated Java packages. Choose 'nested' for a hierarchical package structure that mirrors your API organization, or 'flat' for a simpler structure with fewer nested packages. </ParamField> <ParamField path="package-prefix" type="string" required={false} toc={true}> @@ -94,7 +89,6 @@ config: </ParamField> <ParamField path="publish-to" type="'central' | 'ossrh'" required={false} toc={true}> -Publish target for Maven packages. Use `central` for Maven Central Portal or `ossrh` for legacy Nexus Repository. </ParamField> <ParamField path="wrapped-aliases" type="boolean" default="false" required={false} toc={true}> @@ -123,17 +117,12 @@ If you want to customize how your publishing metadata looks in your ``` <ParamField path="author" type="string" required={false} toc={true}> -Specifies the author name that will appear in the generated package metadata and build configuration files. </ParamField> <ParamField path="email" type="string" required={false} toc={true}> -Sets the contact email address for the package author that will be included in the generated package metadata. </ParamField> <ParamField path="license" type="'MIT' | 'Apache-2.0' | { custom: 'Custom License Name' }" required={false} toc={true}> -Defines the software license for the generated SDK. Choose from standard licenses like 'MIT' or 'Apache-2.0', or specify a custom license name. </ParamField> <ParamField path="package-description" type="string" required={false} toc={true}> -Provides a description of the SDK package that will appear in package metadata and documentation. This helps users understand what the SDK is for and its purpose. </ParamField> <ParamField path="reference-url" type="string" required={false} toc={true}> -Sets the reference URL (typically the API documentation or project website) that will be included in the package metadata for users to find additional information. </ParamField> \ No newline at end of file diff --git a/fern/products/sdks/overview/java/publishing-to-maven-central.mdx b/fern/products/sdks/overview/java/publishing-to-maven-central.mdx index e6142c7e..790760c8 100644 --- a/fern/products/sdks/overview/java/publishing-to-maven-central.mdx +++ b/fern/products/sdks/overview/java/publishing-to-maven-central.mdx @@ -15,28 +15,25 @@ page, you'll have a versioned package published on Maven Central. <Step title="Configure `output` location"> - Change the output location in `generators.yml` from `local-file-system` (the default) to `maven` to indicate that Fern should publish your package directly to the Maven Central registry. - - Then, add `publish-to: central` to indicate that the publish target is the new Maven Central Portal (Sonatype). To publish to the legacy Nexus Repository, use `publish-to: ossrh`. - - ```yaml {6-9} title="generators.yml" - groups: - java-sdk: - generators: - - name: fernapi/fern-java-sdk - version: <Markdown src="/snippets/version-number-java.mdx"/> - output: - location: maven - config: - publish-to: central - ``` + Next, change the output location in `generators.yml` from `local-file-system` (the default) to `maven` to indicate that Fern should publish your package directly to the Maven Central registry: + + ```yaml {6-7} + groups: + java-sdk: + generators: + - name: fernapi/fern-java-sdk + version: <Markdown src="/snippets/version-number-java.mdx"/> + output: + location: maven + + ``` </Step> <Step title="Add repository location"> - Add the path to your GitHub repository. + Add the path to your GitHub repository to `generators.yml`: -```yaml {10-11} title="generators.yml" +```yaml {8-9} groups: java-sdk: generators: @@ -44,8 +41,6 @@ groups: version: <Markdown src="/snippets/version-number-java.mdx"/> output: location: maven - config: - publish-to: central github: repository: your-org/company-java ``` @@ -66,15 +61,17 @@ groups: <Step title="Verify your namespace"> 1. Click on your username, then select **View Namespaces**. Click **Register New Namespace**. - 1. Enter your company website or GitHub account in reverse domain name format and go through the verification process. + 1. Enter your company website or GitHub account in reverse domain name format and go through the + verification process. </Step> <Step title="Configure Maven Coordinate"> - Add the namespace you just verified in Maven Central to the `coordinate` field. This specifies how your Java SDK will be + Add the namespace you just verified in Maven Central to the `coordinate: + groupId:artifactId` field. This specifies how your Java SDK will be published and referenced in the Maven Central respository. - ```yaml {8} title="generators.yml" + ```yaml {8} groups: java-sdk: generators: @@ -82,9 +79,7 @@ groups: version: <Markdown src="/snippets/version-number-java.mdx"/> output: location: maven - coordinate: com.company:sdk-name # groupId:artifactId - config: - publish-to: central + coordinate: com.company:sdk-name # <company name in reverse domain name format>:<SDK name> github: repository: your-org/company-java ``` @@ -106,7 +101,7 @@ groups: Add `username: ${MAVEN_USERNAME}` and `password: ${MAVEN_PASSWORD}` to `generators.yml` to tell Fern to use the `MAVEN_USERNAME` and `MAVEN_PASSWORD` environment variable for authentication when publishing to the Maven Central registry. -```yaml {9-10} title="generators.yml" +```yaml {9-10} groups: java-sdk: generators: @@ -117,8 +112,6 @@ groups: coordinate: com.company:sdk-name username: ${MAVEN_USERNAME} password: ${MAVEN_PASSWORD} - config: - publish-to: central github: repository: your-org/company-java ``` @@ -162,7 +155,7 @@ Export your key so you can store it in an environment variable later on: Add the `keyId`, `password`, and `secretKey` from the previous step to `generators.yml`: -```yaml {11-14} title="generators.yml" +```yaml {11-14} groups: java-sdk: generators: @@ -177,8 +170,6 @@ groups: keyId: ${MAVEN_SIGNATURE_SECRET_KEY_ID} password: ${MAVEN_SIGNATURE_PASSWORD} secretKey: ${MAVEN_SIGNATURE_SECRET_KEY} - config: - publish-to: central github: repository: your-org/company-java ``` diff --git a/fern/products/sdks/overview/java/quickstart.mdx b/fern/products/sdks/overview/java/quickstart.mdx index 812c40f8..7505b824 100644 --- a/fern/products/sdks/overview/java/quickstart.mdx +++ b/fern/products/sdks/overview/java/quickstart.mdx @@ -39,19 +39,11 @@ This command adds the following `group` to `generators.yml`: ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group java-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group java-sdk --api your-api-name - ``` -</Note> + fern generate --group java-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/mcp-server/introduction.mdx b/fern/products/sdks/overview/mcp-server/introduction.mdx index bb068e86..c6052c4d 100644 --- a/fern/products/sdks/overview/mcp-server/introduction.mdx +++ b/fern/products/sdks/overview/mcp-server/introduction.mdx @@ -1,17 +1,26 @@ --- -title: MCP server for your API +title: Model Context Protocol description: Learn how to use the Model Context Protocol (MCP) to integrate AI capabilities with your Fern documentation --- -<Markdown src="/snippets/wip-callout.mdx" /> +<Tip> +**Looking for Fern's own MCP server?** If you want to connect your AI client to Fern's MCP server for help with Ask Fern, Docs, and SDKs, see the [fern-mcp-server repository](https://github.com/fern-api/fern-mcp-server). This page describes how Fern can help you build an MCP server for your own API. +</Tip> -[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard by Anthropic that enables AI applications to connect with external data sources and tools. +[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard by Anthropic that streamlines how AI applications connect with external data sources and tools, enabling AI agents to directly use your product’s APIs. + +A “Built with Fern” MCP server augments your existing TypeScript SDK with MCP capabilities and integrates seamlessly with popular AI-powered tools including Cursor, Claude Desktop, and Windsurf. You can find a full list of MCP clients [here](https://modelcontextprotocol.io/clients). + +<Note> +The MCP generator is in development. Interested in offering an MCP server for your API? Reach out via Slack or support@buildwithfern.com. +</Note> -Fern can generate a production-ready MCP server that augments your existing SDK. Developers can then interact with your API directly through AI clients (like Claude Desktop, Cursor, and Windsurf). ## How it works -Fern generates an MCP server on top of your existing SDK and maintains it in its own repository. Developers can install your MCP server by adding a configuration snippet to their AI client: +**Fern can build a production-ready MCP server on top of your existing TypeScript SDK.** We maintain the package in its own `git` repository, making it easy for your existing developer community to discover and contribute to the project. We can also automatically publish new versions of the package to `npm` for you. + +End users of a “Built with Fern” MCP server can typically get started with a **single config**: ```json { @@ -25,8 +34,36 @@ Fern generates an MCP server on top of your existing SDK and maintains it in its ``` -## Example: Webflow +To learn more about Model Context Protocol (MCP) servers, check out the [MCP server docs](https://modelcontextprotocol.io/quickstart/server). + +## Case study: Webflow + +**We worked with Webflow to launch their [official MCP server](https://www.npmjs.com/package/webflow-mcp-server)** using the existing [Fern-generated TypeScript SDK](https://github.com/webflow/js-webflow-api). + +Check out the [source code on GitHub](https://github.com/webflow/mcp-server) and read the announcement from Webflow’s CTO on X: + +<blockquote class="twitter-tweet"><p lang="en" dir="ltr">🚢 We just launched our Webflow MCP server! Check out Allan’s thread to learn more, watch the demo video below, then give it a try here: <a href="https://t.co/T2K3OpJ6O8">https://t.co/T2K3OpJ6O8</a> <a href="https://t.co/bFUfC64pcf">https://t.co/bFUfC64pcf</a> <a href="https://t.co/oonYuyjHiT">pic.twitter.com/oonYuyjHiT</a></p>— Webflow (@webflow) <a href="https://twitter.com/webflow/status/1907465818088054843?ref_src=twsrc%5Etfw">April 2, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> + +## Why "Built with Fern"? + +There are a few advantages in partnering with Fern to build your MCP server: + +- **Keep your MCP server in sync with your API** - our implementation augments your existing TypeScript SDK. +- **Integrate with Fern Docs and AI Chat** - give your users the ability to query your docs directly from inside of Cursor, Claude Desktop, and more. +- **For APIs at scale** - leverage our team’s expertise developing, testing, and deploying MCP servers for products with hundreds of API endpoints. +- **Thought partnership** - the AI ecosystem is changing fast and we’re here to navigate it together with you, from the latest techniques to the tools that power them. + +## How else can Fern support my MCP server launch? + +We can provide **ready-to-use social media assets** for announcing your MCP support: -Webflow launched their [official MCP server](https://www.npmjs.com/package/webflow-mcp-server) using their existing [Fern-generated TypeScript SDK](https://github.com/webflow/js-webflow-api). You can view the [source code on GitHub](https://github.com/webflow/mcp-server). +- LinkedIn post template +- X (Twitter) post template +- Email announcement template +- Social media graphics +As well as all of the **detailed documentation** that you’ve come to expect from Fern: +- Getting started guide +- API reference +- Usage guidelines and best practices diff --git a/fern/products/sdks/overview/php/changelog/2025-08-27.mdx b/fern/products/sdks/overview/php/changelog/2025-08-27.mdx deleted file mode 100644 index c2829e6d..00000000 --- a/fern/products/sdks/overview/php/changelog/2025-08-27.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 1.16.8 -**`(fix):`** Fixed semver for changelog validation. - diff --git a/fern/products/sdks/overview/php/configuration.mdx b/fern/products/sdks/overview/php/configuration.mdx index 78de344f..a1f1df8f 100644 --- a/fern/products/sdks/overview/php/configuration.mdx +++ b/fern/products/sdks/overview/php/configuration.mdx @@ -5,7 +5,12 @@ description: Configuration options for the Fern PHP SDK. You can customize the behavior of the PHP SDK generator in `generators.yml`: +<<<<<<< HEAD +```yaml {7-8} +default-group: local +======= ```yaml {7-8} title="generators.yml" +>>>>>>> origin/main groups: php-sdk: generators: @@ -18,29 +23,22 @@ groups: ## SDK Configuration Options <ParamField path="clientName" type="string" required={false} toc={true}> -Sets the name of the generated API client class. This determines the primary client type name that users will interact with in the generated PHP SDK. </ParamField> <ParamField path="composerJson" type="Record<string, any>" required={false} toc={true}> -Allows customization of the generated `composer.json` file contents. You can specify additional metadata, dependencies, or configuration that will be merged into the package's composer configuration file. </ParamField> <ParamField path="inlinePathParameters" type="boolean" required={false} toc={true}> -When enabled, path parameters are included as properties in the request class instead of being passed as separate method parameters. This creates a more unified request structure where all parameters are grouped together in the request object. </ParamField> <ParamField path="namespace" type="string" required={false} toc={true}> -Specifies the PHP namespace for all generated code. This determines the namespace hierarchy that users will use when importing and using the SDK classes. </ParamField> <ParamField path="packageName" type="string" required={false} toc={true}> -Sets the name of the PHP package as it will appear in Composer and Packagist. This is the name users will use to install the SDK via Composer (e.g., `composer require your/package-name`). </ParamField> <ParamField path="packagePath" type="string" required={false} toc={true}> -Specifies the directory path where the generated SDK source files should be placed. This determines the file system location of the generated PHP code relative to the output directory. </ParamField> <ParamField path="propertyAccess" type="'public' | 'private'" required={false} toc={true}> -Controls the access level of generated class properties. When set to 'public', properties are public and getter/setter methods are omitted. When set to 'private', properties are private and getter/setter methods are generated for encapsulation. </ParamField> \ No newline at end of file diff --git a/fern/products/sdks/overview/php/quickstart.mdx b/fern/products/sdks/overview/php/quickstart.mdx index 784dfe40..d68e46c1 100644 --- a/fern/products/sdks/overview/php/quickstart.mdx +++ b/fern/products/sdks/overview/php/quickstart.mdx @@ -40,19 +40,11 @@ This command adds the following `group` to `generators.yml`: ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group php-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group php-sdk --api your-api-name - ``` -</Note> + fern generate --group php-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/postman/publishing-to-postman.mdx b/fern/products/sdks/overview/postman/publishing-to-postman.mdx deleted file mode 100644 index 014c4f7c..00000000 --- a/fern/products/sdks/overview/postman/publishing-to-postman.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Publishing to Postman -description: Publish a Postman collection full of example requests and responses ---- - -Publish your Postman collection directly to Postman workspaces, making it easy for your team and API consumers to discover and test your endpoints. - -## Publish directly to Postman - -To publish your collection directly to Postman, configure the output and specify the name of your collection: - -```yaml title="generators.yml" {6-9} -groups: - postman: - generators: - - name: fernapi/fern-postman - version: 0.4.0 - output: - location: postman - api-key: ${POSTMAN_API_KEY} - workspace-id: 07e228e5-3f91-4223-8e27-bbfe4a81a601 - config: - collection-name: My collection name -``` - -## Publish to a collection - -To publish to a particular collection, configure the output and specify the name of your collection and collection ID: - -```yaml title="generators.yml" {10} -groups: - postman: - generators: - - name: fernapi/fern-postman - version: 0.4.0 - output: - location: postman - api-key: ${POSTMAN_API_KEY} - workspace-id: 07e228e5-3f91-4223-8e27-bbfe4a81a601 - collection-id: 21510182-14b07230-46e2-431e-8153-d5c7d217b214 - config: - collection-name: My collection name -``` - - - diff --git a/fern/products/sdks/overview/postman/quickstart.mdx b/fern/products/sdks/overview/postman/quickstart.mdx deleted file mode 100644 index ba9bee6e..00000000 --- a/fern/products/sdks/overview/postman/quickstart.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Postman quickstart -description: "Generate a postman collection full of example requests and responses" ---- - -A Postman collection contains ready-to-use HTTP requests with example payloads and responses that developers can immediately test and explore in Postman. Each API definition generates one complete collection with all endpoints organized into folders. - -Generate a Postman collection by following the instructions on this page. - -<Info> - This page assumes that you have an initialized `fern` folder on your local - machine. See [Set up the `fern` folder](/sdks/overview/quickstart). -</Info> - -<Steps> - -<Markdown src="/products/sdks/snippets/pass-fern-check.mdx"/> - -### Add the Postman generator - -Run the following command to add the Postman generator to `generators.yml`: - -```sh -fern add fern-postman --group postman -``` - -<Note> - `postman` is the name of the `generators.yml` group that configures your Postman collection's output location and other metadata. You can customize this group name to differentiate between multiple collections if you have multiple APIs in your organization. -</Note> - -This command adds the following `group` to `generators.yml`: - -```yaml title="generators.yml" {2-8} -groups: - postman: - generators: - - name: fernapi/fern-postman - version: 0.0.45 - output: - location: local-file-system - path: ../postman -``` - -### Generate the collection - -Run the following command: - -```sh -fern generate --group postman -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: - - ```bash - fern generate --group postman --api your-api-name - ``` -</Note> - -This creates a Postman collection on Fern's cloud. Once complete, you'll see a `collection.json`: - -```bash {4-5} -fern/ - ├─ fern.config.json - ├─ generators.yml -postman - ├─ collection.json -``` -</Steps> \ No newline at end of file diff --git a/fern/products/sdks/overview/python/changelog/2025-03-28.mdx b/fern/products/sdks/overview/python/changelog/2025-03-28.mdx index ccba8243..236d4291 100644 --- a/fern/products/sdks/overview/python/changelog/2025-03-28.mdx +++ b/fern/products/sdks/overview/python/changelog/2025-03-28.mdx @@ -1,4 +1,4 @@ ## 4.5.0 -**`(feat):`** Add support for websocket code generation. +**`(feat):`** Add support for websocket code generation. diff --git a/fern/products/sdks/overview/python/changelog/2025-05-01.mdx b/fern/products/sdks/overview/python/changelog/2025-05-01.mdx index 8859cdec..ddb420bd 100644 --- a/fern/products/sdks/overview/python/changelog/2025-05-01.mdx +++ b/fern/products/sdks/overview/python/changelog/2025-05-01.mdx @@ -1,4 +1,4 @@ ## 4.18.3 -**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. +**`(fix):`** Install the generator-cli at build time as a fallback if runtime installation fails. diff --git a/fern/products/sdks/overview/python/changelog/2025-08-20.mdx b/fern/products/sdks/overview/python/changelog/2025-08-20.mdx deleted file mode 100644 index a2823cb5..00000000 --- a/fern/products/sdks/overview/python/changelog/2025-08-20.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 4.26.1 -**`(chore):`** Additional handling of inferred auth - -## 4.26.0 -**`(chore):`** Bumped IR version to 59. - diff --git a/fern/products/sdks/overview/python/changelog/2025-08-26.mdx b/fern/products/sdks/overview/python/changelog/2025-08-26.mdx deleted file mode 100644 index ce646045..00000000 --- a/fern/products/sdks/overview/python/changelog/2025-08-26.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 4.26.2 -**`(fix):`** Upgrade docker image to use python 3.11.13 so that users can depend on packages that require python 3.11. - - diff --git a/fern/products/sdks/overview/python/changelog/2025-08-27.mdx b/fern/products/sdks/overview/python/changelog/2025-08-27.mdx deleted file mode 100644 index 4ec5bea8..00000000 --- a/fern/products/sdks/overview/python/changelog/2025-08-27.mdx +++ /dev/null @@ -1,6 +0,0 @@ -## 4.27.0-rc0 -**`(feat):`** Client imports are now lazy loaded by default. This will greatly reduce memory footprint when using a small portion of a large API. -The tradeoff is a latency penalty when first accessing a client. -Users can opt in to eager loading (the old behavior) by setting the `lazy_imports` flag to `false` in their configuration. - - diff --git a/fern/products/sdks/overview/python/configuration.mdx b/fern/products/sdks/overview/python/configuration.mdx index ff8b415f..73940a3b 100644 --- a/fern/products/sdks/overview/python/configuration.mdx +++ b/fern/products/sdks/overview/python/configuration.mdx @@ -5,7 +5,12 @@ description: Configuration options for the Fern Python SDK. You can customize the behavior of the Python SDK generator in `generators.yml`: +<<<<<<< HEAD +```yaml {7-16} +default-group: local +======= ```yaml {6-15} title="generators.yml" +>>>>>>> origin/main groups: python-sdk: generators: @@ -19,7 +24,7 @@ groups: - from: file_with_custom_function imports: - custom_function - pydantic_config: + pydantic-config: skip_validation: true ``` @@ -192,13 +197,13 @@ When enabled, includes the API name as part of the package structure and naming. The name of the exported client class that will be used in code snippets. </ParamField> -### pydantic_config +### pydantic-config Configure Pydantic model generation settings for your Python SDK. ```yaml config: - pydantic_config: + pydantic-config: enum_type: "literals" extra_fields: "forbid" frozen: true diff --git a/fern/products/sdks/overview/python/quickstart.mdx b/fern/products/sdks/overview/python/quickstart.mdx index b4e53da0..7febf018 100644 --- a/fern/products/sdks/overview/python/quickstart.mdx +++ b/fern/products/sdks/overview/python/quickstart.mdx @@ -39,19 +39,11 @@ This command adds the following `group` to `generators.yml`: ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group python-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group python-sdk --api your-api-name - ``` -</Note> + fern generate --group python-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/ruby/changelog/2025-08-13.mdx b/fern/products/sdks/overview/ruby/changelog/2025-08-13.mdx index b2f7a78c..1aa59218 100644 --- a/fern/products/sdks/overview/ruby/changelog/2025-08-13.mdx +++ b/fern/products/sdks/overview/ruby/changelog/2025-08-13.mdx @@ -1,12 +1,3 @@ -## 1.0.0-rc3 -**`(feat):`** Always lazy load type references to handle circular dependencies and import order. - -## 1.0.0-rc2 -**`(feat):`** Support for sending request bodies when the request is a reference to a type or a primitive. - -## 1.0.0-rc1 -**`(feat):`** Fix circular type references within the Ruby SDK generator. - ## 1.0.0-rc0 **`(feat):`** Introduce a revamped Ruby SDK generator with several improvements to be detailed in a larger post. diff --git a/fern/products/sdks/overview/ruby/changelog/2025-08-18.mdx b/fern/products/sdks/overview/ruby/changelog/2025-08-18.mdx deleted file mode 100644 index e5751ca5..00000000 --- a/fern/products/sdks/overview/ruby/changelog/2025-08-18.mdx +++ /dev/null @@ -1,18 +0,0 @@ -## 1.0.0-rc9 -**`(fix):`** Union types extend the Model class. - -## 1.0.0-rc8 -**`(fix):`** The client argument on the nested resource is now a keyword argument. - -## 1.0.0-rc7 -**`(fix):`** Update the Union type to not remove the discriminant from the value. - -## 1.0.0-rc6 -**`(fix):`** Fix reference to internal JSON request. - -## 1.0.0-rc5 -**`(fix):`** Fix module name for internal JSON request. - -## 1.0.0-rc4 -**`(fix):`** Fix syntax for Union types extending the Union module. - diff --git a/fern/products/sdks/overview/ruby/changelog/2025-08-20.mdx b/fern/products/sdks/overview/ruby/changelog/2025-08-20.mdx deleted file mode 100644 index 34bad65e..00000000 --- a/fern/products/sdks/overview/ruby/changelog/2025-08-20.mdx +++ /dev/null @@ -1,24 +0,0 @@ -## 1.0.0-rc17 -**`(fix):`** Fix reference request methods. - -## 1.0.0-rc16 -**`(fix):`** Fix subpackage client generation. - -## 1.0.0-rc15 -**`(fix):`** Generate nested subpackage clients. - -## 1.0.0-rc14 -**`(fix):`** Fix parameterless endpoint methods. - -## 1.0.0-rc13 -**`(feat):`** Implement Wrapped Request Endpoints. - -## 1.0.0-rc12 -**`(fix):`** Support multipart form uploads. - -## 1.0.0-rc11 -**`(fix):`** Install dependencies after generating the SDK to produce a Gemfile.lock. - -## 1.0.0-rc10 -**`(fix):`** Generate a Rubocop file and autocorrect the generated code. - diff --git a/fern/products/sdks/overview/ruby/changelog/2025-08-26.mdx b/fern/products/sdks/overview/ruby/changelog/2025-08-26.mdx deleted file mode 100644 index 4e48fef1..00000000 --- a/fern/products/sdks/overview/ruby/changelog/2025-08-26.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.0-rc18 -**`(feat):`** Updating Ruby build and configuration files, and adding custom test files. - diff --git a/fern/products/sdks/overview/ruby/configuration.mdx b/fern/products/sdks/overview/ruby/configuration.mdx index e5bcc1ec..d1b4cd29 100644 --- a/fern/products/sdks/overview/ruby/configuration.mdx +++ b/fern/products/sdks/overview/ruby/configuration.mdx @@ -5,7 +5,12 @@ description: Configuration options for the Fern Ruby SDK. You can customize the behavior of the Ruby SDK generator in `generators.yml`: +<<<<<<< HEAD +```yaml {7-8} +default-group: local +======= ```yaml {6-7} title="generators.yml" +>>>>>>> origin/main groups: ruby-sdk: generators: diff --git a/fern/products/sdks/overview/ruby/quickstart.mdx b/fern/products/sdks/overview/ruby/quickstart.mdx index eb1a23fc..f682ca0c 100644 --- a/fern/products/sdks/overview/ruby/quickstart.mdx +++ b/fern/products/sdks/overview/ruby/quickstart.mdx @@ -40,19 +40,11 @@ This command adds the following `group` to `generators.yml`: ### Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group ruby-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group ruby-sdk --api your-api-name - ``` -</Note> + fern generate --group ruby-sdk + ``` <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> diff --git a/fern/products/sdks/overview/rust/changelog/2025-08-16.mdx b/fern/products/sdks/overview/rust/changelog/2025-08-16.mdx deleted file mode 100644 index 18fdee73..00000000 --- a/fern/products/sdks/overview/rust/changelog/2025-08-16.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.6 -**`(feat):`** Added pagination support - diff --git a/fern/products/sdks/overview/rust/changelog/2025-08-27.mdx b/fern/products/sdks/overview/rust/changelog/2025-08-27.mdx deleted file mode 100644 index 3b5cc4ea..00000000 --- a/fern/products/sdks/overview/rust/changelog/2025-08-27.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.7 -**`(fix):`** Fixed semver for changelog validation. - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-14.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-14.mdx deleted file mode 100644 index deaedf1b..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-14.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.4.1 -**`(fix):`** Fixed an infinite recursion bug in Swift SDKs where convenience initializers without auth schemes could ambiguously call the designated initializer. The generator now always passes arguments explicitly to avoid ambiguity. - - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-15.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-15.mdx deleted file mode 100644 index 3f291d91..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-15.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.5.0 -**`(feat):`** Added 'fileDownload' response support. - - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-16.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-16.mdx deleted file mode 100644 index 6d885c46..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-16.mdx +++ /dev/null @@ -1,7 +0,0 @@ -## 0.7.0 -**`(feat):`** Added sanitization for literal enum values to generate valid and readable names. - - -## 0.6.0 -**`(chore):`** Upgraded to IR v59. - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-18.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-18.mdx deleted file mode 100644 index de6106dc..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-18.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.8.0 -**`(feat):`** Added GitHub publishing support. - - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-19.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-19.mdx deleted file mode 100644 index 5d20da77..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-19.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.9.0 -**`(feat):`** Added `clientClassName` and `environmentEnumName` generator config options for custom naming. - - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-24.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-24.mdx deleted file mode 100644 index 4ee4ffc2..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-24.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.10.0 -**`(feat):`** Namespaced inline request structs under a non-instantiable container enum to reduce the probability of top-level symbol name collisions. - - diff --git a/fern/products/sdks/overview/swift/changelog/2025-08-26.mdx b/fern/products/sdks/overview/swift/changelog/2025-08-26.mdx deleted file mode 100644 index f76dd311..00000000 --- a/fern/products/sdks/overview/swift/changelog/2025-08-26.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 0.11.0 -**`(feat):`** Added `moduleName` generator config option to allow customizing the module name. - - diff --git a/fern/products/sdks/overview/swift/publishing-to-swift-package-manager.mdx b/fern/products/sdks/overview/swift/publishing-to-swift-package-manager.mdx deleted file mode 100644 index 62d15bb9..00000000 --- a/fern/products/sdks/overview/swift/publishing-to-swift-package-manager.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Publishing as a Swift package -description: How to publish the Fern Swift SDK as a Swift package ---- - -Publish your public-facing Fern Swift SDK as a Swift package distributed via Git. After following the steps on this page, you'll have a versioned package that developers can install using Swift Package Manager. - -<Markdown src="/products/sdks/snippets/setup-fern-folder-callout.mdx"/> - -## Configure `generators.yml` - -<Steps> - <Step title="Configure `output` location"> - Swift packages are distributed via Git repositories, so remove the auto-generated `output` and `config` properties. Instead, add the path to your GitHub repository: - - ```yaml {6-7} title="generators.yml" - groups: - swift-sdk: - generators: - - name: fernapi/fern-swift-sdk - version: 1.0.0 - github: - repository: your-org/company-swift - ``` - </Step> -</Steps> - -## Publish as a Swift package - -At this point, you're ready to generate a release for your SDK. - -<Steps> - <Step title="Generate your release"> - Regenerate your SDK and publish it to your repository: - - ```bash - fern generate --group swift-sdk --version <version> - ``` - - Local machine output will verify that the release is pushed to your repository and tagged with the version you specified. - </Step> - - <Step title="Verify package availability"> - Your Swift package is now available! Developers can add it to their projects by: - - - **In Xcode**: File → Add Package Dependencies → Enter your repository URL - - **In Package.swift**: Add to dependencies array: - - ```swift - dependencies: [ - .package(url: "https://github.com/<github-org>/<github-repo-name>", from: "<version>") - ] - ``` - - <Tip> - Unlike other languages that rely on centralized registries, Swift packages are available as soon as they’re tagged and pushed to a Git repository. - - You can optionally submit your package to the community-maintained [Swift Package Index](https://swiftpackageindex.com/) for better discoverability. - </Tip> - </Step> -</Steps> - - - diff --git a/fern/products/sdks/overview/swift/quickstart.mdx b/fern/products/sdks/overview/swift/quickstart.mdx deleted file mode 100644 index dbc17d57..00000000 --- a/fern/products/sdks/overview/swift/quickstart.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Swift quickstart -description: Get started quickly with the Fern Swift SDK. ---- - -Generate a Swift SDK by following the instructions on this page. - -<Markdown src="/products/sdks/snippets/setup-fern-folder-callout.mdx"/> - -<Steps> -<Markdown src="/products/sdks/snippets/pass-fern-check.mdx"/> - -### Add the SDK generator - -Run the following command to add the Swift SDK generator to `generators.yml`: - -```bash -fern add fern-swift-sdk --group swift-sdk -``` - -<Note> - `swift-sdk` is the name of the `generators.yml` group that configures your Swift - SDK's output location and other metadata. You can customize this group name to - differentiate between multiple SDKs across different languages (e.g., - `ruby-sdk`, etc) in your organization. -</Note> - -This command adds the following `group` to `generators.yml`: - -```yaml title="generators.yml" - swift-sdk: # group name - generators: - - name: fernapi/fern-swift-sdk - version: <Markdown src="/snippets/version-number-swift.mdx"/> - output: - location: local-file-system - path: ../sdks/swift -``` - -### Generate the SDK - - Run the following command to generate your SDK: - - ```bash - fern generate --group swift-sdk - ``` - - <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> - -```bash -fern/ # created by fern init -sdks/ # created by fern generate --group swift-sdk -├─ swift - ├─ Package.swift - └─ Sources - ├─ YourClient.swift - ├─ Schemas/ - ├─ Public/ - ├─ Core/ - └─ Resources/ -``` -</Steps> diff --git a/fern/products/sdks/overview/typescript/changelog/2025-04-14.mdx b/fern/products/sdks/overview/typescript/changelog/2025-04-14.mdx index a3e084e7..b2c949a7 100644 --- a/fern/products/sdks/overview/typescript/changelog/2025-04-14.mdx +++ b/fern/products/sdks/overview/typescript/changelog/2025-04-14.mdx @@ -1,5 +1,5 @@ ## 0.51.0 -**`(feat):`** Add `rawResponse` property to JavaScript errors. +**`(feat):`** Add `rawResponse` property to JavaScript errors. ```ts try { diff --git a/fern/products/sdks/overview/typescript/changelog/2025-06-19.mdx b/fern/products/sdks/overview/typescript/changelog/2025-06-19.mdx index 7fb541f7..ee8497f9 100644 --- a/fern/products/sdks/overview/typescript/changelog/2025-06-19.mdx +++ b/fern/products/sdks/overview/typescript/changelog/2025-06-19.mdx @@ -16,7 +16,7 @@ The user can choose how to consume the binary data. ## 1.7.2 -**`(fix):`** Fix bug where duplicate file generation was silently allowed instead of failing. The `withSourceFile` method now properly +**`(fix):`** Fix bug where duplicate file generation was silently allowed instead of failing. The `withSourceFile` method now properly handles the `overwrite` option to prevent unintended file overwrites. diff --git a/fern/products/sdks/overview/typescript/changelog/2025-06-22.mdx b/fern/products/sdks/overview/typescript/changelog/2025-06-22.mdx index c7af2aae..9faa7e9c 100644 --- a/fern/products/sdks/overview/typescript/changelog/2025-06-22.mdx +++ b/fern/products/sdks/overview/typescript/changelog/2025-06-22.mdx @@ -12,7 +12,7 @@ The default is `Node16`. If you choose `Node18`, the `form-data`, `formdata-node ## 1.8.2 -**`(fix):`** When a multipart form part is explicitly marked as JSON, serialize the data as JSON regardless of type. +**`(fix):`** When a multipart form part is explicitly marked as JSON, serialize the data as JSON regardless of type. This also means arrays, maps, etc. will not be split into multiple parts, but serialized to JSON as a single part. diff --git a/fern/products/sdks/overview/typescript/changelog/2025-07-03.mdx b/fern/products/sdks/overview/typescript/changelog/2025-07-03.mdx index c67fff78..263d4e45 100644 --- a/fern/products/sdks/overview/typescript/changelog/2025-07-03.mdx +++ b/fern/products/sdks/overview/typescript/changelog/2025-07-03.mdx @@ -5,7 +5,7 @@ **`(internal):`** Bump version to test Docker image rename to `fernapi/fern-typescript-sdk` ## 2.3.2 -**`(fix):`** Remove ".js" extension from ESM imports in the source generator code. +**`(fix):`** Remove ".js" extension from ESM imports in the source generator code. If `useLegacyExports` is `true`, you will not see ".js" extensions in ESM imports. If `useLegacyExports` is `false` (default), a post process step will add the `.js` extension, so you won't see a difference. diff --git a/fern/products/sdks/overview/typescript/changelog/2025-07-04.mdx b/fern/products/sdks/overview/typescript/changelog/2025-07-04.mdx index 4022bccb..9acc1dd6 100644 --- a/fern/products/sdks/overview/typescript/changelog/2025-07-04.mdx +++ b/fern/products/sdks/overview/typescript/changelog/2025-07-04.mdx @@ -1,10 +1,10 @@ ## 2.4.2 -**`(fix):`** Fixes a compile issue when WebSocket connect methods require query parameters with special characters. +**`(fix):`** Fixes a compile issue when WebSocket connect methods require query parameters with special characters. Fixes response deserialization in websockets to respect skipping validation. ## 2.4.1 -**`(fix):`** When serde layer is enabled, WebSocket channels now pass through unrecognized properties +**`(fix):`** When serde layer is enabled, WebSocket channels now pass through unrecognized properties instead of stripping them to preserve forwards compatibility. diff --git a/fern/products/sdks/overview/typescript/changelog/2025-08-15.mdx b/fern/products/sdks/overview/typescript/changelog/2025-08-15.mdx deleted file mode 100644 index aa42bd8f..00000000 --- a/fern/products/sdks/overview/typescript/changelog/2025-08-15.mdx +++ /dev/null @@ -1,8 +0,0 @@ -## 2.8.2 -**`(feat):`** Log warning when `noSerdeLayer` is `false` and `enableInlineTypes` is `true`. - - -## 2.8.1 -**`(fix):`** Properly assert responses in wire tests when the `neverThrowErrors` flag is enabled. - - diff --git a/fern/products/sdks/overview/typescript/changelog/2025-08-21.mdx b/fern/products/sdks/overview/typescript/changelog/2025-08-21.mdx deleted file mode 100644 index 11f2bade..00000000 --- a/fern/products/sdks/overview/typescript/changelog/2025-08-21.mdx +++ /dev/null @@ -1,25 +0,0 @@ -## 2.8.4 -**`(feat):`** Add `flattenRequestParameters` to the SDK generator config. -`flattenRequestParameters` is a boolean that controls whether to flatten request parameters. -When `false` (default), the legacy flattening logic is used. -When `true`, the new flattening logic is used. - -```yml -# In generators.yml -groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - config: - flattenRequestParameters: true -``` - - -## 2.8.3 -**`(fix):`** Set `Authorization` header for WebSocket connects when auth is available on the generated SDK client. -This will happen regardless of whether the AsyncAPI server or channel is marked for auth. - - -**`(fix):`** Add support for inferred bearer authentication in WebSocket connects. - - diff --git a/fern/products/sdks/overview/typescript/changelog/2025-08-26.mdx b/fern/products/sdks/overview/typescript/changelog/2025-08-26.mdx deleted file mode 100644 index ec90ad0b..00000000 --- a/fern/products/sdks/overview/typescript/changelog/2025-08-26.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## 2.9.0 -**`(feat):`** Generator passes readme configs apiName, disabledSections, and whiteLabel - diff --git a/fern/products/sdks/overview/typescript/changelog/2025-08-27.mdx b/fern/products/sdks/overview/typescript/changelog/2025-08-27.mdx deleted file mode 100644 index c2ff609e..00000000 --- a/fern/products/sdks/overview/typescript/changelog/2025-08-27.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## 2.9.3 -**`(feat):`** Add support for autogenerating simple tests for pagination endpoints. - - diff --git a/fern/products/sdks/overview/typescript/changelog/2025-08-28.mdx b/fern/products/sdks/overview/typescript/changelog/2025-08-28.mdx deleted file mode 100644 index e8fc5db3..00000000 --- a/fern/products/sdks/overview/typescript/changelog/2025-08-28.mdx +++ /dev/null @@ -1,8 +0,0 @@ -## 2.9.4 -**`(fix):`** Grab overrideable root header value from Client as default. - - -## 2.9.2 -**`(fix):`** Do not throw an error if example properties are mismatched with the schema definition. - - diff --git a/fern/products/sdks/overview/typescript/configuration.mdx b/fern/products/sdks/overview/typescript/configuration.mdx index 109e94a7..6d1381eb 100644 --- a/fern/products/sdks/overview/typescript/configuration.mdx +++ b/fern/products/sdks/overview/typescript/configuration.mdx @@ -5,23 +5,30 @@ description: Configuration options for the Fern TypeScript SDK. You can customize the behavior of the TypeScript SDK generator in `generators.yml`: +<<<<<<< HEAD +```yml {7-8} +default-group: local +======= ```yml {6-8} title="generators.yml" +>>>>>>> origin/main groups: - ts-sdk: + local: generators: - name: fernapi/fern-typescript-sdk version: <Markdown src="/snippets/version-number-ts.mdx"/> config: +<<<<<<< HEAD + namespaceExport: Acme +======= namespaceExport: AcmePayments noSerdeLayer: false +>>>>>>> origin/main ``` ## SDK configuration options <ParamField path="allowExtraFields" type="boolean" toc={true}> Allow fields that are not defined in object schemas. This only applies to serde. - -See [TypeScript serde layer](/sdks/generators/typescript/serde-layer) for more information. </ParamField> <ParamField path="bundle" type="boolean" toc={true}> @@ -260,30 +267,28 @@ await service.getFoo({ pathParamName: "pathParamValue", id: "SOME_ID" }); </ParamField> <ParamField path="namespaceExport" type="string" toc={true}> -Customizes the exported namespace and client class names in the generated SDK. Must be in PascalCase. - -By default, names are derived from the organization and API names defined in your API definition: +By default, names are based on the organization and API names in the Fern Definition: -```typescript -import { AcmeApi, AcmeApiClient } from "@acme/node"; -``` + ```typescript + import { AcmeApi, AcmeApiClient } from "@acme/node"; + ``` -Setting namespaceExport overrides these default names: + `namespaceExport` customizes the exported namespace and client names: -```yaml title="generators.yml" -config: - namespaceExport: AcmePayments -``` + ```yaml + # generators.yml + config: + namespaceExport: Acme + ``` -```typescript -import { AcmePayments, AcmeClient } from "@acme/node"; -``` + ```typescript + import { Acme, AcmeClient } from "@acme/node"; + ``` </ParamField> - <ParamField path="neverThrowErrors" type="boolean" default="false" toc={true}> - When enabled, the client doesn't throw errors when a non-200 response is received from the server. Instead, the response is wrapped in an [`ApiResponse`](https://github.com/fern-api/fern/blob/main/seed/ts-sdk/alias/src/core/fetcher/APIResponse.ts). + When enabled, the client doesn't throw errors when a non-200 response is received from the server. Instead, the response is wrapped in an [`ApiResponse`](packages/core-utilities/fetcher/src/APIResponse.ts). ```typescript const response = await client.callEndpoint(...); @@ -327,19 +332,24 @@ Prevent the generator from running any scripts such as `yarn format` or `yarn in </ParamField> <ParamField path="noSerdeLayer" type="boolean" default="true" toc={true}> -Controls whether the serde layer is enabled for serialization/deserialization. -When `noSerdeLayer: false`, the generated client includes custom serialization code that transforms property names to camelCase, validates requests/responses at runtime, and supports complex types. +No serialization/deserialization code is generated by default. The client uses `JSON.parse()` and `JSON.stringify()` instead of the default Serde layer. + + When `noSerdeLayer: false`, the generated client includes a layer for serializing requests and deserializing responses. This has three benefits: + + 1. The client validates requests and response at runtime (client-side). + + 1. The client can support complex types like `Date` and `Set`. + + 1. The generated types can stray from the wire/JSON representation to be more + idiomatic. For example, when the Serde layer is enabled (`noSerdeLayer: false`), all properties are `camelCase`, even if the server is expecting `snake_case`. -See [TypeScript serde layer](/sdks/generators/typescript/serde-layer) for detailed guidance on when to enable this option. </ParamField> <ParamField path="outputSourceFiles" type="boolean" default="true" toc={true}> - Controls the output format of generated files: - - **When `true` (default)**: Outputs raw TypeScript `.ts` files - - **When `false`**: Runs TypeScript compiler and outputs compiled `.js` files with `.d.ts` declaration files + When enabled, the generator outputs raw TypeScript files. When disabled (the default), outputs `.js` and `d.ts` files. - <Note>This option only applies when using local file system output. This setting is ignored when publishing to GitHub or npm, where files are always compiled.</Note> + <Note>This only applies when dumping code locally. This configuration is ignored when publishing to Github or npm.</Note> </ParamField> <ParamField path="packageJson" type="object" toc={true}> @@ -451,10 +461,10 @@ The default is `web`. <ParamField path="useBigInt" type="boolean" default="false" toc={true}> When `useBigInt` is set to `true`, a customized JSON serializer & deserializer is used that will preserve the precision of `bigint`'s, as opposed to the native `JSON.stringify` and `JSON.parse` function which converts `bigint`'s to number's losing precision. -When combining `useBigInt` with our serialization layer (`noSerdeLayer: false`), both the request and response properties that are marked as `long` and `bigint` in OpenAPI/Fern spec, will consistently be `bigint`'s. -However, when disabling the serialization layer (`noSerdeLayer: true`), they will be typed as `number | bigint`. See [TypeScript serde layer](/sdks/generators/typescript/serde-layer) for more information. +When combining `useBigInt` with our serialization layer (`no-serde: false`), both the request and response properties that are marked as `long` and `bigint` in OpenAPI/Fern spec, will consistently be `bigint`'s. +However, when disabling the serialization layer (`no-serde: true`), they will be typed as `number | bigint`. -Here's an overview of what to expect from the generated types when combining `useBigInt` and `noSerdeLayer` with the following Fern definition: +Here's an overview of what to expect from the generated types when combining `useBigInt` and `noSerde` with the following Fern definition: *Fern definition*: @@ -470,28 +480,28 @@ types: ```typescript // useBigInt: true -// noSerdeLayer: false +// noSerde: false interface ObjectWithLongAndBigInt { longProp: bigint; bigIntProp: bigint; } // useBigInt: true -// noSerdeLayer: true +// noSerde: true interface ObjectWithLongAndBigInt { longProp: bigint | number; bigIntProp: bigint | number; } // useBigInt: false -// noSerdeLayer: false +// noSerde: false interface ObjectWithLongAndBigInt { longProp: number; bigIntProp: string; } // useBigInt: false -// noSerdeLayer: true +// noSerde: true interface ObjectWithLongAndBigInt { longProp: number; bigIntProp: string; diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index b93e88f3..d99496de 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -14,9 +14,9 @@ you'll have a versioned package published on npm. <Info> This page assumes that you have: - * An initialized `fern` folder. See [Set up the `fern` + * An initialized `fern` folder on your local machine. See [Set up the `fern` folder](/sdks/overview/quickstart). - * A GitHub repository for your TypeScript SDK. See [Project structure](/sdks/overview/project-structure). + * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/overview/github). * A TypeScript generator group in `generators.yml`. See [TypeScript Quickstart](quickstart#add-the-sdk-generator). @@ -24,81 +24,82 @@ you'll have a versioned package published on npm. ## Configure `generators.yml` -<Note>Your `generators.yml` [should live in your source repository](/sdks/overview/project-structure) (or on your local machine), not the repository that contains your TypeScript SDK code.</Note> - <Steps> - <Step title="Configure `output` location"> + + <Step title="Configure `output` location"> In the `group` for your TypeScript SDK, change the output location in from `local-file-system` (the default) to `npm` to indicate that Fern should publish your package directly to the npm registry: - ```yaml {6-7} title="generators.yml" - groups: - ts-sdk: # Group name for your TypeScript SDK - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - ``` + ```yaml {6-7} + groups: + ts-sdk: # Group name for your TypeScript SDK + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> + output: + location: npm - </Step> + ``` + </Step> - <Step title="Add a unique package name"> + <Step title="Add a unique package name"> - Your package name must be unique in the npm repository, otherwise publishing your SDK to npm will fail. + Your package name must be unique in the npm repository, otherwise publishing your SDK to npm will fail. Update your package name if you haven't done so already: - ```yaml {8} title="generators.yml" - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - package-name: your-package-name - ``` - </Step> +```yaml {8} +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> + output: + location: npm + package-name: your-package-name +``` + + </Step> <Step title="Configure `namespaceExport`"> - The `namespaceExport` option controls the name of the generated client. This is the name customers use to import your SDK (`import { your-client-name } from 'your-package-name';`). - - ```yaml {9-10} title="generators.yml" - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - package-name: your-package-name - config: - namespaceExport: YourClientName # must be PascalCase - ``` - - </Step> - - <Step title="Add repository location"> - - Add the path to the GitHub repository containing your TypeScript SDK: - - ```yaml {11-12} title="generators.yml" - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - package-name: your-package-name - config: - namespaceExport: YourClientName - github: - repository: your-org/company-typescript - ``` - - </Step> + The `namespaceExport` option controls the name of the generated client. This is the name customers use to import your SDK (`import { your-client-name } from 'your-package-name';`). + + +```yaml {9-10} +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> + output: + location: npm + package-name: your-package-name + config: + namespaceExport: YourClientName # must be PascalCase +``` + + </Step> + + <Step title="Add repository location"> + + Add the path to your GitHub repository to `generators.yml`, if you haven't already: + +```yaml {11-12} +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> + output: + location: npm + package-name: your-package-name + config: + namespaceExport: YourClientName + github: + repository: your-org/company-typescript +``` + + </Step> </Steps> ## Generate an npm token @@ -168,7 +169,7 @@ Choose how you want to authenticate and publish your SDK to npm. You can use Git <AccordionGroup> <Accordion title="Release via a GitHub workflow (recommended)"> -Set up a release workflow via [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) so you can trigger new SDK releases directly from your source repository. +Set up a release workflow via [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) so you can trigger new SDK releases directly from your repository. <Steps> <Step title="Set up authentication"> @@ -184,10 +185,10 @@ Set up a release workflow via [GitHub Actions](https://docs.github.com/en/action </Step> <Step title="Add secret for your npm Token"> - 1. Select **New repository secret**. - 1. Name your secret `NPM_TOKEN`. - 1. Add the corresponding token you generated above. - 1. Click **Add secret**. + 1. Select **New repository secret**. + 1. Name your secret `NPM_TOKEN`. + 1. Add the corresponding token you generated above. + 1. Click **Add secret**. <Frame> <img src="assets/npm-token-secret.png" alt="NPM_TOKEN secret" /> @@ -196,82 +197,62 @@ Set up a release workflow via [GitHub Actions](https://docs.github.com/en/action </Step> <Step title="Add secret for your Fern Token"> - 1. Select **New repository secret**. - 1. Name your secret `FERN_TOKEN`. - 1. Add your Fern token. If you don't already have one, generate one by - running `fern token`. By default, the `fern_token` is generated for the - organization listed in `fern.config.json`. - 1. Click **Add secret**. + 1. Select **New repository secret**. + 1. Name your secret `FERN_TOKEN`. + 1. Add your Fern token. If you don't already have one, generate one by running + `fern-token`. By default, the `fern_token` is generated for the organization + listed in `fern.config.json`. + 1. Click **Add secret**. - </Step> - <Step title="Configure npm authentication token"> + <Frame> + <img src="assets/npm-token-secret.png" alt="NPM_TOKEN secret" /> + </Frame> - Add `token: ${NPM_TOKEN}` to `generators.yml`. - - ```yaml {9} title="generators.yml" - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - package-name: name-of-your-package - token: ${NPM_TOKEN} - config: - namespaceExport: YourClientName - github: - repository: your-org/your-repository - ``` </Step> <Step title="Set up a new workflow"> - Set up a CI workflow that you can manually trigger from the GitHub UI. In your repository, navigate to **Actions**. Select **New workflow**, then **Set up workflow yourself**. Add a workflow that's similar to this: + In your repo, navigate to **Actions**. Select **New workflow**, then **Set up workflow yourself**. Set up a workflow dispatch that is similar to this: ```yaml title=".github/workflows/publish.yml" maxLines=0 name: Publish TypeScript SDK on: - workflow_dispatch: - inputs: - version: - description: "The version of the TypeScript SDK that you would like to release" - required: true - type: string + workflow_dispatch: + inputs: + version: + description: "The version of the TypeScript SDK that you would like to release" + required: true + type: string jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Install Fern CLI - run: npm install -g fern-api - - - name: Release TypeScript SDK - env: - FERN_TOKEN: ${{ secrets.FERN_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug + release: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install Fern CLI + run: npm install -g fern-api + + - name: Release TypeScript SDK + env: + FERN_TOKEN: ${{ secrets.FERN_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug ``` - <Note> - You can alternatively configure your workflow to execute `on: [push]`. See Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) for an example. - </Note> - </Step> - + </Step> <Step title="Run your workflow"> - Navigate to the **Actions** tab, select the workflow you just created, specify a version number, and click **Run workflow**. - - This regenerates your SDK, tags the new release with the version number you specified, and initiates a Fern-generated publishing workflow in your TypeScript SDK repository that publishes your release to npm. + Navigate to the **Actions** tab, select the workflow you just created, and + click **Run workflow**. - <Frame> - <img src="assets/ts-sdk-release-action.png" alt="Running TS publish workflow" /> - </Frame> + <Frame> + <img src="assets/ts-sdk-release-action.png" alt="Running TS publish workflow" /> + </Frame> - Once your workflow completes, log back into npm and navigate to **Packages** to see your new release. + Once your workflow completes, log back into npm and + navigate to **Packages** to see your new release. </Step> </Steps> @@ -283,21 +264,23 @@ Set up a release workflow via [GitHub Actions](https://docs.github.com/en/action Add `token: ${NPM_TOKEN}` to `generators.yml` to tell Fern to use the `NPM_TOKEN` environment variable for authentication when publishing to the npm registry. - ```yaml {9} - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> - output: - location: npm - package-name: name-of-your-package - token: ${NPM_TOKEN} - config: - namespaceExport: YourClientName - github: - repository: your-org/your-repository - ``` +```yaml {9} +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: <Markdown src="/snippets/typescript-sdk-version.mdx"/> + output: + location: npm + package-name: name-of-your-package + token: ${NPM_TOKEN} + config: + namespaceExport: YourClientName + github: + repository: your-org/your-repository +``` + + When you regenerate your release, Fern will automatically create a workflow in your repository called `.github/workflows/ci.yml` that will automatically publish your release to npm. For an example, see Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) </Step> <Step title="Set npm environment variable"> @@ -309,7 +292,7 @@ Set up a release workflow via [GitHub Actions](https://docs.github.com/en/action </Step> <Step title="Regenerate your SDK"> - Regenerating your SDK tags the new release with the version number you specified and initiates a Fern-generated publishing workflow in your TypeScript SDK repository that publishes your release to npm. + ```bash fern generate --group ts-sdk --version <version> diff --git a/fern/products/sdks/overview/typescript/quickstart.mdx b/fern/products/sdks/overview/typescript/quickstart.mdx index f241a19e..e05e086f 100644 --- a/fern/products/sdks/overview/typescript/quickstart.mdx +++ b/fern/products/sdks/overview/typescript/quickstart.mdx @@ -39,21 +39,13 @@ This command adds the following `group` to `generators.yml`: ``` ## Generate the SDK -Run the following command to generate your SDK: - -```bash -fern generate --group ts-sdk -``` - -<Note> - If you have multiple APIs, use the [`--api` flag](/cli-api-reference/cli-reference/commands#api) to specify the API you want to generate: + Run the following command to generate your SDK: ```bash - fern generate --group ts-sdk --api your-api-name - ``` -</Note> + fern generate --group ts-sdk + ``` -<Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> + <Markdown src="/products/sdks/snippets/generate-sdk.mdx"/> ```bash fern/ # created by fern init diff --git a/fern/products/sdks/overview/typescript/serde-layer.mdx b/fern/products/sdks/overview/typescript/serde-layer.mdx deleted file mode 100644 index 455d86b7..00000000 --- a/fern/products/sdks/overview/typescript/serde-layer.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: TypeScript serde layer -description: Control how your API naming conventions are transformed in the generated TypeScript SDK ---- - -Fern's TypeScript SDK generator includes an optional serde layer that determines whether the generated SDK matches your original API naming conventions (snake_case vs. camelCase, case-sensitive fields) or follows TypeScript conventions. This serde layer is controlled by the `noSerdeLayer` option. - -By default, the serde layer is **disabled** (`noSerdeLayer: true`), meaning field names are preserved exactly as they appear in your API specification. - -## When to enable the serde layer - -```yaml title="generators.yml" {7} -groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/version-number-ts.mdx"/> - config: - noSerdeLayer: false # Enable serde layer -``` - -When you turn on the serde layer, (`noSerdeLayer: false`), the TypeScript SDK generator includes custom serialization code that: -- Transforms all property names from your API to camelCase -- Validates requests and responses at runtime -- Supports complex types like `Date` and `Set`. - -Enable the serde layer when you want idiomatic TypeScript conventions and don't have case-sensitive field conflicts. Keep it disabled when your API has fields that differ only by casing or when you need exact field name preservation. - -## Additional configuration options - -Several configuration options work alongside an enabled serde layer: -- `skipResponseValidation` disables the serde layer's runtime validation while keeping its transformation features -- `allowExtraFields` permits properties not defined in your schema. -- `useBigInt` enables custom JSON handling to preserve large number precision. - -These options only take effect when the serde layer is enabled (`noSerdeLayer: false`), as they require the custom serialization infrastructure. - -```yaml title="generators.yml" {7-10} -groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/version-number-ts.mdx"/> - config: - noSerdeLayer: false # Enable serde layer - skipResponseValidation: true # Disable runtime validation errors - allowExtraFields: true # Allow undefined fields in responses - useBigInt: true # Preserve precision for large numbers -``` - -For the complete list of all TypeScript configuration options, go to [TypeScript configuration](/sdks/generators/typescript/configuration). - diff --git a/fern/products/sdks/project-structure.mdx b/fern/products/sdks/project-structure.mdx deleted file mode 100644 index 283e406f..00000000 --- a/fern/products/sdks/project-structure.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Project structure -description: An overview of the file and folder structure of a Fern SDKs project ---- - -Before generating SDKs with Fern, set up the proper GitHub repository structure to house your API definitions and SDK code so it's intuitive for you and your users to access, maintain, and update code. - -## Repository architecture - -Fern recommends a multi-repository structure containing: - -- **Source repository**: Contains your API definitions and SDK generation configuration -- **SDK repositories**: Separate repositories for each SDK (TypeScript, Python, Go, etc.) - -```bash -├─ company-repo # Source repository -│ ├─ .github.workflows # Contains publishing workflows for all SDKs -│ └─ fern/ -│ ├─ fern.config.json # Root-level config -│ ├─ generators.yml # References SDK repos -│ └─ definition/ - ├─ overrides.yml # Optional overrides file -│ └─ api.yml # Your API definition -├─ typescript-sdk-repo # SDK repository -├─ python-sdk-repo # SDK repository -└─ go-sdk-repo # SDK repository -``` - -This separation allows you to manage API definitions centrally while keeping each SDK in its own repository for independent versioning and distribution. - -<Info title="Examples"> - See Cohere's [fern folder](https://github.com/cohere-ai/cohere-developer-experience/tree/23d6c541a01eb6b54dd9bb3588c805bb0e307713/fern) and [TypeScript](https://github.com/cohere-ai/cohere-typescript) and [Python](https://github.com/cohere-ai/cohere-python) SDK repositories. -</Info> - -## Core configuration files - -The source repository contains a `fern/` folder that is initialized with your API definitions and a top-level `generators.yml` file. - -### `fern.config.json` - -Every fern folder has a single `fern.config.json` file. This file stores the organization name and the version of the Fern CLI that you are using: - -```json -{ - "organization": "your-organization", - "version": "<Markdown src="/products/sdks/snippets/fern-config-json-version.mdx"/>" -} -``` - -Every time you run a fern CLI command, the CLI downloads itself at the correct version to ensure determinism. - -### `generators.yml` - -The `generators.yml` file specifies which SDKs to generate and where to publish them. It acts as the bridge between your API definitions and your SDK repositories. It contains a group for each SDK generator and points to the corresponding SDK's repository: - -```yaml -groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: <Markdown src="/snippets/version-number-ts.mdx"/> - github: - repository: your-organization/typescript-sdk-repo - - python-sdk: - generators: - - name: fernapi/fern-python-sdk - version: <Markdown src="/snippets/version-number-python.mdx"/> - github: - repository: your-organization/python-sdk-repo -``` - -<Info title="Examples"> - See Cohere's [`generators.yml` file](https://github.com/cohere-ai/cohere-developer-experience/blob/23d6c541a01eb6b54dd9bb3588c805bb0e307713/fern/apis/sdks/generators.yml) and Vapi's [`generators.yml` file](https://github.com/VapiAI/docs/blob/9c674c2b16ba03e864e26673c5290c88048c9a7a/fern/apis/api/generators.yml). -</Info> - -See the [`generators.yml` reference page](/sdks/reference/generators-yml) for complete configuration options. - -### API definition file - -For information on how to structure your API definition files, see [Project structure (API Definitions)](/api-definitions/overview/project-structure). - -### Optional: `overrides.yml` file - -You can optionally add an `overrides.yml` file to customize your API definition without modifying the original spec file. For more information, see [Overrides](/api-definitions/overview/overrides). - -## SDK repository structure - -Each SDK has its own repository with the following structure: - -```bash -typescript-sdk-repo/ # Individual SDK repository -├─ .github/workflows/ # Generated by Fern -├─ scripts/ -├─ src/ -├─ tests/ -└─ .fernignore # Files Fern shouldn't modify -``` - -Fern generates most of these files automatically, including preserving any custom code you've added. - -## Setup instructions - -1. **Create repositories**: Set up your source repository, plus one repository for each SDK -2. **Install Fern GitHub App**: Install the [Fern GitHub App](https://github.com/apps/fern-api) on all repositories -3. **Configure `generators.yml`**: In your `generators.yml`, add a reference to each SDK repository. - -## Multiple API definitions - -<Markdown src="/snippets/multiple-apis.mdx" /> - diff --git a/fern/products/sdks/reference/generators-yml-reference.mdx b/fern/products/sdks/reference/generators-yml-reference.mdx index 41a2eb62..72efb39e 100644 --- a/fern/products/sdks/reference/generators-yml-reference.mdx +++ b/fern/products/sdks/reference/generators-yml-reference.mdx @@ -171,9 +171,109 @@ api: ### Specification Types -#### OpenAPI +#### OpenAPI -<Markdown src="/snippets/openapi-specs.mdx" /> +```yaml +api: + specs: + - openapi: "./openapi.yml" + origin: "https://api.example.com/openapi.json" + overrides: "./openapi-overrides.yml" + namespace: "v1" + settings: + title-as-schema-name: true + inline-path-parameters: false + prefer-undiscriminated-unions-with-literals: true + filter: + endpoints: ["POST /users", "GET /users/{id}"] + example-generation: + request: + max-depth: 2 +``` + +<ParamField path="openapi" type="string" required={true} toc={true}> + Path to the OpenAPI specification file. +</ParamField> + +<ParamField path="origin" type="string" toc={true}> + URL of the API definition origin for polling updates. +</ParamField> + +<ParamField path="overrides" type="string" toc={true}> + Path to OpenAPI overrides file. +</ParamField> + +<ParamField path="namespace" type="string" toc={true}> + Namespace for the specification. +</ParamField> + +<ParamField path="settings" type="OpenAPISettingsSchema" toc={true}> + OpenAPI-specific generation settings. +</ParamField> + +<ParamField path="title-as-schema-name" type="boolean" default="true" toc={true}> + Whether to use the titles of schemas within an OpenAPI definition as the names of types within Fern. +</ParamField> + +<ParamField path="inline-path-parameters" type="boolean" default="false" toc={true}> + Whether to include path parameters within the generated in-lined request. +</ParamField> + +<ParamField path="prefer-undiscriminated-unions-with-literals" type="boolean" default="false" toc={true}> + Whether to prefer undiscriminated unions with literals. +</ParamField> + +<ParamField path="only-include-referenced-schemas" type="boolean" default="false" toc={true}> + Whether to only include schemas referenced by endpoints in the generated SDK (tree-shaking). +</ParamField> + +<ParamField path="respect-nullable-schemas" type="boolean" default="false" toc={true}> + Preserves nullable schemas in API definition settings. When false, nullable schemas are treated as optional. +</ParamField> + +<ParamField path="object-query-parameters" type="boolean" toc={true}> + Enables parsing deep object query parameters. +</ParamField> + +<ParamField path="respect-readonly-schemas" type="boolean" toc={true}> + Enables exploring readonly schemas in OpenAPI specifications. +</ParamField> + +<ParamField path="respect-forward-compatible-enums" type="boolean" default="false" toc={true}> + Enables respecting forward compatible enums in OpenAPI specifications. +</ParamField> + +<ParamField path="use-bytes-for-binary-response" type="boolean" toc={true}> + Enables using the `bytes` type for binary responses. Defaults to file stream. +</ParamField> + +<ParamField path="default-form-parameter-encoding" type="FormParameterEncoding" default="json" toc={true}> + The default encoding of form parameters. Options: `form`, `json`. +</ParamField> + +<ParamField path="additional-properties-defaults-to" type="boolean" default="false" toc={true}> + Configure what `additionalProperties` should default to when not explicitly defined on a schema. +</ParamField> + +<ParamField path="type-dates-as-strings" type="boolean" default="true" toc={true}> + If true, convert strings with format date to strings. If false, convert to dates. +</ParamField> + +<ParamField path="preserve-single-schema-oneof" type="boolean" default="false" toc={true}> + If true, preserve oneOf structures with a single schema. If false, unwrap them. +</ParamField> + +<ParamField path="filter.endpoints" type="list<string>" toc={true}> + Endpoints to include in the generated SDK (e.g., "POST /users"). +</ParamField> + +<ParamField path="example-generation.request.max-depth" type="integer" toc={true}> + Controls the maximum depth for which optional properties will have examples generated. A depth of 0 means no optional properties will have examples. +</ParamField> + +<ParamField path="example-generation.response.max-depth" type="integer" toc={true}> + Controls the maximum depth for which optional properties will have examples generated in responses. +</ParamField> #### AsyncAPI diff --git a/fern/products/sdks/sdks.yml b/fern/products/sdks/sdks.yml index 8f216bc1..7d6db1d0 100644 --- a/fern/products/sdks/sdks.yml +++ b/fern/products/sdks/sdks.yml @@ -7,16 +7,16 @@ navigation: - page: Quickstart path: ./fern-folder.mdx slug: quickstart - - page: Project structure - path: ./project-structure.mdx - slug: project-structure - - page: Adding custom code + - page: Project Structure + path: ./github-setup.mdx + slug: github + - page: Adding Custom Code path: ./custom-code.mdx slug: custom-code - page: Capabilities path: ./capabilities.mdx slug: capabilities - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase - section: Generators contents: @@ -26,7 +26,7 @@ navigation: - page: Quickstart path: ./overview/typescript/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/typescript/design.mdx slug: design @@ -39,19 +39,16 @@ navigation: - page: Adding custom code path: ./overview/typescript/custom-code.mdx slug: custom-code - - page: Enabling the serde layer - path: ./overview/typescript/serde-layer.mdx - slug: serde-layer - changelog: ./overview/typescript/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.typescript - section: Python contents: - page: Quickstart path: ./overview/python/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/python/design.mdx slug: design @@ -66,21 +63,21 @@ navigation: slug: custom-code - changelog: ./overview/python/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.python - section: Go contents: - page: Quickstart path: ./overview/go/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/go/design.mdx slug: design - page: Configuration path: ./overview/go/configuration.mdx slug: configuration - - page: Publishing as a Go module + - page: Publishing as a Go Module path: ./overview/go/publishing-to-go-package-manager.mdx slug: publishing - page: Adding custom code @@ -88,14 +85,14 @@ navigation: slug: custom-code - changelog: ./overview/go/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.go - section: Java contents: - page: Quickstart path: ./overview/java/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/java/design.mdx slug: design @@ -110,7 +107,7 @@ navigation: slug: custom-code - changelog: ./overview/java/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.java - section: .NET slug: csharp @@ -118,7 +115,7 @@ navigation: - page: Quickstart path: ./overview/csharp/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/csharp/design.mdx slug: design @@ -134,14 +131,14 @@ navigation: slug: custom-code - changelog: ./overview/csharp/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.net - section: PHP contents: - page: Quickstart path: ./overview/php/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/php/design.mdx slug: design @@ -157,14 +154,14 @@ navigation: slug: custom-code - changelog: ./overview/php/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.php - section: Ruby contents: - page: Quickstart path: ./overview/ruby/quickstart.mdx slug: quickstart - - page: Design decisions + - page: Design Decisions hidden: true path: ./overview/ruby/design.mdx slug: design @@ -180,60 +177,40 @@ navigation: slug: custom-code - changelog: ./overview/ruby/changelog slug: changelog - - link: Customer showcase + - link: Customer Showcase href: https://buildwithfern.com/showcase#sdk-customers.ruby - - section: Swift - contents: - - page: Quickstart - path: ./overview/swift/quickstart.mdx - slug: quickstart - - page: Configuration - path: ./overview/swift/configuration.mdx - slug: configuration - - page: Publishing as a Swift package - path: ./overview/swift/publishing-to-swift-package-manager.mdx - slug: publishing - - changelog: ./overview/swift/changelog - slug: changelog - - section: Postman - contents: - - page: Quickstart - path: ./overview/postman/quickstart.mdx - slug: quickstart - - page: Publishing to Postman - path: ./overview/postman/publishing-to-postman.mdx - slug: publishing - page: MCP Server path: ./overview/mcp-server/introduction.mdx slug: mcp-server - - section: Deep dives + - section: Deep Dives contents: - - page: Customize method names + - page: Customize Method Names path: ./guides/customize-method-names.mdx slug: customize-method-names - page: Setup local SDK previews path: ./guides/setup-local-sdk-previews.mdx slug: local-previews - - page: Configure global headers + - page: Configure Global Headers path: ./guides/configure-global-headers.mdx slug: global-headers - - page: Configure auto-pagination + - page: Configure Auto-Pagination path: ./guides/configure-auto-pagination.mdx slug: auto-pagination - - page: Configure idempotency + - page: Configure Idempotency path: ./guides/configure-idempotency.mdx slug: idempotency - - page: Filter your endpoints (audiences) + - page: Filter Your Endpoints (Audiences) path: ./guides/filter-your-endpoints-audiences.mdx slug: audiences - - page: Customize your README + - page: Customize the README for your SDKs path: ./guides/configure-readme.mdx slug: readme + - page: Self-host Fern's SDK Generators + hidden: true + path: ./guides/self-host-fern-generators.mdx + slug: self-host-generators - page: Retries with Backoff path: ./guides/retries-with-backoff.mdx - - page: Self-hosted SDKs - path: ./guides/self-hosted.mdx - slug: self-hosted - section: Reference contents: - page: generators.yml diff --git a/fern/products/sdks/snippets/setup-fern-folder-callout.mdx b/fern/products/sdks/snippets/setup-fern-folder-callout.mdx index 29b8f546..d4bc1c29 100644 --- a/fern/products/sdks/snippets/setup-fern-folder-callout.mdx +++ b/fern/products/sdks/snippets/setup-fern-folder-callout.mdx @@ -1,7 +1,7 @@ <Info> This page assumes that you have: - * An initialized `fern` folder. See [Set up the `fern` + * An initialized `fern` folder on your local machine. See [Set up the `fern` folder](/sdks/overview/quickstart). - * A GitHub repository for your SDK. See [Project Structure](/sdks/overview/project-structure). + * A GitHub repository for your SDK. See [Project Structure](/sdks/overview/github). </Info> \ No newline at end of file diff --git a/fern/snippets/openapi-specs.mdx b/fern/snippets/openapi-specs.mdx deleted file mode 100644 index e488336e..00000000 --- a/fern/snippets/openapi-specs.mdx +++ /dev/null @@ -1,108 +0,0 @@ -```yaml title="generators.yml" -api: - specs: - - openapi: "./openapi.yml" - origin: "https://api.example.com/openapi.json" - overrides: "./openapi-overrides.yml" - namespace: "v1" - settings: - title-as-schema-name: true - inline-path-parameters: false - inline-all-of-schemas: true - prefer-undiscriminated-unions-with-literals: true - filter: - endpoints: ["POST /users", "GET /users/{id}"] - example-generation: - request: - max-depth: 2 -``` - -<ParamField path="openapi" type="string" required={true} toc={true}> - Path to the OpenAPI specification file. -</ParamField> - -<ParamField path="origin" type="string" toc={true}> - URL of the API definition origin for polling updates. -</ParamField> - -<ParamField path="overrides" type="string" toc={true}> - Path to OpenAPI overrides file. -</ParamField> - -<ParamField path="namespace" type="string" toc={true}> - Namespace for the specification. -</ParamField> - -<ParamField path="settings" type="OpenAPISettingsSchema" toc={true}> - OpenAPI-specific generation settings. -</ParamField> - -<ParamField path="title-as-schema-name" type="boolean" default="true" toc={true}> - Whether to use the titles of schemas within an OpenAPI definition as the names of types within Fern. -</ParamField> - -<ParamField path="inline-path-parameters" type="boolean" default="false" toc={true}> - Whether to include path parameters within the generated in-lined request. -</ParamField> - -<ParamField path="inline-all-of-schemas" type="boolean" default="false" toc={true}> - Whether to inline `allOf` schemas during code generation. When true, Fern recursively visits `allOf` schema definitions and inlines them into the child schema. When false, `allOf` schemas are extended through inheritance. - - Enabling this setting allows child schemas to override parent property requirements. For example, a child schema can mark a parent's required property as optional. Without this setting, Fern ignores the child schema's optional declaration and preserves the parent schema's requirement instead. -</ParamField> - -<ParamField path="prefer-undiscriminated-unions-with-literals" type="boolean" default="false" toc={true}> - Whether to prefer undiscriminated unions with literals. -</ParamField> - -<ParamField path="only-include-referenced-schemas" type="boolean" default="false" toc={true}> - Whether to only include schemas referenced by endpoints in the generated SDK (tree-shaking). -</ParamField> - -<ParamField path="respect-nullable-schemas" type="boolean" default="false" toc={true}> - Preserves nullable schemas in API definition settings. When false, nullable schemas are treated as optional. -</ParamField> - -<ParamField path="object-query-parameters" type="boolean" toc={true}> - Enables parsing deep object query parameters. -</ParamField> - -<ParamField path="respect-readonly-schemas" type="boolean" toc={true}> - Enables exploring readonly schemas in OpenAPI specifications. -</ParamField> - -<ParamField path="respect-forward-compatible-enums" type="boolean" default="false" toc={true}> - Enables respecting forward compatible enums in OpenAPI specifications. -</ParamField> - -<ParamField path="use-bytes-for-binary-response" type="boolean" toc={true}> - Enables using the `bytes` type for binary responses. Defaults to file stream. -</ParamField> - -<ParamField path="default-form-parameter-encoding" type="FormParameterEncoding" default="json" toc={true}> - The default encoding of form parameters. Options: `form`, `json`. -</ParamField> - -<ParamField path="additional-properties-defaults-to" type="boolean" default="false" toc={true}> - Configure what `additionalProperties` should default to when not explicitly defined on a schema. -</ParamField> - -<ParamField path="type-dates-as-strings" type="boolean" default="true" toc={true}> - If true, convert strings with format date to strings. If false, convert to dates. -</ParamField> - -<ParamField path="preserve-single-schema-oneof" type="boolean" default="false" toc={true}> - If true, preserve oneOf structures with a single schema. If false, unwrap them. -</ParamField> - -<ParamField path="filter.endpoints" type="list<string>" toc={true}> - Endpoints to include in the generated SDK (e.g., "POST /users"). -</ParamField> - -<ParamField path="example-generation.request.max-depth" type="integer" toc={true}> - Controls the maximum depth for which optional properties will have examples generated. A depth of 0 means no optional properties will have examples. -</ParamField> - -<ParamField path="example-generation.response.max-depth" type="integer" toc={true}> - Controls the maximum depth for which optional properties will have examples generated in responses. -</ParamField> diff --git a/fern/snippets/seo-metadata-page.mdx b/fern/snippets/seo-metadata-page.mdx deleted file mode 100644 index efd950a1..00000000 --- a/fern/snippets/seo-metadata-page.mdx +++ /dev/null @@ -1,118 +0,0 @@ -<CodeBlock title="plantstore-quickstart.mdx"> -```mdx ---- -title: PlantStore API Quick Start -headline: "Get Started with PlantStore API | Developer Documentation" -keywords: plants, garden, nursery -canonical-url: https://docs.plantstore.dev/welcome -og:site_name: PlantStore Developer Documentation -og:title: "PlantStore API Quick Start Guide" -og:description: "Learn how to integrate with PlantStore's API to manage plant inventory, process orders, and track shipments. Complete with code examples." -og:image: https://plantstore.dev/images/api-docs-banner.png -og:image:width: 1200 -og:image:height: 630 -twitter:card: summary_large_image -twitter:site: "@PlantStoreAPI" -noindex: false -nofollow: false ---- -``` -</CodeBlock> - -<AccordionGroup> -<Accordion title="Document properties"> - -<ParamField path="headline" type="string" required={false}> - When set, the `<title />` tag in the document head will use this value rather than the `title` property. This property changes the title that search engines see when crawling this page, and can be used to address Duplicate Title issues in your SEO report. -</ParamField> - -<ParamField path="canonical-url" type="string" required={false}> - Overrides the canonical URL for this page. Must be a full URL including the protocol (i.e. `https://buildwithfern.com/learn/docs/content/frontmatter`) -</ParamField> - -<ParamField path="keywords" type="string" required={false}> - Comma-separated string of keywords relevant to the page content (i.e. `plants, garden, nursery`). These keywords help search engines understand the page topic and contributes to search rankings. Use specific, relevant terms that users might search for when looking for the page's content. - - This field accepts only comma-separated strings, not bracketed arrays. - -</ParamField> - -</Accordion> -<Accordion title="OpenGraph properties"> - -<ParamField path="og:site_name" type="string" required={false}> - The name of your website as it should appear when your content is shared. -</ParamField> - -<ParamField path="og:title" type="string" required={false}> - The title of your page as it should appear when your content is shared. -</ParamField> - -<ParamField path="og:description" type="string" required={false}> - The description of your page as it should appear when your content is shared. -</ParamField> - -<ParamField path="og:url" type="string" required={false}> - The URL of your page. -</ParamField> - -<ParamField path="og:image" type="string" required={false}> - The URL or identifier of the image that will be displayed when your content is shared. -</ParamField> - -<ParamField path="og:image:width" type="number" required={false}> - The width of the image in pixels. -</ParamField> - -<ParamField path="og:image:height" type="number" required={false}> - The height of the image in pixels. -</ParamField> - -<ParamField path="og:locale" type="string" required={false}> - The locale of the page, typically in the format `language_TERRITORY` (e.g., `en_US`). -</ParamField> - -<ParamField path="og:logo" type="string" required={false}> - The URL or identifier of the logo image of your website that will be displayed when your content is shared. -</ParamField> -</Accordion> -<Accordion title="Twitter properties"> - -<ParamField path="twitter:title" type="string" required={false}> - The title of your page as it should appear in a tweet. -</ParamField> - -<ParamField path="twitter:description" type="string" required={false}> - The description of your page as it should appear in a tweet. -</ParamField> - -<ParamField path="twitter:handle" type="string" required={false}> - The Twitter handle of the page creator or site. -</ParamField> - -<ParamField path="twitter:image" type="string" required={false}> - The URL or identifier of the image that will be displayed in a tweet. -</ParamField> - -<ParamField path="twitter:site" type="string" required={false}> - The name of your website as it should appear in a tweet. -</ParamField> - -<ParamField path="twitter:url" type="string" required={false}> - The URL of your page. -</ParamField> - -<ParamField path="twitter:card" type="string" required={false}> - The type of card to be used for sharing on Twitter. Options: `summary`, `summary_large_image`, `app`, `player` -</ParamField> -</Accordion> -<Accordion title="Indexing properties"> -<ParamField path="noindex" type="boolean" required={false} default={false}> - If set to `true`, the page will not be indexed by search engines. -</ParamField> - -<ParamField path="nofollow" type="boolean" required={false} default={false}> - If set to `true`, a search engine will not follow any links present on the page. -</ParamField> -</Accordion> -</AccordionGroup> diff --git a/fern/snippets/seo-metadata-site.mdx b/fern/snippets/seo-metadata-site.mdx deleted file mode 100644 index fa728de3..00000000 --- a/fern/snippets/seo-metadata-site.mdx +++ /dev/null @@ -1,84 +0,0 @@ - -```yaml docs.yml -metadata: - # Core platform identity - og:site_name: "Square Developer Documentation" - og:title: "Square Developer Platform | Payments, Commerce & Banking APIs" - og:description: "Build with Square's suite of APIs and SDKs. Accept payments, manage inventory, create loyalty programs, and access financial services. Complete documentation for developers building the future of commerce." - og:url: "https://developer.squareup.com/docs" - - # Social sharing assets - og:image: "https://developer.squareup.com/images/docs-social-card.png" - og:image:width: 1200 - og:image:height: 630 - og:locale: "en_US" - og:logo: "https://developer.squareup.com/images/square-logo.png" - - # Twitter (I mean X) optimization - twitter:title: "Square Developer Platform Documentation" - twitter:description: "Integrate payments, point-of-sale, inventory, and financial services into your applications with Square's developer platform. Get started with our APIs, SDKs, and comprehensive guides." - twitter:handle: "@SquareDev" - twitter:image: "https://developer.squareup.com/images/twitter-card.png" - twitter:site: "@Square" - twitter:card: "summary_large_image" -``` - -<ParamField path="metadata.og:site_name" type="string" required={false}> - The name of your website for Open Graph tags. -</ParamField> - -<ParamField path="metadata.og:title" type="string" required={false}> - The title shown in social media previews. -</ParamField> - -<ParamField path="metadata.og:description" type="string" required={false}> - The description shown in social media previews. -</ParamField> - -<ParamField path="metadata.og:url" type="string" required={false}> - The canonical URL of your documentation. -</ParamField> - -<ParamField path="metadata.og:image" type="string" required={false}> - The image shown in social media previews. Recommended size is 1200x630 pixels. -</ParamField> - -<ParamField path="metadata.og:image:width" type="number" required={false}> - The width of your Open Graph image in pixels. -</ParamField> - -<ParamField path="metadata.og:image:height" type="number" required={false}> - The height of your Open Graph image in pixels. -</ParamField> - -<ParamField path="metadata.og:locale" type="string" required={false}> - The locale of your content (e.g., "en_US"). -</ParamField> - -<ParamField path="metadata.og:logo" type="string" required={false}> - URL to your company logo. -</ParamField> - -<ParamField path="metadata.twitter:title" type="string" required={false}> - The title shown in Twitter Card previews. -</ParamField> - -<ParamField path="metadata.twitter:description" type="string" required={false}> - The description shown in Twitter Card previews. -</ParamField> - -<ParamField path="metadata.twitter:handle" type="string" required={false}> - Your company's Twitter handle. -</ParamField> - -<ParamField path="metadata.twitter:image" type="string" required={false}> - The image shown in Twitter Card previews. -</ParamField> - -<ParamField path="metadata.twitter:site" type="string" required={false}> - The Twitter handle for your website. -</ParamField> - -<ParamField path="metadata.twitter:card" type="string" required={false}> - The Twitter Card type. Options are `summary`, `summary_large_image`, `app`, or `player`. -</ParamField> diff --git a/fern/snippets/version-number-csharp.mdx b/fern/snippets/version-number-csharp.mdx index 9b3176bc..41bb57bd 100644 --- a/fern/snippets/version-number-csharp.mdx +++ b/fern/snippets/version-number-csharp.mdx @@ -1 +1 @@ -2.1.15 \ No newline at end of file +2.1.10 \ No newline at end of file diff --git a/fern/snippets/version-number-go.mdx b/fern/snippets/version-number-go.mdx index 9dbb0c00..bd8bf882 100644 --- a/fern/snippets/version-number-go.mdx +++ b/fern/snippets/version-number-go.mdx @@ -1 +1 @@ -1.7.0 \ No newline at end of file +1.7.0 diff --git a/fern/snippets/version-number-java.mdx b/fern/snippets/version-number-java.mdx index 43140c02..340dfe76 100644 --- a/fern/snippets/version-number-java.mdx +++ b/fern/snippets/version-number-java.mdx @@ -1 +1 @@ -2.43.3 \ No newline at end of file +2.43.3 diff --git a/fern/snippets/version-number-php.mdx b/fern/snippets/version-number-php.mdx index c4de08c7..0d1ea064 100644 --- a/fern/snippets/version-number-php.mdx +++ b/fern/snippets/version-number-php.mdx @@ -1 +1 @@ -1.16.8 \ No newline at end of file +1.16.7 \ No newline at end of file diff --git a/fern/snippets/version-number-python.mdx b/fern/snippets/version-number-python.mdx index 4e940ae2..ad94be36 100644 --- a/fern/snippets/version-number-python.mdx +++ b/fern/snippets/version-number-python.mdx @@ -1 +1 @@ -4.28.0 \ No newline at end of file +4.28.0 diff --git a/fern/snippets/version-number-ruby.mdx b/fern/snippets/version-number-ruby.mdx index aa4023da..64e3e9b3 100644 --- a/fern/snippets/version-number-ruby.mdx +++ b/fern/snippets/version-number-ruby.mdx @@ -1 +1 @@ -1.0.0-rc19 \ No newline at end of file +1.0.0-rc19 diff --git a/fern/snippets/version-number-ts.mdx b/fern/snippets/version-number-ts.mdx index 5cc82157..8bbb6e40 100644 --- a/fern/snippets/version-number-ts.mdx +++ b/fern/snippets/version-number-ts.mdx @@ -1 +1 @@ -2.10.1 \ No newline at end of file +2.10.1 diff --git a/footer/src/FernFooter.tsx b/footer/src/FernFooter.tsx index a1f6dfce..591b1a6c 100644 --- a/footer/src/FernFooter.tsx +++ b/footer/src/FernFooter.tsx @@ -3,8 +3,8 @@ import { FernStatusWidget } from './FernStatus'; import { BuiltWithFernLight } from './images/builtwithfern-light'; import { BuiltWithFernDark } from './images/builtwithfern-dark'; -import { BuiltWithFernFrameLight } from './images/builtwithfern-frame-light'; -import { BuiltWithFernFrameDark } from './images/builtwithfern-frame-dark'; +// import { BuiltWithFernFrameLight } from './images/builtwithfern-frame-light'; +// import { BuiltWithFernFrameDark } from './images/builtwithfern-frame-dark'; import { GitHubLight } from './images/github-light'; import { GitHubDark } from './images/github-dark'; import { XLight } from './images/x-light'; @@ -58,6 +58,7 @@ export const FernFooter: React.FC = () => { height: 1rem; margin: 0; filter: saturate(0) opacity(0.7); + transform: translateX(-0.5rem); } .footer-logo-frame { @@ -187,13 +188,13 @@ export const FernFooter: React.FC = () => { /* Responsive Design - Mobile */ @media (max-width: 640px) { .footer { - padding: 2rem 1.5rem; + padding: 2rem 1rem; } .footer-top { flex-direction: column; gap: 1.5rem; - margin-bottom: 2rem; + margin-bottom: 1rem; } .footer-logo-frame { @@ -203,7 +204,11 @@ export const FernFooter: React.FC = () => { .footer-status { flex-direction: column; gap: 0.75rem; - padding-top: 2rem; + padding-top: 0rem; + } + + .footer-link { + width:fit-content; } .footer-links { @@ -225,6 +230,16 @@ export const FernFooter: React.FC = () => { .footer-bottom-text { order: 2; } + + .footer-column-socials { + flex-direction: row; + flex-wrap: wrap; + gap: 1rem; + } + + .soc2-badge { + padding: 0; + } } /* Tablet breakpoint */ @@ -249,8 +264,8 @@ export const FernFooter: React.FC = () => { <BuiltWithFernLight className="footer-logo-img dark:hidden" /> <BuiltWithFernDark className="footer-logo-img hidden dark:block" /> - <BuiltWithFernFrameLight className="footer-logo-frame dark:hidden" /> - <BuiltWithFernFrameDark className="footer-logo-frame hidden dark:block" /> + {/* <BuiltWithFernFrameLight className="footer-logo-frame dark:hidden" /> + <BuiltWithFernFrameDark className="footer-logo-frame hidden dark:block" /> */} </a> <div className="footer-status"> diff --git a/footer/src/FernStatus.tsx b/footer/src/FernStatus.tsx index 21bd3af7..e2cceed7 100644 --- a/footer/src/FernStatus.tsx +++ b/footer/src/FernStatus.tsx @@ -208,6 +208,13 @@ export const FernStatusWidget: React.FC = () => { 0% { transform: scale(0.6); opacity: 0.5; } 100% { transform: scale(1.5); opacity: 0; } } + + /* Responsive Design - Mobile */ + @media (max-width: 640px) { + .fern-status-widget { + padding-left: 0.5rem !important; + } + } `}</style> </div> </a>