Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ jobs:
with:
repository: runcycles/cycles-protocol
path: cycles-protocol
- uses: actions/checkout@v4
with:
repository: runcycles/cycles-server-admin
path: cycles-server-admin
- uses: actions/setup-node@v4
with:
node-version: 20
Expand Down
25 changes: 23 additions & 2 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { defineConfig } from 'vitepress'
import { useSidebar } from 'vitepress-openapi'
import spec from '../public/openapi.json' with { type: 'json' }
import adminSpec from '../public/admin-openapi.json' with { type: 'json' }

const openApiSidebar = useSidebar({
spec,
linkPrefix: '/api/operations/',
})

const adminApiSidebar = useSidebar({
spec: adminSpec,
linkPrefix: '/admin-api/operations/',
})

export default defineConfig({
base: '/docs/',
title: 'Cycles Docs',
Expand All @@ -20,20 +26,35 @@ export default defineConfig({
nav: [
{ text: 'Home', link: '/' },
{ text: 'Quickstart', link: '/quickstart/getting-started-with-the-python-client' },
{ text: 'API Reference', link: '/api/' },
{
text: 'API Reference',
items: [
{ text: 'Cycles Protocol API', link: '/api/' },
{ text: 'Admin API', link: '/admin-api/' },
],
},
{ text: 'Protocol', link: 'https://github.com/runcycles/cycles-protocol' },
{ text: 'GitHub', link: 'https://github.com/runcycles' }
],
sidebar: {
'/api/': [
{
text: 'API Reference',
text: 'Cycles Protocol API',
items: [
{ text: 'Overview', link: '/api/' },
...openApiSidebar.generateSidebarGroups(),
],
},
],
'/admin-api/': [
{
text: 'Admin API',
items: [
{ text: 'Overview', link: '/admin-api/' },
...adminApiSidebar.generateSidebarGroups(),
],
},
],
'/': [
{
text: 'Quickstart',
Expand Down
11 changes: 11 additions & 0 deletions admin-api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
aside: false
outline: false
title: Admin API Reference
---

<script setup lang="ts">
import adminSpec from '../public/admin-openapi.json'
</script>

<OASpec :spec="adminSpec" />
15 changes: 15 additions & 0 deletions admin-api/operations/[operationId].md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
aside: false
outline: false
title: Admin API Reference
---

<script setup lang="ts">
import { useRoute } from 'vitepress'
import adminSpec from '../../public/admin-openapi.json'

const route = useRoute()
const operationId = route.data.params.operationId
</script>

<OAOperation :operationId="operationId" :spec="adminSpec" />
15 changes: 15 additions & 0 deletions admin-api/operations/[operationId].paths.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { usePaths } from 'vitepress-openapi'
import spec from '../../public/admin-openapi.json' with { type: 'json' }

export default {
paths() {
return usePaths({ spec })
.getPathsByVerbs()
.map(({ operationId, summary }) => ({
params: {
operationId,
pageTitle: `${summary} - Admin API`,
},
}))
},
}
40 changes: 24 additions & 16 deletions scripts/convert-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@ import { fileURLToPath } from 'node:url'
import YAML from 'yaml'

const __dirname = dirname(fileURLToPath(import.meta.url))
const candidates = [

function convertSpec(name, candidates, outFile) {
const specPath = candidates.filter(Boolean).find(p => existsSync(p))
if (!specPath) {
console.error(`Could not find ${name}. Searched:\n` + candidates.filter(Boolean).map(p => ' ' + p).join('\n'))
process.exit(1)
}
const outPath = resolve(__dirname, '../public', outFile)
mkdirSync(dirname(outPath), { recursive: true })
const yaml = readFileSync(specPath, 'utf-8')
const json = JSON.stringify(YAML.parse(yaml), null, 2)
writeFileSync(outPath, json)
console.log(`Converted ${specPath} → ${outPath}`)
}

// Cycles Protocol spec
convertSpec('cycles-protocol-v0.yaml', [
process.env.SPEC_PATH,
resolve(__dirname, '../../cycles-protocol/cycles-protocol-v0.yaml'), // local dev (sibling repo)
resolve(__dirname, '../cycles-protocol/cycles-protocol-v0.yaml'), // CI (checked out into workspace)
].filter(Boolean)
const specPath = candidates.find(p => existsSync(p))
if (!specPath) {
console.error('Could not find cycles-protocol-v0.yaml. Searched:\n' + candidates.map(p => ' ' + p).join('\n'))
console.error('Set SPEC_PATH env var to the correct location.')
process.exit(1)
}
const outPath = resolve(__dirname, '../public/openapi.json')

mkdirSync(dirname(outPath), { recursive: true })

const yaml = readFileSync(specPath, 'utf-8')
const json = JSON.stringify(YAML.parse(yaml), null, 2)
writeFileSync(outPath, json)
], 'openapi.json')

console.log(`Converted ${specPath} → ${outPath}`)
// Admin API spec
convertSpec('complete-budget-governance YAML', [
process.env.ADMIN_SPEC_PATH,
resolve(__dirname, '../../cycles-server-admin/complete-budget-governance-v0.1.23.yaml'), // local dev (sibling repo)
resolve(__dirname, '../cycles-server-admin/complete-budget-governance-v0.1.23.yaml'), // CI (checked out into workspace)
], 'admin-openapi.json')