├── .changeset ├── README.md └── config.json ├── .github └── workflows │ ├── autofix.yml │ ├── integration.yml │ └── release.yml ├── .gitignore ├── .node-version ├── .prettierignore ├── .prettierrc.cjs ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── docs ├── README.md ├── astro.config.ts ├── package.json ├── public │ └── favicon.svg ├── src │ ├── assets │ │ └── showcase │ │ │ ├── classchartsapi.github.io.png │ │ │ ├── docs.garajonai.com.png │ │ │ ├── docs.taiko.xyz.png │ │ │ ├── fxhu.kripod.dev.png │ │ │ ├── openpayments.dev.png │ │ │ └── openpodcastapi.org.png │ ├── content.config.ts │ ├── content │ │ └── docs │ │ │ ├── configuration.mdx │ │ │ ├── getting-started.mdx │ │ │ ├── index.mdx │ │ │ └── resources │ │ │ ├── showcase.mdx │ │ │ └── starlight.mdx │ ├── env.d.ts │ └── styles │ │ └── custom.css └── tsconfig.json ├── eslint.config.mjs ├── package.json ├── packages ├── starlight-openapi-docs-demo │ ├── index.ts │ ├── middleware.ts │ └── package.json └── starlight-openapi │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── components │ ├── Content.astro │ ├── ContentPicker.astro │ ├── Deprecated.astro │ ├── ExternalDocs.astro │ ├── Heading.astro │ ├── Items.astro │ ├── Key.astro │ ├── Md.astro │ ├── OperationTag.astro │ ├── Overview.astro │ ├── RequestBody.astro │ ├── Route.astro │ ├── Section.astro │ ├── Select.astro │ ├── Tag.astro │ ├── Tags.astro │ ├── Text.astro │ ├── callback │ │ ├── CallbackOperation.astro │ │ └── Callbacks.astro │ ├── example │ │ ├── Example.astro │ │ └── Examples.astro │ ├── operation │ │ ├── Operation.astro │ │ ├── OperationDescription.astro │ │ ├── OperationMethod.astro │ │ └── OperationUrl.astro │ ├── parameter │ │ ├── Parameter.astro │ │ └── Parameters.astro │ ├── response │ │ ├── Response.astro │ │ ├── ResponseExamples.astro │ │ ├── ResponseHeaders.astro │ │ └── Responses.astro │ ├── schema │ │ ├── Schema.astro │ │ ├── SchemaObject.astro │ │ ├── SchemaObjectAllOf.astro │ │ ├── SchemaObjectObject.astro │ │ ├── SchemaObjectObjectProperties.astro │ │ └── SchemaObjects.astro │ └── security │ │ ├── Security.astro │ │ ├── SecurityDefinitions.astro │ │ └── SecurityOAuth2Flow.astro │ ├── index.ts │ ├── libs │ ├── callback.ts │ ├── config.ts │ ├── content.ts │ ├── document.ts │ ├── env.d.ts │ ├── example.ts │ ├── header.ts │ ├── integration.ts │ ├── items.ts │ ├── markdown.ts │ ├── operation.ts │ ├── parameter.ts │ ├── parser.ts │ ├── path.ts │ ├── pathItem.ts │ ├── requestBody.ts │ ├── response.ts │ ├── route.ts │ ├── schema.ts │ ├── schemaObject.ts │ ├── security.ts │ ├── starlight.ts │ ├── utils.ts │ └── vite.ts │ ├── middleware.ts │ ├── package.json │ ├── playwright.config.ts │ ├── styles.css │ ├── tests │ ├── callback.test.ts │ ├── fixtures │ │ ├── DocPage.ts │ │ └── SidebarPage.ts │ ├── header.test.ts │ ├── operation.test.ts │ ├── operationTag.test.ts │ ├── overview.test.ts │ ├── parameter.test.ts │ ├── recursion.test.ts │ ├── requestBody.test.ts │ ├── response.test.ts │ ├── security.test.ts │ ├── sidebar.test.ts │ ├── test.ts │ ├── toc.test.ts │ └── webhooks.test.ts │ ├── tsconfig.json │ └── virtual.d.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── schemas ├── README.md ├── v2.0 │ ├── animals.yaml │ └── petstore-simple.yaml └── v3.0 │ ├── animals.yaml │ ├── petstore-expanded.yaml │ ├── petstore.json │ ├── recursive-simple.yaml │ └── recursive.yaml └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { "repo": "HiDeoo/starlight-openapi" } 6 | ], 7 | "commit": false, 8 | "access": "public", 9 | "baseBranch": "main", 10 | "updateInternalDependencies": "patch", 11 | "ignore": ["starlight-openapi-docs", "starlight-openapi-docs-demo"] 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/autofix.yml: -------------------------------------------------------------------------------- 1 | name: autofix.ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | workflow_call: 11 | 12 | permissions: 13 | contents: read 14 | 15 | concurrency: 16 | cancel-in-progress: true 17 | group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} 18 | 19 | jobs: 20 | autofix: 21 | name: Format code 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | 27 | - name: Install pnpm 28 | uses: pnpm/action-setup@v4 29 | with: 30 | version: 8.6.12 31 | 32 | - name: Install Node.js 33 | uses: actions/setup-node@v4 34 | with: 35 | cache: pnpm 36 | node-version: 18 37 | 38 | - name: Install dependencies 39 | run: pnpm install 40 | 41 | - name: Format code 42 | run: pnpm format 43 | 44 | - name: Run autofix 45 | uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c 46 | with: 47 | fail-fast: false 48 | -------------------------------------------------------------------------------- /.github/workflows/integration.yml: -------------------------------------------------------------------------------- 1 | name: integration 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | workflow_call: 11 | 12 | concurrency: 13 | cancel-in-progress: true 14 | group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} 15 | 16 | jobs: 17 | lint_test: 18 | name: Lint & Test 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | 24 | - name: Install pnpm 25 | uses: pnpm/action-setup@v4 26 | with: 27 | version: 8.6.12 28 | 29 | - name: Install Node.js 30 | uses: actions/setup-node@v4 31 | with: 32 | cache: pnpm 33 | node-version: 18 34 | 35 | - name: Install dependencies 36 | run: pnpm install 37 | 38 | - name: Generates docs TypeScript types 39 | run: pnpm astro sync 40 | working-directory: docs 41 | 42 | - name: Lint 43 | run: pnpm lint 44 | 45 | - name: Test 46 | run: pnpm test 47 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | changeset: 10 | name: Changeset 11 | if: ${{ github.repository_owner == 'hideoo' }} 12 | runs-on: ubuntu-latest 13 | permissions: 14 | contents: write 15 | id-token: write 16 | pull-requests: write 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v4 25 | with: 26 | version: 8.6.12 27 | 28 | - name: Install Node.js 29 | uses: actions/setup-node@v4 30 | with: 31 | cache: pnpm 32 | node-version: 18 33 | 34 | - name: Install dependencies 35 | run: pnpm install 36 | 37 | - name: Create Release Pull Request or Publish 38 | uses: changesets/action@v1 39 | with: 40 | version: pnpm run version 41 | publish: pnpm changeset publish 42 | commit: 'ci: release' 43 | title: 'ci: release' 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .astro 2 | .DS_Store 3 | .eslintcache 4 | .idea 5 | .next 6 | .turbo 7 | .vercel 8 | .vscode/* 9 | !.vscode/extensions.json 10 | !.vscode/launch.json 11 | !.vscode/settings.json 12 | !.vscode/tasks.json 13 | .vscode-test 14 | .vscode-test-web 15 | *.local 16 | *.log 17 | *.pem 18 | *.tsbuildinfo 19 | build 20 | coverage 21 | dist 22 | dist-ssr 23 | lerna-debug.log* 24 | logs 25 | next-env.d.ts 26 | node_modules 27 | npm-debug.log* 28 | out 29 | pnpm-debug.log* 30 | releases 31 | test-results 32 | yarn-debug.log* 33 | yarn-error.log* 34 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | v18.17.1 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .astro 2 | .changeset 3 | .github/blocks 4 | .next 5 | .vercel 6 | .vscode-test 7 | .vscode-test-web 8 | build 9 | coverage 10 | dist 11 | dist-ssr 12 | out 13 | pnpm-lock.yaml 14 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | const baseConfig = require('@hideoo/prettier-config') 2 | 3 | /** 4 | * @type {import('prettier').Config} 5 | */ 6 | const prettierConfig = { 7 | ...baseConfig, 8 | overrides: [ 9 | { 10 | files: '*.astro', 11 | options: { 12 | parser: 'astro', 13 | }, 14 | }, 15 | ], 16 | plugins: [require.resolve('prettier-plugin-astro')], 17 | } 18 | 19 | module.exports = prettierConfig 20 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.useFlatConfig": true, 3 | "eslint.validate": [ 4 | "javascript", 5 | "javascriptreact", 6 | "typescript", 7 | "typescriptreact", 8 | "html", 9 | "vue", 10 | "markdown", 11 | "astro" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-present, HiDeoo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | packages/starlight-openapi/README.md -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 |
2 |

starlight-openapi 🧭

3 |

Starlight plugin to generate documentation from OpenAPI/Swagger specifications.

4 |
5 | 6 |
7 | 8 | Integration Status 9 | 10 | 11 | License 12 | 13 |
14 |
15 | 16 | ## Docs 17 | 18 | Run the docs locally using [pnpm](https://pnpm.io): 19 | 20 | ```shell 21 | pnpm run dev 22 | ``` 23 | 24 | ## License 25 | 26 | Licensed under the MIT License, Copyright © HiDeoo. 27 | 28 | See [LICENSE](https://github.com/HiDeoo/starlight-openapi/blob/main/LICENSE) for more information. 29 | -------------------------------------------------------------------------------- /docs/astro.config.ts: -------------------------------------------------------------------------------- 1 | import starlight from '@astrojs/starlight' 2 | import { defineConfig } from 'astro/config' 3 | import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' 4 | import starlightOpenAPIDocsDemo from 'starlight-openapi-docs-demo' 5 | 6 | export default defineConfig({ 7 | integrations: [ 8 | starlight({ 9 | customCss: ['./src/styles/custom.css'], 10 | editLink: { 11 | baseUrl: 'https://github.com/HiDeoo/starlight-openapi/edit/main/docs/', 12 | }, 13 | plugins: [ 14 | starlightOpenAPI([ 15 | { 16 | base: 'api/petstore', 17 | schema: '../schemas/v3.0/petstore-expanded.yaml', 18 | sidebar: { collapsed: false, label: 'Petstore' }, 19 | }, 20 | { 21 | base: 'api/1password', 22 | schema: 23 | 'https://raw.githubusercontent.com/APIs-guru/openapi-directory/gh-pages/v2/specs/1password.local/connect/1.5.7/openapi.yaml', 24 | sidebar: { label: '1Password Connect' }, 25 | }, 26 | { 27 | base: 'api/giphy', 28 | schema: 29 | 'https://raw.githubusercontent.com/APIs-guru/openapi-directory/gh-pages/v2/specs/giphy.com/1.0/openapi.yaml', 30 | sidebar: { label: 'Giphy' }, 31 | }, 32 | { 33 | base: 'api/v3/petstore-simple', 34 | schema: '../schemas/v3.0/petstore.json', 35 | sidebar: { label: 'Petstore v3.0 (simple)', operations: { labels: 'operationId' } }, 36 | }, 37 | { 38 | base: 'api/v2/petstore-simple', 39 | schema: '../schemas/v2.0/petstore-simple.yaml', 40 | sidebar: { label: 'Petstore v2.0 (simple)' }, 41 | }, 42 | { 43 | base: 'api/v3/animals', 44 | schema: '../schemas/v3.0/animals.yaml', 45 | sidebar: { label: 'Animals v3.0', operations: { sort: 'alphabetical' }, tags: { sort: 'alphabetical' } }, 46 | }, 47 | { 48 | base: 'api/v2/animals', 49 | schema: '../schemas/v2.0/animals.yaml', 50 | sidebar: { label: 'Animals v2.0' }, 51 | }, 52 | { 53 | base: 'api/v3/recursive', 54 | schema: '../schemas/v3.0/recursive.yaml', 55 | sidebar: { label: 'Recursion v3.0' }, 56 | }, 57 | { 58 | base: 'api/v3/recursive-simple', 59 | schema: '../schemas/v3.0/recursive-simple.yaml', 60 | sidebar: { label: 'Simple Recursion v3.0' }, 61 | }, 62 | ]), 63 | starlightOpenAPIDocsDemo(), 64 | ], 65 | sidebar: [ 66 | { 67 | label: 'Start Here', 68 | items: [ 69 | { label: 'Getting Started', link: '/getting-started/' }, 70 | { label: 'Configuration', link: '/configuration/' }, 71 | ], 72 | }, 73 | { 74 | label: 'Resources', 75 | items: [ 76 | { label: 'Showcase', link: '/resources/showcase/' }, 77 | { label: 'Plugins and Tools', link: '/resources/starlight/' }, 78 | ], 79 | }, 80 | { 81 | label: 'Demo', 82 | items: openAPISidebarGroups, 83 | }, 84 | ], 85 | social: [ 86 | { href: 'https://bsky.app/profile/hideoo.dev', icon: 'blueSky', label: 'Bluesky' }, 87 | { href: 'https://github.com/HiDeoo/starlight-openapi', icon: 'github', label: 'GitHub' }, 88 | ], 89 | title: 'Starlight OpenAPI', 90 | }), 91 | ], 92 | image: { service: { entrypoint: 'astro/assets/services/sharp' } }, 93 | }) 94 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starlight-openapi-docs", 3 | "version": "0.8.3", 4 | "license": "MIT", 5 | "description": "Starlight plugin to generate documentation from OpenAPI/Swagger specifications.", 6 | "author": "HiDeoo (https://hideoo.dev)", 7 | "type": "module", 8 | "scripts": { 9 | "dev": "astro dev", 10 | "start": "astro dev", 11 | "build": "astro build", 12 | "preview": "astro preview", 13 | "astro": "astro", 14 | "lint": "eslint . --cache --max-warnings=0" 15 | }, 16 | "dependencies": { 17 | "@astrojs/starlight": "^0.34.0", 18 | "@hideoo/starlight-plugins-docs-components": "^0.4.0", 19 | "astro": "^5.7.4", 20 | "sharp": "^0.33.5", 21 | "starlight-openapi": "workspace:*", 22 | "starlight-openapi-docs-demo": "workspace:*" 23 | }, 24 | "engines": { 25 | "node": ">=18.17.1" 26 | }, 27 | "packageManager": "pnpm@8.6.12", 28 | "private": true, 29 | "sideEffects": false, 30 | "keywords": [ 31 | "starlight", 32 | "plugin", 33 | "openapi", 34 | "swagger", 35 | "documentation", 36 | "astro" 37 | ], 38 | "homepage": "https://github.com/HiDeoo/starlight-openapi", 39 | "repository": { 40 | "type": "git", 41 | "url": "https://github.com/HiDeoo/starlight-openapi.git", 42 | "directory": "docs" 43 | }, 44 | "bugs": "https://github.com/HiDeoo/starlight-openapi/issues" 45 | } 46 | -------------------------------------------------------------------------------- /docs/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 🧭 2 | -------------------------------------------------------------------------------- /docs/src/assets/showcase/classchartsapi.github.io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/classchartsapi.github.io.png -------------------------------------------------------------------------------- /docs/src/assets/showcase/docs.garajonai.com.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/docs.garajonai.com.png -------------------------------------------------------------------------------- /docs/src/assets/showcase/docs.taiko.xyz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/docs.taiko.xyz.png -------------------------------------------------------------------------------- /docs/src/assets/showcase/fxhu.kripod.dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/fxhu.kripod.dev.png -------------------------------------------------------------------------------- /docs/src/assets/showcase/openpayments.dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/openpayments.dev.png -------------------------------------------------------------------------------- /docs/src/assets/showcase/openpodcastapi.org.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiDeoo/starlight-openapi/ed6e878f3b873df4d63f616c436003907537f519/docs/src/assets/showcase/openpodcastapi.org.png -------------------------------------------------------------------------------- /docs/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { docsLoader } from '@astrojs/starlight/loaders' 2 | import { docsSchema } from '@astrojs/starlight/schema' 3 | import { defineCollection } from 'astro:content' 4 | 5 | export const collections = { 6 | docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), 7 | } 8 | -------------------------------------------------------------------------------- /docs/src/content/docs/configuration.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Configuration 3 | description: An overview of all the configuration options supported by the Starlight OpenAPI plugin. 4 | tableOfContents: 5 | maxHeadingLevel: 5 6 | --- 7 | 8 | The Starlight OpenAPI plugin can be configured inside the `astro.config.mjs` configuration file of your project: 9 | 10 | ```js {11} 11 | // astro.config.mjs 12 | import starlight from '@astrojs/starlight' 13 | import { defineConfig } from 'astro/config' 14 | import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' 15 | 16 | export default defineConfig({ 17 | integrations: [ 18 | starlight({ 19 | plugins: [ 20 | starlightOpenAPI([ 21 | // Configuration options go here. 22 | ]), 23 | ], 24 | title: 'My Docs', 25 | }), 26 | ], 27 | }) 28 | ``` 29 | 30 | ## Plugin configuration 31 | 32 | The Starlight OpenAPI plugin accepts an array of objects where each object represents a configuration for a specific OpenAPI/Swagger schema. 33 | 34 | A configuration object can have the following properties: 35 | 36 | ### `base` (required) 37 | 38 | **Type:** `string` 39 | 40 | The base path containing the generated documentation, e.g. `'api/petstore'`. 41 | 42 | ### `schema` (required) 43 | 44 | **Type:** `string` 45 | 46 | The OpenAPI/Swagger schema path or URL. 47 | 48 | ### `sidebar` 49 | 50 | The generated sidebar group configuration which accepts the following properties: 51 | 52 | #### `collapsed` 53 | 54 | **Type:** `boolean` 55 | **Default:** `true` 56 | 57 | Wheter the generated documentation sidebar group should be collapsed by default or not. 58 | 59 | #### `label` 60 | 61 | **Type:** `string` 62 | **Default:** the OpenAPI document title 63 | 64 | The generated documentation sidebar group label. 65 | 66 | #### `operations` 67 | 68 | The generated documentation operations sidebar links configuration which accepts the following properties: 69 | 70 | ##### `badges` 71 | 72 | **Type:** `boolean` 73 | **Default:** `false` 74 | 75 | Defines if the sidebar should display badges next to operation links with the associated HTTP method. 76 | 77 | ##### `labels` 78 | 79 | **Type:** `'operationId' | 'summary'` 80 | **Default:** `'summary'` 81 | 82 | Whether the operation sidebar link labels should use the operation ID or summary. 83 | 84 | By default, the summary is used as the operation sidebar label and falls back to the operation ID if no summary is provided. 85 | Setting this option to `'operationId'` will always use the operation ID as the operation sidebar label. 86 | 87 | ##### `sort` 88 | 89 | **Type:** `'alphabetical' | 'document'` 90 | **Default:** `'document'` 91 | 92 | Defines the sorting method for the operation sidebar links. 93 | 94 | By default, the operation sidebar links are sorted in the order they appear in the OpenAPI document. 95 | 96 | #### `tags` 97 | 98 | The generated documentation tags sidebar groups configuration which accepts the following properties: 99 | 100 | ##### `sort` 101 | 102 | **Type:** `'alphabetical' | 'document'` 103 | **Default:** `'document'` 104 | 105 | Defines the sorting method for the tag sidebar groups. 106 | 107 | By default, the tag sidebar groups are sorted in the order they appear in the OpenAPI document. 108 | 109 | ## Multiple schemas 110 | 111 | You can generate documentation for multiple OpenAPI/Swagger schemas by passing multiple objects to the plugin configuration. 112 | 113 | ```js {11-21} 114 | // astro.config.mjs 115 | import starlight from '@astrojs/starlight' 116 | import { defineConfig } from 'astro/config' 117 | import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' 118 | 119 | export default defineConfig({ 120 | integrations: [ 121 | starlight({ 122 | plugins: [ 123 | starlightOpenAPI([ 124 | { 125 | base: 'api/petstore', 126 | schema: '../schemas/api-schema.yaml', 127 | sidebar: { label: 'My API' }, 128 | }, 129 | { 130 | base: 'api/1password', 131 | schema: 132 | 'https://raw.githubusercontent.com/APIs-guru/openapi-directory/gh-pages/v2/specs/1password.local/connect/1.5.7/openapi.yaml', 133 | sidebar: { label: '1Password Connect' }, 134 | }, 135 | ]), 136 | ], 137 | title: 'My Docs', 138 | }), 139 | ], 140 | }) 141 | ``` 142 | 143 | ## Sidebar groups 144 | 145 | The `openAPISidebarGroups` export can be used in your Starlight [sidebar configuration](https://starlight.astro.build/reference/configuration/#sidebar) to add the generated documentation sidebar groups to the sidebar. 146 | 147 | ```js {24-25} "{ openAPISidebarGroups }" 148 | // astro.config.mjs 149 | import starlight from '@astrojs/starlight' 150 | import { defineConfig } from 'astro/config' 151 | import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' 152 | 153 | export default defineConfig({ 154 | integrations: [ 155 | starlight({ 156 | plugins: [ 157 | // Generate the OpenAPI documentation pages. 158 | starlightOpenAPI([ 159 | { 160 | base: 'api', 161 | schema: '../schemas/api-schema.yaml', 162 | sidebar: { label: 'My API' }, 163 | }, 164 | ]), 165 | ], 166 | sidebar: [ 167 | { 168 | label: 'Guides', 169 | items: [{ label: 'Example Guide', link: '/guides/example/' }], 170 | }, 171 | // Add the generated sidebar groups to the sidebar. 172 | ...openAPISidebarGroups, 173 | ], 174 | title: 'My Docs', 175 | }), 176 | ], 177 | }) 178 | ``` 179 | -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | description: Learn how to generate documentation from OpenAPI/Swagger specifications using the Starlight OpenAPI plugin. 4 | --- 5 | 6 | A [Starlight](https://starlight.astro.build) plugin to generate documentation from OpenAPI/Swagger specifications. 7 | 8 | - Support for [Swagger 2.0](https://swagger.io/specification/v2/), [OpenAPI 3.0](https://swagger.io/specification/v3/) and [OpenAPI 3.1](https://swagger.io/specification/) specifications. 9 | - Support for local and remote schemas. 10 | - Configurable sidebar label and sidebar group collapsing. 11 | 12 | ## Prerequisites 13 | 14 | You will need to have a Starlight website set up. 15 | If you don't have one yet, you can follow the ["Getting Started"](https://starlight.astro.build/getting-started) guide in the Starlight docs to create one. 16 | 17 | ## Installation 18 | 19 | import { Steps } from '@astrojs/starlight/components' 20 | import { PackageManagers } from '@hideoo/starlight-plugins-docs-components' 21 | 22 | 23 | 24 | 1. Starlight OpenAPI is a Starlight [plugin](https://starlight.astro.build/reference/plugins/). Install it using your favorite package manager: 25 | 26 | 27 | 28 | 2. Configure the plugin in your Starlight [configuration](https://starlight.astro.build/reference/configuration/#plugins) in the `astro.config.mjs` file. 29 | 30 | The following example shows how to specify a schema file and add the generated sidebar group to the sidebar: 31 | 32 | ```diff lang="js" 33 | // astro.config.mjs 34 | import starlight from '@astrojs/starlight' 35 | import { defineConfig } from 'astro/config' 36 | +import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' 37 | 38 | export default defineConfig({ 39 | integrations: [ 40 | starlight({ 41 | + plugins: [ 42 | + // Generate the OpenAPI documentation pages. 43 | + starlightOpenAPI([ 44 | + { 45 | + base: 'api', 46 | + schema: '../schemas/api-schema.yaml', 47 | + }, 48 | + ]), 49 | + ], 50 | sidebar: [ 51 | { 52 | label: 'Guides', 53 | items: [{ label: 'Example Guide', link: '/guides/example/' }], 54 | }, 55 | + // Add the generated sidebar group to the sidebar. 56 | + ...openAPISidebarGroups, 57 | ], 58 | title: 'My Docs', 59 | }), 60 | ], 61 | }) 62 | ``` 63 | 64 | 3. [Start the development server](https://starlight.astro.build/getting-started/#start-the-development-server) to preview the generated documentation. 65 | 66 | 67 | 68 | The Starlight OpenAPI plugin behavior can be tweaked using various [configuration options](/configuration). 69 | -------------------------------------------------------------------------------- /docs/src/content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Starlight OpenAPI 3 | description: Starlight plugin to generate documentation from OpenAPI/Swagger specifications. 4 | head: 5 | - tag: title 6 | content: Starlight OpenAPI 7 | template: splash 8 | editUrl: false 9 | lastUpdated: false 10 | hero: 11 | tagline: Starlight plugin to generate documentation from OpenAPI/Swagger specifications. 12 | image: 13 | html: '🧭' 14 | actions: 15 | - text: Getting Started 16 | link: /getting-started/ 17 | icon: rocket 18 | - text: Demo 19 | link: /api/petstore/operations/addpet/ 20 | icon: right-arrow 21 | variant: minimal 22 | --- 23 | 24 | import { Card, CardGrid } from '@astrojs/starlight/components' 25 | 26 | ## Next steps 27 | 28 | 29 | 30 | Check the [getting started guide](/getting-started/) for installation instructions. 31 | 32 | 33 | Edit your config in `astro.config.mjs`. 34 | 35 | 36 | Add your OpenAPI schema to your project. 37 | 38 | 39 | Learn more in the [Starlight OpenAPI Docs](/getting-started/). 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/src/content/docs/resources/showcase.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Showcase 3 | description: Discover Starlight project using the Starlight OpenAPI plugin. 4 | --- 5 | 6 | import { ShowcaseIntro, Showcase } from '@hideoo/starlight-plugins-docs-components' 7 | 8 | 12 | 13 | ## Sites 14 | 15 | Starlight OpenAPI is already being used in production. These are some of the sites around the web: 16 | 17 | 51 | 52 | See all the [public project repos using Starlight OpenAPI on GitHub](https://github.com/hideoo/starlight-openapi/network/dependents). 53 | -------------------------------------------------------------------------------- /docs/src/content/docs/resources/starlight.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Starlight Plugins and Tools 3 | description: Discover other Starlight plugins, components and tools developed by HiDeoo. 4 | --- 5 | 6 | import { ResourcesIntro, Resources } from '@hideoo/starlight-plugins-docs-components' 7 | 8 | 9 | 10 | ## Plugins 11 | 12 | 13 | 14 | ## Components 15 | 16 | 17 | 18 | ## Tools 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs/src/styles/custom.css: -------------------------------------------------------------------------------- 1 | .hero-html { 2 | --size: 10rem; 3 | 4 | font-size: var(--size); 5 | justify-content: center; 6 | line-height: var(--size); 7 | } 8 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import hideoo from '@hideoo/eslint-config' 2 | 3 | export default hideoo([ 4 | { 5 | rules: { 6 | '@typescript-eslint/no-duplicate-type-constituents': 'off', 7 | }, 8 | }, 9 | ]) 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starlight-openapi-monorepo", 3 | "version": "0.8.3", 4 | "license": "MIT", 5 | "description": "Starlight plugin to generate documentation from OpenAPI/Swagger specifications.", 6 | "author": "HiDeoo (https://hideoo.dev)", 7 | "type": "module", 8 | "scripts": { 9 | "test": "pnpm --stream -r test", 10 | "lint": "astro check --noSync --minimumSeverity warning && pnpm -r lint", 11 | "format": "prettier -w --cache --ignore-unknown .", 12 | "version": "pnpm changeset version && pnpm i --no-frozen-lockfile" 13 | }, 14 | "devDependencies": { 15 | "@astrojs/check": "^0.9.4", 16 | "@changesets/changelog-github": "^0.5.0", 17 | "@changesets/cli": "^2.27.10", 18 | "@hideoo/eslint-config": "^4.0.0", 19 | "@hideoo/prettier-config": "^2.0.0", 20 | "@hideoo/tsconfig": "^2.0.1", 21 | "astro": "^5.7.4", 22 | "eslint": "^9.17.0", 23 | "prettier": "^3.4.2", 24 | "prettier-plugin-astro": "^0.14.1", 25 | "typescript": "^5.7.2" 26 | }, 27 | "engines": { 28 | "node": ">=18.17.1" 29 | }, 30 | "packageManager": "pnpm@8.6.12", 31 | "private": true, 32 | "sideEffects": false, 33 | "keywords": [ 34 | "starlight", 35 | "plugin", 36 | "openapi", 37 | "swagger", 38 | "documentation", 39 | "astro" 40 | ], 41 | "homepage": "https://github.com/HiDeoo/starlight-openapi", 42 | "repository": { 43 | "type": "git", 44 | "url": "https://github.com/HiDeoo/starlight-openapi.git" 45 | }, 46 | "bugs": "https://github.com/HiDeoo/starlight-openapi/issues" 47 | } 48 | -------------------------------------------------------------------------------- /packages/starlight-openapi-docs-demo/index.ts: -------------------------------------------------------------------------------- 1 | import type { StarlightPlugin } from '@astrojs/starlight/types' 2 | 3 | export default function starlightOpenAPIDocsDemoPlugin(): StarlightPlugin { 4 | return { 5 | name: 'starlight-openapi-docs-demo-plugin', 6 | hooks: { 7 | 'config:setup': ({ addRouteMiddleware }) => { 8 | if (process.env['TEST']) return 9 | 10 | addRouteMiddleware({ entrypoint: 'starlight-openapi-docs-demo/middleware', order: 'post' }) 11 | }, 12 | }, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/starlight-openapi-docs-demo/middleware.ts: -------------------------------------------------------------------------------- 1 | import { defineRouteMiddleware, type StarlightRouteData } from '@astrojs/starlight/route-data' 2 | 3 | export const onRequest = defineRouteMiddleware((context) => { 4 | const { starlightRoute } = context.locals 5 | const { sidebar } = starlightRoute 6 | 7 | starlightRoute.sidebar = sidebar.map((item) => { 8 | if (isSidebarGroup(item) && item.label === 'Demo') { 9 | return { ...item, entries: item.entries.slice(0, 3) } 10 | } 11 | 12 | return item 13 | }) 14 | }) 15 | 16 | function isSidebarGroup(item: SidebarItem): item is SidebarGroup { 17 | return item.type === 'group' 18 | } 19 | 20 | type SidebarItem = StarlightRouteData['sidebar'][number] 21 | export type SidebarGroup = Extract 22 | -------------------------------------------------------------------------------- /packages/starlight-openapi-docs-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starlight-openapi-docs-demo", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "author": "HiDeoo (https://hideoo.dev)", 6 | "type": "module", 7 | "exports": { 8 | ".": "./index.ts", 9 | "./middleware": "./middleware.ts", 10 | "./package.json": "./package.json" 11 | }, 12 | "peerDependencies": { 13 | "@astrojs/starlight": ">=0.34.0" 14 | }, 15 | "engines": { 16 | "node": ">=18.17.1" 17 | }, 18 | "packageManager": "pnpm@8.6.12", 19 | "private": true, 20 | "sideEffects": false, 21 | "keywords": [ 22 | "starlight", 23 | "plugin", 24 | "openapi", 25 | "swagger", 26 | "documentation", 27 | "astro" 28 | ], 29 | "homepage": "https://github.com/HiDeoo/starlight-openapi", 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/HiDeoo/starlight-openapi.git", 33 | "directory": "packages/starlight-openapi-docs-demo" 34 | }, 35 | "bugs": "https://github.com/HiDeoo/starlight-openapi/issues" 36 | } 37 | -------------------------------------------------------------------------------- /packages/starlight-openapi/.npmignore: -------------------------------------------------------------------------------- 1 | .eslintcache 2 | .prettierignore 3 | playwright.config.ts 4 | tests 5 | test-results 6 | tsconfig.json 7 | tsconfig.tsbuildinfo 8 | -------------------------------------------------------------------------------- /packages/starlight-openapi/README.md: -------------------------------------------------------------------------------- 1 |
2 |

starlight-openapi 🧭

3 |

Starlight plugin to generate documentation from OpenAPI/Swagger specifications.

4 |

5 | 6 | Screenshot of starlight-openapi 7 | 8 |

9 |
10 | 11 |
12 | 13 | Integration Status 14 | 15 | 16 | License 17 | 18 |
19 |
20 | 21 | ## Getting Started 22 | 23 | Want to get started immediately? Check out the [getting started guide](https://starlight-openapi.vercel.app/getting-started/) or check out the [demo](https://starlight-openapi.vercel.app/api/petstore/operations/addpet/) to see the plugin in action. 24 | 25 | ## Features 26 | 27 | A [Starlight](https://starlight.astro.build) plugin to generate documentation from OpenAPI/Swagger specifications. 28 | 29 | - Support for [Swagger 2.0](https://swagger.io/specification/v2/), [OpenAPI 3.0](https://swagger.io/specification/v3/) and [OpenAPI 3.1](https://swagger.io/specification/) specifications. 30 | - Support for local and remote schemas. 31 | - Configurable sidebar label and sidebar group collapsing. 32 | 33 | ## License 34 | 35 | Licensed under the MIT License, Copyright © HiDeoo. 36 | 37 | See [LICENSE](https://github.com/HiDeoo/starlight-openapi/blob/main/LICENSE) for more information. 38 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Content.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Content } from '../libs/content' 3 | import { isExamples } from '../libs/example' 4 | import { isSchemaObject } from '../libs/schemaObject' 5 | 6 | import ContentPicker from './ContentPicker.astro' 7 | import Schema from './schema/Schema.astro' 8 | 9 | interface Props { 10 | content: Content 11 | } 12 | 13 | const { content } = Astro.props 14 | --- 15 | 16 | 17 | { 18 | Object.entries(content).map(([type, media], index) => { 19 | return ( 20 | 28 | ) 29 | }) 30 | } 31 | 32 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/ContentPicker.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Select from './Select.astro' 3 | 4 | interface Props { 5 | label: string 6 | types: string[] | undefined 7 | } 8 | 9 | const { label, types } = Astro.props 10 | --- 11 | 12 | 13 | 46 | 47 | 48 | ) : openAPIV3RequestBody ? ( 49 | 50 | ) : null} 51 | 52 | ) 53 | } 54 | 55 | 63 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Route.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro' 3 | import OpenAPIParser from '@readme/openapi-parser' 4 | import type { InferGetStaticPropsType } from 'astro' 5 | 6 | import { getSchemaStaticPaths } from '../libs/route' 7 | import { getPageProps } from '../libs/starlight' 8 | 9 | import Operation from './operation/Operation.astro' 10 | import OperationTag from './OperationTag.astro' 11 | import Overview from './Overview.astro' 12 | 13 | export const prerender = true 14 | 15 | export function getStaticPaths() { 16 | return getSchemaStaticPaths() 17 | } 18 | 19 | type Props = InferGetStaticPropsType 20 | 21 | const { schema, type } = Astro.props 22 | 23 | schema.document = await OpenAPIParser.dereference(schema.document) 24 | 25 | const isOverview = type === 'overview' 26 | const isOperationTag = type === 'operation-tag' 27 | 28 | const title = isOverview || isOperationTag ? 'Overview' : Astro.props.operation.title 29 | --- 30 | 31 | 39 | { 40 | isOverview ? ( 41 | 42 | ) : isOperationTag ? ( 43 | 44 | ) : ( 45 | 46 | ) 47 | } 48 | 49 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Section.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { slug } from '../libs/path' 3 | 4 | import Heading from './Heading.astro' 5 | 6 | export interface SectionHeadingProps { 7 | level?: number 8 | prefix?: string | undefined 9 | } 10 | 11 | interface Props extends SectionHeadingProps { 12 | empty?: boolean 13 | title: string 14 | } 15 | 16 | const { empty, level = 3, prefix = '', title } = Astro.props 17 | --- 18 | 19 |
20 | 21 | {title} 22 | 23 | { 24 | Astro.slots.has('pre-panel') && ( 25 |
26 | 27 |
28 | ) 29 | } 30 | { 31 | !empty && ( 32 |
33 | 34 |
35 | ) 36 | } 37 | { 38 | Astro.slots.has('post-panel') && ( 39 |
40 | 41 |
42 | ) 43 | } 44 |
45 | 46 | 74 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Select.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Icon } from '@astrojs/starlight/components' 3 | 4 | interface Props { 5 | label: string 6 | options: string[] | undefined 7 | } 8 | 9 | const { label, options } = Astro.props 10 | --- 11 | 12 | { 13 | options && options.length > 0 && ( 14 | 23 | ) 24 | } 25 | 26 | 59 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Tag.astro: -------------------------------------------------------------------------------- 1 | {' '} 2 | 3 | 4 | 5 | 6 | 15 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Tags.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Tag from './Tag.astro' 3 | 4 | interface Props { 5 | label?: string 6 | tags: unknown[] 7 | } 8 | 9 | const { label, tags: allTags } = Astro.props 10 | 11 | const tags = allTags.filter((tag): tag is string | number => typeof tag === 'string' || typeof tag === 'number') 12 | --- 13 | 14 | { 15 | tags.length > 0 && ( 16 |
17 | {label && <>{label}} 18 | {tags.map((tag) => { 19 | if (typeof tag === 'string' && tag.length === 0) { 20 | return "" 21 | } 22 | 23 | return {tag} 24 | })} 25 |
26 | ) 27 | } 28 | 29 | 38 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/Text.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Tag from './Tag.astro' 3 | 4 | interface Props { 5 | label?: string 6 | tag?: boolean 7 | } 8 | 9 | const { label, tag } = Astro.props 10 | 11 | const text: string | undefined = await Astro.slots.render('default') 12 | --- 13 | 14 | { 15 | text && text.length > 0 && ( 16 |

17 | {label && {label}: } 18 | {tag ? ( 19 | 20 | 21 | 22 | ) : ( 23 | 24 | )} 25 |

26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/callback/CallbackOperation.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Callback } from '../../libs/callback' 3 | import type { CallbackOperation } from '../../libs/operation' 4 | import { getParametersByLocation } from '../../libs/parameter' 5 | import type { Schema } from '../../libs/schema' 6 | import Deprecated from '../Deprecated.astro' 7 | import ExternalDocs from '../ExternalDocs.astro' 8 | import Md from '../Md.astro' 9 | import OperationDescription from '../operation/OperationDescription.astro' 10 | import Parameters from '../parameter/Parameters.astro' 11 | import RequestBody from '../RequestBody.astro' 12 | import Responses from '../response/Responses.astro' 13 | import type { SectionHeadingProps } from '../Section.astro' 14 | import Security from '../security/Security.astro' 15 | 16 | interface Props { 17 | callback: Callback 18 | id: string 19 | operation: CallbackOperation 20 | schema: Schema 21 | url: string 22 | } 23 | 24 | const { callback, id, operation: callbackOperation, schema, url } = Astro.props 25 | const { operation } = callbackOperation 26 | 27 | const sectionHeadingProps: SectionHeadingProps = { level: 4, prefix: id } 28 | const parameters = getParametersByLocation(operation.parameters, callback.parameters) 29 | --- 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/callback/Callbacks.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCallbackObject, getCallbacks } from '../../libs/callback' 3 | import { getCallbackOperations, type Operation as CallbacksOperation } from '../../libs/operation' 4 | import { slug } from '../../libs/path' 5 | import type { Schema } from '../../libs/schema' 6 | import CallbackOperation from '../callback/CallbackOperation.astro' 7 | import Heading from '../Heading.astro' 8 | import Md from '../Md.astro' 9 | 10 | interface Props { 11 | operation: CallbacksOperation 12 | schema: Schema 13 | } 14 | 15 | const { operation, schema } = Astro.props 16 | 17 | const callbacks = getCallbacks(operation) 18 | const identifiers = Object.keys(callbacks ?? {}) 19 | --- 20 | 21 | { 22 | callbacks && identifiers.length > 0 && ( 23 | <> 24 | 25 | Callbacks 26 | 27 | {identifiers.map((identifier) => { 28 | const callbackObject = getCallbackObject(callbacks, identifier) 29 | const id = slug(identifier) 30 | 31 | return ( 32 | <> 33 | 34 | {identifier} 35 | 36 | {Object.entries(callbackObject).map(([url, callback]) => { 37 | const operations = getCallbackOperations(callback) 38 | 39 | return ( 40 | <> 41 | {callback.summary &&

{callback.summary}

} 42 | 43 | {operations.map((operation) => ( 44 | 45 | ))} 46 | 47 | ) 48 | })} 49 | 50 | ) 51 | })} 52 | 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/example/Example.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Code } from '@astrojs/starlight/components' 3 | import { parseTemplate, type PrimitiveValue } from 'url-template' 4 | 5 | import type { ExampleV3 } from '../../libs/example' 6 | import type { Parameter } from '../../libs/parameter' 7 | import Md from '../Md.astro' 8 | import Text from '../Text.astro' 9 | 10 | interface Props { 11 | example?: ExampleV3 12 | parameter?: Parameter | undefined 13 | raw?: ExampleV3['value'] 14 | type?: string | undefined 15 | } 16 | 17 | const { example, parameter, raw, type } = Astro.props 18 | 19 | const exampleToRender = raw === undefined ? example : { value: raw } 20 | 21 | function getExampleValue(value: unknown): string { 22 | return parameter?.in === 'query' ? getQueryParameterValue(parameter, value) : getFallbackValue(value) 23 | } 24 | 25 | function getFallbackValue(value: unknown): string { 26 | switch (typeof value) { 27 | case 'string': { 28 | return value 29 | } 30 | case 'boolean': 31 | case 'number': { 32 | return value.toString() 33 | } 34 | default: { 35 | return JSON.stringify(value, null, 2) 36 | } 37 | } 38 | } 39 | 40 | function getQueryParameterValue(parameter: Parameter, value: unknown): string { 41 | switch (parameter.style) { 42 | case 'deepObject': { 43 | if (!value || typeof value !== 'object' || !parameter.explode) { 44 | return getFallbackValue(value) 45 | } 46 | 47 | return `?${Object.keys(value) 48 | .map((key) => `${parameter.name}[${key}]=${value[key as keyof typeof value]}`) 49 | .join('&')}` 50 | } 51 | case 'form': { 52 | return getFormValue(parameter, value) 53 | } 54 | case 'pipeDelimited': 55 | case 'spaceDelimited': { 56 | if (!Array.isArray(value)) { 57 | return getFallbackValue(value) 58 | } 59 | 60 | return parameter.explode 61 | ? getFormValue(parameter, value) 62 | : `?${parameter.name}=${value.join(parameter.style === 'pipeDelimited' ? '|' : '%20')}` 63 | } 64 | default: { 65 | return getFallbackValue(value) 66 | } 67 | } 68 | } 69 | 70 | function getFormValue(parameter: Parameter, value: unknown) { 71 | // https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.8 72 | return parseTemplate(`{?${parameter.name}${parameter.explode ? '*' : ''}}`).expand({ 73 | [parameter.name]: value as PrimitiveValue, 74 | }) 75 | } 76 | 77 | function getExampleLang(code: string, type: string | undefined) { 78 | switch (type) { 79 | case 'application/json': { 80 | return 'json' 81 | } 82 | default: { 83 | try { 84 | JSON.parse(code) 85 | return 'json' 86 | } catch { 87 | // Fallback to plain text when failing to parse the code as JSON. 88 | } 89 | return 'plaintext' 90 | } 91 | } 92 | } 93 | 94 | const code = exampleToRender ? getExampleValue(exampleToRender.value).trim() : '' 95 | --- 96 | 97 | { 98 | exampleToRender && ( 99 | <> 100 | {exampleToRender.summary} 101 | 102 | {exampleToRender.externalValue && ( 103 | 104 | {exampleToRender.externalValue} 105 | 106 | )} 107 | {code.length > 0 && } 108 | 109 | ) 110 | } 111 | 112 | 124 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/example/Examples.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { ExamplesV3 } from '../../libs/example' 3 | import type { Parameter } from '../../libs/parameter' 4 | import ContentPicker from '../ContentPicker.astro' 5 | 6 | import Example from './Example.astro' 7 | 8 | export interface Props { 9 | example: unknown | undefined 10 | examples: ExamplesV3 | undefined 11 | parameter?: Parameter | undefined 12 | type?: string | undefined 13 | } 14 | 15 | const { example, examples, parameter, type } = Astro.props 16 | --- 17 | 18 | { 19 | example || examples ? ( 20 | examples ? ( 21 | <> 22 |
Examples
23 | 24 | {Object.entries(examples).map(([exampleType, data], index) => ( 25 | 28 | ))} 29 | 30 | 31 | ) : ( 32 | <> 33 |
Example
34 | 35 | 36 | ) 37 | ) : null 38 | } 39 | 40 | 45 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/operation/Operation.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getOperationURLs, type PathItemOperation } from '../../libs/operation' 3 | import { getParametersByLocation } from '../../libs/parameter' 4 | import type { Schema } from '../../libs/schema' 5 | import Callbacks from '../callback/Callbacks.astro' 6 | import Deprecated from '../Deprecated.astro' 7 | import ExternalDocs from '../ExternalDocs.astro' 8 | import Md from '../Md.astro' 9 | import Parameters from '../parameter/Parameters.astro' 10 | import RequestBody from '../RequestBody.astro' 11 | import Responses from '../response/Responses.astro' 12 | import Security from '../security/Security.astro' 13 | 14 | import OperationDescription from './OperationDescription.astro' 15 | 16 | interface Props { 17 | operation: PathItemOperation 18 | schema: Schema 19 | } 20 | 21 | const { operation: pathItemOperation, schema } = Astro.props 22 | const { operation } = pathItemOperation 23 | const urls = getOperationURLs(schema.document, pathItemOperation) 24 | const parameters = getParametersByLocation(operation.parameters, pathItemOperation.pathItem.parameters) 25 | --- 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/operation/OperationDescription.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Icon } from '@astrojs/starlight/components' 3 | 4 | import type { OperationURL, PathItemOperation } from '../../libs/operation' 5 | 6 | import OperationMethod from './OperationMethod.astro' 7 | import OperationUrl from './OperationUrl.astro' 8 | 9 | interface Props { 10 | method: PathItemOperation['method'] 11 | path: PathItemOperation['path'] 12 | urls?: OperationURL[] 13 | } 14 | 15 | const { method, path, urls } = Astro.props 16 | --- 17 | 18 |
19 | { 20 | path ? ( 21 | urls && urls.length > 0 ? ( 22 |
23 | 24 | 25 | 26 | 27 |
    28 | {urls.map(({ description, url }) => ( 29 | 30 | ))} 31 |
32 |
33 | ) : ( 34 |
35 | 36 |
37 | ) 38 | ) : ( 39 | 40 | ) 41 | } 42 |
43 | 44 | 105 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/operation/OperationMethod.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { OperationHttpMethod } from '../../libs/operation' 3 | 4 | interface Props { 5 | method: OperationHttpMethod 6 | path?: string 7 | } 8 | 9 | const { method, path } = Astro.props 10 | --- 11 | 12 |
13 |
{method.toUpperCase()}
14 |
{path}
15 |
16 | 17 | 79 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/operation/OperationUrl.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { HTMLAttributes } from 'astro/types' 3 | 4 | interface Props { 5 | description: string | undefined 6 | url: string 7 | } 8 | 9 | const { description, url } = Astro.props 10 | 11 | const inputAttributes: HTMLAttributes<'input'> = { 12 | readonly: true, 13 | type: 'text', 14 | value: url, 15 | } 16 | --- 17 | 18 |
  • 19 | { 20 | description && description.length > 0 ? ( 21 | 25 | ) : ( 26 | 27 | ) 28 | } 29 |
  • 30 | 31 | 52 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/parameter/Parameter.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { isOpenAPIV2Items } from '../../libs/items' 3 | import type { Parameter } from '../../libs/parameter' 4 | import { isParameterWithSchemaObject } from '../../libs/schemaObject' 5 | import Content from '../Content.astro' 6 | import Items from '../Items.astro' 7 | import Key from '../Key.astro' 8 | import Md from '../Md.astro' 9 | import Schema from '../schema/Schema.astro' 10 | 11 | interface Props { 12 | parameter: Parameter 13 | } 14 | 15 | const { parameter } = Astro.props 16 | --- 17 | 18 | 19 | { 20 | isOpenAPIV2Items(parameter) ? ( 21 | <> 22 | 23 | 24 | 25 | ) : parameter.content ? ( 26 | <> 27 | 28 | 29 | 30 | ) : isParameterWithSchemaObject(parameter) ? ( 31 | 38 | ) : null 39 | } 40 | 41 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/parameter/Parameters.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { getParametersByLocation } from '../../libs/parameter' 3 | import { capitalize } from '../../libs/utils' 4 | import Heading from '../Heading.astro' 5 | import Section, { type SectionHeadingProps } from '../Section.astro' 6 | 7 | import Parameter from './Parameter.astro' 8 | 9 | interface Props extends SectionHeadingProps { 10 | parameters: ReturnType 11 | } 12 | 13 | const { level = 2, parameters, prefix } = Astro.props 14 | --- 15 | 16 | { 17 | parameters.size > 0 && ( 18 | <> 19 | 20 | Parameters 21 | 22 | {[...parameters.entries()].map(([location, parameters]) => ( 23 |
    24 | {[...parameters.values()].map((parameter) => ( 25 | 26 | ))} 27 |
    28 | ))} 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /packages/starlight-openapi/components/response/Response.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { isOpenAPIV2ResponseWithExamples } from '../../libs/example' 3 | import { isResponseWithHeaders } from '../../libs/header' 4 | import type { Operation } from '../../libs/operation' 5 | import { getOpenAPIV2OperationProduces } from '../../libs/requestBody' 6 | import { 7 | getOpenAPIV2ResponseSchema, 8 | getOpenAPIV3ResponseContent, 9 | type Response, 10 | type Responses, 11 | } from '../../libs/response' 12 | import type { Schema } from '../../libs/schema' 13 | import Content from '../Content.astro' 14 | import Md from '../Md.astro' 15 | import SchemaObject from '../schema/SchemaObject.astro' 16 | import Section, { type SectionHeadingProps } from '../Section.astro' 17 | import Select from '../Select.astro' 18 | 19 | import ResponseExamples from './ResponseExamples.astro' 20 | import ResponseHeaders from './ResponseHeaders.astro' 21 | 22 | interface Props extends SectionHeadingProps { 23 | name: keyof Responses 24 | operation: Operation 25 | response: Response 26 | schema: Schema 27 | } 28 | 29 | const { name, operation, response, schema, ...sectionHeadingProps } = Astro.props 30 | 31 | const openAPIV2ResponseSchema = getOpenAPIV2ResponseSchema(response) 32 | const openAPIV3ResponseContent = getOpenAPIV3ResponseContent(response) 33 | 34 | const produces = getOpenAPIV2OperationProduces(schema, operation) 35 | 36 | const isEmpty = !openAPIV2ResponseSchema && !openAPIV3ResponseContent 37 | --- 38 | 39 |
    40 | 41 | { 42 | openAPIV2ResponseSchema ? ( 43 | <> 44 |