feat: automate mgmt api spec update (#26655)
* fix: correct mgmt api naming * feat: new command to generate mgmt api sections * feat: sort section items * chore: tidy up * fix: add generate sections to the default command * feat: add gha to auto update mgmt api docs * chore: tidy up * fix: operationId logic to support self-hosting references * chore: update latest mgmt api specs * chore: update latest mgmt api specs
This commit is contained in:
40
.github/workflows/docs-mgmt-api-update.yml
vendored
Normal file
40
.github/workflows/docs-mgmt-api-update.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Update Mgmt Api Docs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 00:00 UTC every Monday
|
||||
- cron: '0 0 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-docs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies in apps/docs/spec/parser directory
|
||||
working-directory: apps/docs/spec/parser
|
||||
run: npm install
|
||||
|
||||
- name: Change to apps/docs/spec directory and run make command
|
||||
working-directory: apps/docs/spec
|
||||
run: make download.api.v1 dereference.api.v1 generate.sections.api.v1 format
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: 'feat: update mgmt api docs'
|
||||
title: 'feat: update mgmt api docs'
|
||||
body: 'This PR updates mgmt api docs automatically.'
|
||||
branch: 'gha/auto-update-mgmt-api-docs'
|
||||
base: 'master'
|
||||
@@ -8,7 +8,7 @@ import ApiSchema from '~/components/ApiSchema'
|
||||
|
||||
const MgmtApiOperationSection = (props) => {
|
||||
const operation = props.spec.operations.find((x: any) => x.operationId === props.funcData.id)
|
||||
const bodyContentTypes = Object.keys(operation.requestBody?.content ?? {})
|
||||
const bodyContentTypes = Object.keys(operation?.requestBody?.content ?? {})
|
||||
const [selectedContentType, setSelectedContentType] = useState(bodyContentTypes[0] || undefined)
|
||||
|
||||
const hasBodyArray =
|
||||
|
||||
@@ -227,7 +227,11 @@ export type enrichedOperation = OpenAPIV3.OperationObject & {
|
||||
tags?: []
|
||||
}
|
||||
|
||||
export function gen_v3(spec: OpenAPIV3.Document, dest: string, { apiUrl }: { apiUrl: string }) {
|
||||
export function gen_v3(
|
||||
spec: OpenAPIV3.Document,
|
||||
dest: string,
|
||||
{ apiUrl, type }: { apiUrl: string; type?: 'client-lib' | 'cli' | 'api' | 'mgmt-api' }
|
||||
) {
|
||||
const specLayout = spec.tags || []
|
||||
const operations: enrichedOperation[] = []
|
||||
|
||||
@@ -236,12 +240,15 @@ export function gen_v3(spec: OpenAPIV3.Document, dest: string, { apiUrl }: { api
|
||||
|
||||
toArrayWithKey(val!, 'operation').forEach((o) => {
|
||||
const operation = o as v3OperationWithPath
|
||||
const operationId =
|
||||
type === 'mgmt-api' && isValidSlug(operation.operationId)
|
||||
? operation.operationId
|
||||
: slugify(operation.summary!)
|
||||
const enriched = {
|
||||
...operation,
|
||||
path: key,
|
||||
fullPath,
|
||||
operationId: slugify(operation.summary!),
|
||||
|
||||
operationId,
|
||||
responseList: toArrayWithKey(operation.responses!, 'responseCode') || [],
|
||||
}
|
||||
// @ts-expect-error // missing 'responses', see OpenAPIV3.OperationObject.responses
|
||||
@@ -279,6 +286,11 @@ const slugify = (text: string) => {
|
||||
.replace(/-+$/, '') // Trim - from end of text
|
||||
}
|
||||
|
||||
function isValidSlug(slug: string): boolean {
|
||||
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/
|
||||
return slugRegex.test(slug)
|
||||
}
|
||||
|
||||
// Uppercase the first letter of a string
|
||||
const toTitle = (text: string) => {
|
||||
return text.charAt(0).toUpperCase() + text.slice(1)
|
||||
|
||||
@@ -6,10 +6,10 @@ import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
|
||||
import { gen_v3 } from '~/lib/refGenerator/helpers'
|
||||
|
||||
import apiCommonSections from '~/spec/common-api-sections.json' assert { type: 'json' }
|
||||
import specFile from '~/spec/transforms/api_v0_openapi_deparsed.json' assert { type: 'json' }
|
||||
import specFile from '~/spec/transforms/api_v1_openapi_deparsed.json' assert { type: 'json' }
|
||||
|
||||
// @ts-ignore
|
||||
const generatedSpec = gen_v3(specFile, 'wat', { apiUrl: 'apiv0' })
|
||||
const generatedSpec = gen_v3(specFile, 'wat', { apiUrl: 'apiv0', type: 'mgmt-api' })
|
||||
const sections = flattenSections(apiCommonSections)
|
||||
const libraryPath = '/api'
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function fetchSources() {
|
||||
'api',
|
||||
'/reference/api',
|
||||
{ title: 'Management API Reference' },
|
||||
'spec/transforms/api_v0_openapi_deparsed.json',
|
||||
'spec/transforms/api_v1_openapi_deparsed.json',
|
||||
'spec/common-api-sections.json'
|
||||
).load()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
REPO_DIR=$(shell pwd)
|
||||
|
||||
run: download transform format
|
||||
run: download transform generate format
|
||||
|
||||
|
||||
###############################################################################
|
||||
@@ -19,7 +19,7 @@ init:
|
||||
download: download.api.v1 download.storage.v1 download.tsdoc.v2
|
||||
|
||||
download.api.v1:
|
||||
curl -sS https://api.supabase.com/api/v1-json > $(REPO_DIR)/api_v0_openapi.json
|
||||
curl -sS https://api.supabase.com/api/v1-json > $(REPO_DIR)/api_v1_openapi.json
|
||||
|
||||
|
||||
# This flow needs to be updated, so we'l comment out for the moment
|
||||
@@ -57,10 +57,10 @@ download.analytics.v0:
|
||||
###############################################################################
|
||||
# Transform docs into working files
|
||||
###############################################################################
|
||||
transform: dereference.api.v0 dereference.auth.v1 dereference.storage.v0 dereference.tsdoc.v2 combine.tsdoc.v2
|
||||
transform: dereference.api.v1 dereference.auth.v1 dereference.storage.v0 dereference.tsdoc.v2 combine.tsdoc.v2
|
||||
|
||||
dereference.api.v0:
|
||||
npx @redocly/cli bundle --dereferenced -o $(REPO_DIR)/transforms/api_v0_openapi_deparsed.json $(REPO_DIR)/api_v0_openapi.json
|
||||
dereference.api.v1:
|
||||
npx @redocly/cli bundle --dereferenced -o $(REPO_DIR)/transforms/api_v1_openapi_deparsed.json $(REPO_DIR)/api_v1_openapi.json
|
||||
|
||||
dereference.auth.v1:
|
||||
npx @redocly/cli bundle --dereferenced -o $(REPO_DIR)/transforms/auth_v1_openapi_deparsed.json $(REPO_DIR)/auth_v1_openapi.json
|
||||
@@ -119,6 +119,14 @@ combine-raw.tsdoc.v2:
|
||||
$(REPO_DIR)/enrichments/tsdoc_v2/functions.json \
|
||||
> $(REPO_DIR)/enrichments/tsdoc_v2/combined_raw.json
|
||||
|
||||
###############################################################################
|
||||
# Generate sections from OpenAPI 3.0
|
||||
###############################################################################
|
||||
generate: generate.sections.api.v1
|
||||
|
||||
generate.sections.api.v1:
|
||||
node $(REPO_DIR)/sections/generateMgmtApiSections.ts $(REPO_DIR)/transforms/api_v1_openapi_deparsed.json $(REPO_DIR)/common-api-sections.json
|
||||
|
||||
###############################################################################
|
||||
# Validate OpenAPI 3.0
|
||||
###############################################################################
|
||||
|
||||
File diff suppressed because one or more lines are too long
6802
apps/docs/spec/api_v1_openapi.json
Normal file
6802
apps/docs/spec/api_v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,535 +7,476 @@
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Projects",
|
||||
"title": "auth",
|
||||
"items": [
|
||||
{
|
||||
"id": "list-all-projects",
|
||||
"title": "List all projects",
|
||||
"slug": "list-all-projects",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "get-project-api-keys",
|
||||
"title": "Get project api keys",
|
||||
"slug": "get-project-api-keys",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "create-a-project",
|
||||
"title": "Create a project",
|
||||
"slug": "create-a-project",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "deletes-the-given-project",
|
||||
"title": "Delete a project",
|
||||
"slug": "deletes-the-given-project",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Organizations",
|
||||
"items": [
|
||||
{
|
||||
"id": "list-all-organizations",
|
||||
"title": "List all organizations",
|
||||
"slug": "list-all-organizations",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-information-about-the-organization",
|
||||
"title": "Get an organization",
|
||||
"slug": "gets-information-about-the-organization",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "create-an-organization",
|
||||
"title": "Create an organization",
|
||||
"slug": "create-an-organization",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "list-members-of-an-organization",
|
||||
"title": "List organization members",
|
||||
"slug": "list-members-of-an-organization",
|
||||
"type": "operation"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Services",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-projects-service-health-status",
|
||||
"title": "Get services health",
|
||||
"slug": "gets-projects-service-health-status",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-projects-auth-config",
|
||||
"title": "Get auth service config",
|
||||
"slug": "gets-projects-auth-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-a-projects-auth-config",
|
||||
"title": "Update auth service config",
|
||||
"slug": "updates-a-projects-auth-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-projects-postgrest-config",
|
||||
"title": "Get postgrest service config",
|
||||
"slug": "gets-projects-postgrest-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-projects-postgrest-config",
|
||||
"title": "Update postgrest service config",
|
||||
"slug": "updates-projects-postgrest-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Database",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-projects-postgres-config",
|
||||
"title": "Get Postgres config",
|
||||
"slug": "gets-projects-postgres-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-projects-postgres-config",
|
||||
"title": "Update Postgres config",
|
||||
"slug": "updates-projects-postgres-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "returns-the-projects-eligibility-for-upgrades",
|
||||
"title": "Get Postgres upgrade eligibility",
|
||||
"slug": "returns-the-projects-eligibility-for-upgrades",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-the-latest-status-of-the-projects-upgrade",
|
||||
"title": "Get Postgres upgrade status",
|
||||
"slug": "gets-the-latest-status-of-the-projects-upgrade",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "upgrades-the-projects-postgres-version",
|
||||
"title": "Upgrade Postgres version",
|
||||
"slug": "upgrades-the-projects-postgres-version",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "returns-projects-readonly-mode-status",
|
||||
"title": "Get readonly mode status",
|
||||
"slug": "returns-projects-readonly-mode-status",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "disables-projects-readonly-mode-for-the-next-15-minutes",
|
||||
"title": "Disable readonly mode temporarily",
|
||||
"slug": "disables-projects-readonly-mode-for-the-next-15-minutes",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "run-sql-query",
|
||||
"title": "Run a query",
|
||||
"slug": "run-sql-query",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "enables-database-webhooks-on-the-project",
|
||||
"title": "Enable database webhook",
|
||||
"slug": "enables-database-webhooks-on-the-project",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Database Branching",
|
||||
"items": [
|
||||
{
|
||||
"id": "list-all-database-branches",
|
||||
"title": "List all branches",
|
||||
"slug": "list-all-database-branches",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "get-database-branch-config",
|
||||
"title": "Get a branch config",
|
||||
"slug": "get-database-branch-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "create-a-database-branch",
|
||||
"title": "Create a branch",
|
||||
"slug": "create-a-database-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "resets-a-database-branch",
|
||||
"title": "Reset a branch",
|
||||
"slug": "resets-a-database-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "update-database-branch-config",
|
||||
"title": "Update a branch config",
|
||||
"slug": "update-database-branch-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "delete-a-database-branch",
|
||||
"title": "Delete a branch",
|
||||
"slug": "delete-a-database-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "disables-preview-branching",
|
||||
"title": "Disable preview branching",
|
||||
"slug": "disables-preview-branching",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Secrets",
|
||||
"items": [
|
||||
{
|
||||
"id": "list-all-secrets",
|
||||
"title": "List all secrets",
|
||||
"slug": "list-all-secrets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "bulk-create-secrets",
|
||||
"title": "Bulk create secrets",
|
||||
"slug": "bulk-create-secrets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "bulk-delete-secrets",
|
||||
"title": "Bulk delete secrets",
|
||||
"slug": "bulk-delete-secrets",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Typescript",
|
||||
"items": [
|
||||
{
|
||||
"id": "generate-typescript-types",
|
||||
"title": "Generate TypeScript types",
|
||||
"slug": "generate-typescript-types",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Functions",
|
||||
"items": [
|
||||
{
|
||||
"id": "create-a-function",
|
||||
"title": "Create a function",
|
||||
"slug": "create-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "list-all-functions",
|
||||
"title": "List all functions",
|
||||
"slug": "list-all-functions",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "retrieve-a-function",
|
||||
"title": "Retrieve a function",
|
||||
"slug": "retrieve-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "update-a-function",
|
||||
"title": "Update a function",
|
||||
"slug": "update-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "delete-a-function",
|
||||
"title": "Delete a function",
|
||||
"slug": "delete-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "retrieve-a-function-body",
|
||||
"title": "Retrieve a function body",
|
||||
"slug": "retrieve-a-function-body",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Storage",
|
||||
"items": [
|
||||
{
|
||||
"id": "lists-all-buckets",
|
||||
"title": "List all buckets",
|
||||
"slug": "lists-all-buckets",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Custom Hostname",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-projects-custom-hostname-config",
|
||||
"title": "Retrieve hostname configuration",
|
||||
"slug": "gets-projects-custom-hostname-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "deletes-a-projects-custom-hostname-configuration",
|
||||
"title": "Delete hostname configuration",
|
||||
"slug": "deletes-a-projects-custom-hostname-configuration",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-projects-custom-hostname-configuration",
|
||||
"title": "Update hostname configuration",
|
||||
"slug": "updates-projects-custom-hostname-configuration",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "attempts-to-verify-the-dns-configuration-for-projects-custom-hostname-configuration",
|
||||
"title": "Verify DNS configuration",
|
||||
"slug": "attempts-to-verify-the-dns-configuration-for-projects-custom-hostname-configuration",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "activates-a-custom-hostname-for-a-project",
|
||||
"title": "Activate custom hostname",
|
||||
"slug": "activates-a-custom-hostname-for-a-project",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Vanity Subdomain",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-current-vanity-subdomain-config",
|
||||
"title": "Get vanity subdomain config",
|
||||
"slug": "gets-current-vanity-subdomain-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "checks-vanity-subdomain-availability",
|
||||
"title": "Check vanity subdomain availability",
|
||||
"slug": "checks-vanity-subdomain-availability",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "activates-a-vanity-subdomain-for-a-project",
|
||||
"title": "Activate vanity subdomain config",
|
||||
"slug": "activates-a-vanity-subdomain-for-a-project",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "deletes-a-projects-vanity-subdomain-configuration",
|
||||
"title": "Deactive vanity subdomain config",
|
||||
"slug": "deletes-a-projects-vanity-subdomain-configuration",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "pgsodium",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-projects-pgsodium-config",
|
||||
"title": "Retrieve pgsodium config",
|
||||
"slug": "gets-projects-pgsodium-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-projects-pgsodium-config-updating-the-root_key-can-cause-all-data-encrypted-with-the-older-key-to-become-inaccessible",
|
||||
"title": "Update pgsodium config",
|
||||
"slug": "updates-projects-pgsodium-config-updating-the-root_key-can-cause-all-data-encrypted-with-the-older-key-to-become-inaccessible",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Network",
|
||||
"items": [
|
||||
{
|
||||
"id": "gets-projects-network-bans",
|
||||
"title": "Retrieve network bans",
|
||||
"slug": "gets-projects-network-bans",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "remove-network-bans",
|
||||
"title": "Delete network bans",
|
||||
"slug": "remove-network-bans",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-projects-network-restrictions",
|
||||
"title": "Retrieve network restrictions",
|
||||
"slug": "gets-projects-network-restrictions",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-projects-network-restrictions",
|
||||
"title": "Update network restrictions",
|
||||
"slug": "updates-projects-network-restrictions",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Ssl enforcement",
|
||||
"items": [
|
||||
{
|
||||
"id": "get-projects-ssl-enforcement-configuration",
|
||||
"title": "Get ssl enforcement config",
|
||||
"slug": "get-projects-ssl-enforcement-configuration",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "update-projects-ssl-enforcement-configuration",
|
||||
"title": "Update ssl enforcement config",
|
||||
"slug": "update-projects-ssl-enforcement-configuration",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Single Sign-On",
|
||||
"items": [
|
||||
{
|
||||
"id": "lists-all-sso-providers",
|
||||
"title": "List all sso providers",
|
||||
"slug": "lists-all-sso-providers",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-a-sso-provider-by-its-uuid",
|
||||
"title": "Get a sso provider",
|
||||
"slug": "gets-a-sso-provider-by-its-uuid",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "creates-a-new-sso-provider",
|
||||
"id": "v1-create-a-sso-provider",
|
||||
"title": "Create a sso provider",
|
||||
"slug": "creates-a-new-sso-provider",
|
||||
"slug": "v1-create-a-sso-provider",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "updates-a-sso-provider-by-its-uuid",
|
||||
"title": "Update a sso provider",
|
||||
"slug": "updates-a-sso-provider-by-its-uuid",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "removes-a-sso-provider-by-its-uuid",
|
||||
"id": "v1-delete-a-sso-provider",
|
||||
"title": "Delete a sso provider",
|
||||
"slug": "removes-a-sso-provider-by-its-uuid",
|
||||
"slug": "v1-delete-a-sso-provider",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-a-sso-provider",
|
||||
"title": "Get a sso provider",
|
||||
"slug": "v1-get-a-sso-provider",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-auth-service-config",
|
||||
"title": "Get auth service config",
|
||||
"slug": "v1-get-auth-service-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-sso-provider",
|
||||
"title": "List all sso provider",
|
||||
"slug": "v1-list-all-sso-provider",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-a-sso-provider",
|
||||
"title": "Update a sso provider",
|
||||
"slug": "v1-update-a-sso-provider",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-auth-service-config",
|
||||
"title": "Update auth service config",
|
||||
"slug": "v1-update-auth-service-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Oauth",
|
||||
"title": "database",
|
||||
"items": [
|
||||
{
|
||||
"id": "authorize-user-through-oauth",
|
||||
"title": "Authorize user",
|
||||
"slug": "authorize-user-through-oauth",
|
||||
"id": "v1-disable-readonly-mode-temporarily",
|
||||
"title": "Disable readonly mode temporarily",
|
||||
"slug": "v1-disable-readonly-mode-temporarily",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "exchange-auth-code-for-users-access-and-refresh-token",
|
||||
"title": "Exchange oauth token",
|
||||
"slug": "exchange-auth-code-for-users-access-and-refresh-token",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Read replicas",
|
||||
"items": [
|
||||
{
|
||||
"id": "set-up-a-read-replica",
|
||||
"title": "Setup a read replica",
|
||||
"slug": "set-up-a-read-replica",
|
||||
"id": "v1-enable-database-webhook",
|
||||
"title": "Enable database webhook",
|
||||
"slug": "v1-enable-database-webhook",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "remove-a-read-replica",
|
||||
"title": "Remove a read replica",
|
||||
"slug": "remove-a-read-replica",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Backups",
|
||||
"items": [
|
||||
{
|
||||
"id": "lists-all-backups",
|
||||
"title": "List all backups",
|
||||
"slug": "lists-all-backups",
|
||||
"id": "v1-generate-typescript-types",
|
||||
"title": "Generate typescript types",
|
||||
"slug": "v1-generate-typescript-types",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "restores-a-pitr-backup-for-a-database",
|
||||
"title": "Restores PITR backup",
|
||||
"slug": "restores-a-pitr-backup-for-a-database",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "Snippets",
|
||||
"items": [
|
||||
{
|
||||
"id": "lists-sql-snippets-for-the-logged-in-user",
|
||||
"title": "List all snippets",
|
||||
"slug": "lists-sql-snippets-for-the-logged-in-user",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "gets-a-specific-sql-snippet",
|
||||
"id": "v1-get-a-snippet",
|
||||
"title": "Get a snippet",
|
||||
"slug": "gets-a-specific-sql-snippet",
|
||||
"slug": "v1-get-a-snippet",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "get-postgres-config",
|
||||
"title": "Get postgres config",
|
||||
"slug": "get-postgres-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-project-pgbouncer-config",
|
||||
"title": "Get project pgbouncer config",
|
||||
"slug": "v1-get-project-pgbouncer-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-readonly-mode-status",
|
||||
"title": "Get readonly mode status",
|
||||
"slug": "v1-get-readonly-mode-status",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-ssl-enforcement-config",
|
||||
"title": "Get ssl enforcement config",
|
||||
"slug": "v1-get-ssl-enforcement-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-backups",
|
||||
"title": "List all backups",
|
||||
"slug": "v1-list-all-backups",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-snippets",
|
||||
"title": "List all snippets",
|
||||
"slug": "v1-list-all-snippets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-remove-a-read-replica",
|
||||
"title": "Remove a read replica",
|
||||
"slug": "v1-remove-a-read-replica",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-restore-pitr-backup",
|
||||
"title": "Restore pitr backup",
|
||||
"slug": "v1-restore-pitr-backup",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-run-a-query",
|
||||
"title": "Run a query",
|
||||
"slug": "v1-run-a-query",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-setup-a-read-replica",
|
||||
"title": "Setup a read replica",
|
||||
"slug": "v1-setup-a-read-replica",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "update-postgres-config",
|
||||
"title": "Update postgres config",
|
||||
"slug": "update-postgres-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-ssl-enforcement-config",
|
||||
"title": "Update ssl enforcement config",
|
||||
"slug": "v1-update-ssl-enforcement-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "domains",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-activate-custom-hostname",
|
||||
"title": "Activate custom hostname",
|
||||
"slug": "v1-activate-custom-hostname",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-activate-vanity-subdomain-config",
|
||||
"title": "Activate vanity subdomain config",
|
||||
"slug": "v1-activate-vanity-subdomain-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-check-vanity-subdomain-availability",
|
||||
"title": "Check vanity subdomain availability",
|
||||
"slug": "v1-check-vanity-subdomain-availability",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-deactive-vanity-subdomain-config",
|
||||
"title": "Deactive vanity subdomain config",
|
||||
"slug": "v1-deactive-vanity-subdomain-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-hostname-config",
|
||||
"title": "Get hostname config",
|
||||
"slug": "v1-get-hostname-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-vanity-subdomain-config",
|
||||
"title": "Get vanity subdomain config",
|
||||
"slug": "v1-get-vanity-subdomain-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-hostname-config",
|
||||
"title": "Update hostname config",
|
||||
"slug": "v1-update-hostname-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-verify-dns-config",
|
||||
"title": "Verify dns config",
|
||||
"slug": "v1-verify-dns-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "edge functions",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-delete-a-function",
|
||||
"title": "Delete a function",
|
||||
"slug": "v1-delete-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-a-function",
|
||||
"title": "Get a function",
|
||||
"slug": "v1-get-a-function",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-a-function-body",
|
||||
"title": "Get a function body",
|
||||
"slug": "v1-get-a-function-body",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-functions",
|
||||
"title": "List all functions",
|
||||
"slug": "v1-list-all-functions",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-a-function",
|
||||
"title": "Update a function",
|
||||
"slug": "v1-update-a-function",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "environments",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-create-a-branch",
|
||||
"title": "Create a branch",
|
||||
"slug": "v1-create-a-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-delete-a-branch",
|
||||
"title": "Delete a branch",
|
||||
"slug": "v1-delete-a-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-disable-preview-branching",
|
||||
"title": "Disable preview branching",
|
||||
"slug": "v1-disable-preview-branching",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-a-branch-config",
|
||||
"title": "Get a branch config",
|
||||
"slug": "v1-get-a-branch-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-branches",
|
||||
"title": "List all branches",
|
||||
"slug": "v1-list-all-branches",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-reset-a-branch",
|
||||
"title": "Reset a branch",
|
||||
"slug": "v1-reset-a-branch",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-a-branch-config",
|
||||
"title": "Update a branch config",
|
||||
"slug": "v1-update-a-branch-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "oauth",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-authorize-user",
|
||||
"title": "Authorize user",
|
||||
"slug": "v1-authorize-user",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-exchange-oauth-token",
|
||||
"title": "Exchange oauth token",
|
||||
"slug": "v1-exchange-oauth-token",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "organizations",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-create-an-organization",
|
||||
"title": "Create an organization",
|
||||
"slug": "v1-create-an-organization",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-an-organization",
|
||||
"title": "Get an organization",
|
||||
"slug": "v1-get-an-organization",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-organizations",
|
||||
"title": "List all organizations",
|
||||
"slug": "v1-list-all-organizations",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-organization-members",
|
||||
"title": "List organization members",
|
||||
"slug": "v1-list-organization-members",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "projects",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-create-a-project",
|
||||
"title": "Create a project",
|
||||
"slug": "v1-create-a-project",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-delete-network-bans",
|
||||
"title": "Delete network bans",
|
||||
"slug": "v1-delete-network-bans",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-all-projects",
|
||||
"title": "Get all projects",
|
||||
"slug": "v1-get-all-projects",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-network-restrictions",
|
||||
"title": "Get network restrictions",
|
||||
"slug": "v1-get-network-restrictions",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-postgrest-upgrade-eligibility",
|
||||
"title": "Get postgrest upgrade eligibility",
|
||||
"slug": "v1-get-postgrest-upgrade-eligibility",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-postgrest-upgrade-status",
|
||||
"title": "Get postgrest upgrade status",
|
||||
"slug": "v1-get-postgrest-upgrade-status",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-services-health",
|
||||
"title": "Get services health",
|
||||
"slug": "v1-get-services-health",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-network-bans",
|
||||
"title": "List all network bans",
|
||||
"slug": "v1-list-all-network-bans",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-network-restrictions",
|
||||
"title": "Update network restrictions",
|
||||
"slug": "v1-update-network-restrictions",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-upgrade-postgres-version",
|
||||
"title": "Upgrade postgres version",
|
||||
"slug": "v1-upgrade-postgres-version",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "rest",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-get-postgrest-service-config",
|
||||
"title": "Get postgrest service config",
|
||||
"slug": "v1-get-postgrest-service-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-postgrest-service-config",
|
||||
"title": "Update postgrest service config",
|
||||
"slug": "v1-update-postgrest-service-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "secrets",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-bulk-create-secrets",
|
||||
"title": "Bulk create secrets",
|
||||
"slug": "v1-bulk-create-secrets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-bulk-delete-secrets",
|
||||
"title": "Bulk delete secrets",
|
||||
"slug": "v1-bulk-delete-secrets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-pgsodium-config",
|
||||
"title": "Get pgsodium config",
|
||||
"slug": "v1-get-pgsodium-config",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-get-project-api-keys",
|
||||
"title": "Get project api keys",
|
||||
"slug": "v1-get-project-api-keys",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-list-all-secrets",
|
||||
"title": "List all secrets",
|
||||
"slug": "v1-list-all-secrets",
|
||||
"type": "operation"
|
||||
},
|
||||
{
|
||||
"id": "v1-update-pgsodium-config",
|
||||
"title": "Update pgsodium config",
|
||||
"slug": "v1-update-pgsodium-config",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"title": "storage",
|
||||
"items": [
|
||||
{
|
||||
"id": "v1-list-all-buckets",
|
||||
"title": "List all buckets",
|
||||
"slug": "v1-list-all-buckets",
|
||||
"type": "operation"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
97
apps/docs/spec/sections/generateMgmtApiSections.ts
Normal file
97
apps/docs/spec/sections/generateMgmtApiSections.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function slugToTitle(slug) {
|
||||
if (!slug) return ''
|
||||
// remove version prefix if available
|
||||
const prefixRegex = /^v\d+/;
|
||||
const title = slug.replace(prefixRegex, '').replace(/-/g, ' ').trimStart()
|
||||
return title.charAt(0).toUpperCase() + title.slice(1)
|
||||
}
|
||||
|
||||
function isValidSlug(slug) {
|
||||
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/
|
||||
return slugRegex.test(slug)
|
||||
}
|
||||
|
||||
function extractSectionsFromOpenApi(filePath, outputPath) {
|
||||
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
console.error(`Error reading file ${filePath}:`, err);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const openApiJson = JSON.parse(data);
|
||||
const categories = []
|
||||
const sections = [];
|
||||
|
||||
if (openApiJson.paths) {
|
||||
for (const route in openApiJson.paths) {
|
||||
const methods = openApiJson.paths[route];
|
||||
for (const method in methods) {
|
||||
const tag = methods[method].tags[0];
|
||||
const operationId = methods[method].operationId;
|
||||
// If operationId is not in the form of a slug ignore it.
|
||||
// This is intentional because operationId is not defined under the swagger
|
||||
// spec and is extracted automatically from the function name.
|
||||
if (!tag || !isValidSlug(operationId)) continue;
|
||||
|
||||
if (!categories.includes(tag)) {
|
||||
categories.push(tag)
|
||||
sections.push(
|
||||
{
|
||||
"type": "category",
|
||||
"title": tag,
|
||||
"items":[]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const sectionCate = sections.find((i) => i.title === tag);
|
||||
sectionCate.items.push({
|
||||
"id": operationId,
|
||||
"title": slugToTitle(operationId),
|
||||
"slug": operationId,
|
||||
"type": "operation"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finalize sections
|
||||
sections.sort((a, b) => a.title.localeCompare(b.title));
|
||||
sections.forEach((i) => i.items.sort((a, b) => a.title.localeCompare(b.title)));
|
||||
sections.unshift({
|
||||
"title": "Introduction",
|
||||
"id": "introduction",
|
||||
"slug": "introduction",
|
||||
"type": "markdown",
|
||||
});
|
||||
|
||||
fs.writeFile(outputPath, JSON.stringify(sections, null, 2), 'utf8', (err) => {
|
||||
if (err) {
|
||||
console.error(`Error writing to file ${outputPath}:`, err);
|
||||
return;
|
||||
}
|
||||
console.log(`Sections successfully generated!!!`);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error parsing JSON:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get file paths from command line arguments
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length < 2) {
|
||||
console.error('Please provide the openapi file path and output file path as arguments.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const inputFilePath = path.resolve(args[0]);
|
||||
const outputFilePath = path.resolve(args[1]);
|
||||
|
||||
;(async () => {
|
||||
extractSectionsFromOpenApi(inputFilePath, outputFilePath);
|
||||
})()
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user