Skip to content

Commit 9bced60

Browse files
update api routes to fetch the apiIndex at runtime rather than import it
1 parent 7b27a98 commit 9bced60

File tree

11 files changed

+131
-69
lines changed

11 files changed

+131
-69
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ src/apiIndex.json
3434
textContent/*.mdx
3535

3636
coverage/
37+
38+
.wrangler/

astro.config.mjs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ export default defineConfig({
1313
noExternal: ["@patternfly/*", "react-dropzone"],
1414
external: ["node:fs", "node:path"]
1515
},
16-
build: {
17-
rollupOptions: {
18-
external: [/apiIndex\.json$/]
19-
}
20-
},
2116
server: {
2217
fs: {
2318
allow: ['./']

cli/cli.ts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,14 @@ async function updateTsConfigOutputDirPath(program: Command) {
9696
const tsConfig = JSON.parse(tsConfigFile)
9797
const formattedOutputDir = join(absoluteOutputDir, '*')
9898

99-
tsConfig.compilerOptions.paths["outputDir/*"] = [formattedOutputDir]
99+
tsConfig.compilerOptions.paths['outputDir/*'] = [formattedOutputDir]
100100

101101
await writeFile(tsConfigPath, JSON.stringify(tsConfig, null, 2))
102102

103103
if (verbose) {
104-
console.log(`Updated tsconfig.json with outputDir path: ${formattedOutputDir}`)
104+
console.log(
105+
`Updated tsconfig.json with outputDir path: ${formattedOutputDir}`,
106+
)
105107
}
106108
} catch (e: any) {
107109
console.error('Error updating tsconfig.json with outputDir path:', e)
@@ -132,7 +134,9 @@ async function initializeApiIndex(program: Command) {
132134
}
133135
}
134136

135-
async function buildProject(): Promise<DocsConfig | undefined> {
137+
async function buildProject(program: Command): Promise<DocsConfig | undefined> {
138+
const { verbose } = program.opts()
139+
136140
if (!config) {
137141
console.error(
138142
'No config found, please run the `setup` command or manually create a pf-docs.config.mjs file',
@@ -159,35 +163,40 @@ async function buildProject(): Promise<DocsConfig | undefined> {
159163
outDir: docsOutputDir,
160164
})
161165

166+
// copy the apiIndex.json file to the docs directory so it can be served as a static asset
167+
const apiIndexPath = join(absoluteOutputDir, 'apiIndex.json')
168+
const docsApiIndexPath = join(absoluteOutputDir, 'docs', 'apiIndex.json')
169+
await copyFile(apiIndexPath, docsApiIndexPath)
170+
171+
if (verbose) {
172+
console.log('Copied apiIndex.json to docs directory')
173+
}
174+
162175
return config
163176
}
164177

165-
async function deploy() {
166-
const { verbose } = program.opts()
178+
async function deploy(program: Command) {
179+
const { verbose, dryRun } = program.opts()
167180

168181
if (verbose) {
169182
console.log('Starting Cloudflare deployment...')
170183
}
171184

185+
if (dryRun) {
186+
console.log('Dry run mode enabled, skipping deployment')
187+
return
188+
}
189+
172190
try {
173-
// First build the project
174-
const config = await buildProject()
175-
if (config) {
176-
if (verbose) {
177-
console.log('Build complete, deploying to Cloudflare...')
178-
}
179-
180-
// Deploy using Wrangler
181-
const { execSync } = await import('child_process')
182-
const outputPath = join(absoluteOutputDir, 'docs')
183-
184-
execSync(`npx wrangler pages deploy ${outputPath}`, {
185-
stdio: 'inherit',
186-
cwd: currentDir,
187-
})
188-
189-
console.log('Successfully deployed to Cloudflare Pages!')
190-
}
191+
// Deploy using Wrangler
192+
const { execSync } = await import('child_process')
193+
194+
execSync(`wrangler pages deploy`, {
195+
stdio: 'inherit',
196+
cwd: currentDir,
197+
})
198+
199+
console.log('Successfully deployed to Cloudflare Pages!')
191200
} catch (error) {
192201
console.error('Deployment failed:', error)
193202
process.exit(1)
@@ -199,6 +208,7 @@ program.name('pf-doc-core')
199208

200209
program.option('--verbose', 'verbose mode', false)
201210
program.option('--props', 'generate props data', false)
211+
program.option('--dry-run', 'dry run mode', false)
202212

203213
program.command('setup').action(async () => {
204214
await Promise.all([
@@ -232,7 +242,7 @@ program.command('start').action(async () => {
232242
})
233243

234244
program.command('build').action(async () => {
235-
await buildProject()
245+
await buildProject(program)
236246
})
237247

238248
program.command('generate-props').action(async () => {
@@ -257,7 +267,7 @@ program
257267
})
258268

259269
program.command('deploy').action(async () => {
260-
await deploy()
270+
await deploy(program)
261271
})
262272

263273
program.parse(process.argv)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"build:props": "npm run build:cli && node ./dist/cli/cli.js generate-props",
1919
"preview": "wrangler pages dev",
2020
"astro": "astro",
21-
"deploy": "wrangler pages deploy",
21+
"deploy": "npm run build:cli && node ./dist/cli/cli.js deploy",
2222
"versions:upload": "wrangler versions upload",
2323
"prettier": "prettier --write ./src",
2424
"lint": "eslint . --cache --cache-strategy content",

src/pages/api/[version].ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { APIRoute } from 'astro'
2-
import { createJsonResponse, createIndexKey } from '../../utils/apiHelpers'
3-
import { sections as sectionsData } from 'outputDir/apiIndex.json'
2+
import { createJsonResponse } from '../../utils/apiHelpers'
3+
import { fetchApiIndex } from '../../utils/apiIndex/fetch'
44

55
export const prerender = false
66

7-
export const GET: APIRoute = async ({ params }) => {
7+
export const GET: APIRoute = async ({ params, url }) => {
88
const { version } = params
99

1010
if (!version) {
@@ -14,12 +14,19 @@ export const GET: APIRoute = async ({ params }) => {
1414
)
1515
}
1616

17-
const key = createIndexKey(version)
18-
const sections = sectionsData[key as keyof typeof sectionsData]
17+
try {
18+
const index = await fetchApiIndex(url)
19+
const sections = index.sections[version]
1920

20-
if (!sections) {
21-
return createJsonResponse({ error: `Version '${version}' not found` }, 404)
22-
}
21+
if (!sections) {
22+
return createJsonResponse({ error: `Version '${version}' not found` }, 404)
23+
}
2324

24-
return createJsonResponse(sections)
25+
return createJsonResponse(sections)
26+
} catch (error) {
27+
return createJsonResponse(
28+
{ error: 'Failed to load API index' },
29+
500
30+
)
31+
}
2532
}
Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { APIRoute } from 'astro'
22
import { createJsonResponse, createIndexKey } from '../../../utils/apiHelpers'
3-
import { pages as pagesData } from 'outputDir/apiIndex.json'
3+
import { fetchApiIndex } from '../../../utils/apiIndex/fetch'
44

55
export const prerender = false
66

7-
export const GET: APIRoute = async ({ params }) => {
7+
export const GET: APIRoute = async ({ params, url }) => {
88
const { version, section } = params
99

1010
if (!version || !section) {
@@ -14,15 +14,23 @@ export const GET: APIRoute = async ({ params }) => {
1414
)
1515
}
1616

17-
const key = createIndexKey(version, section)
18-
const pages = pagesData[key as keyof typeof pagesData]
17+
try {
18+
const index = await fetchApiIndex(url)
19+
const key = createIndexKey(version, section)
20+
const pages = index.pages[key]
1921

20-
if (!pages) {
22+
if (!pages) {
23+
return createJsonResponse(
24+
{ error: `Section '${section}' not found for version '${version}'` },
25+
404,
26+
)
27+
}
28+
29+
return createJsonResponse(pages)
30+
} catch (error) {
2131
return createJsonResponse(
22-
{ error: `Section '${section}' not found for version '${version}'` },
23-
404,
32+
{ error: 'Failed to load API index' },
33+
500
2434
)
2535
}
26-
27-
return createJsonResponse(pages)
2836
}
Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { APIRoute } from 'astro'
22
import { createJsonResponse, createIndexKey } from '../../../../utils/apiHelpers'
3-
import { tabs as tabsData } from 'outputDir/apiIndex.json'
3+
import { fetchApiIndex } from '../../../../utils/apiIndex/fetch'
44

55
export const prerender = false
66

7-
export const GET: APIRoute = async ({ params }) => {
7+
export const GET: APIRoute = async ({ params, url }) => {
88
const { version, section, page } = params
99

1010
if (!version || !section || !page) {
@@ -14,17 +14,25 @@ export const GET: APIRoute = async ({ params }) => {
1414
)
1515
}
1616

17-
const key = createIndexKey(version, section, page)
18-
const tabs = tabsData[key as keyof typeof tabsData]
17+
try {
18+
const index = await fetchApiIndex(url)
19+
const key = createIndexKey(version, section, page)
20+
const tabs = index.tabs[key]
1921

20-
if (!tabs) {
22+
if (!tabs) {
23+
return createJsonResponse(
24+
{
25+
error: `Page '${page}' not found in section '${section}' for version '${version}'`,
26+
},
27+
404,
28+
)
29+
}
30+
31+
return createJsonResponse(tabs)
32+
} catch (error) {
2133
return createJsonResponse(
22-
{
23-
error: `Page '${page}' not found in section '${section}' for version '${version}'`,
24-
},
25-
404,
34+
{ error: 'Failed to load API index' },
35+
500
2636
)
2737
}
28-
29-
return createJsonResponse(tabs)
3038
}

src/pages/api/openapi.json.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import type { APIRoute } from 'astro'
2-
import index from 'outputDir/apiIndex.json'
2+
import { fetchApiIndex } from '../../utils/apiIndex/fetch'
33

44
export const prerender = false
55

6-
export const GET: APIRoute = async () => {
7-
const versions = index.versions
6+
export const GET: APIRoute = async ({ url }) => {
7+
let versions: string[]
8+
try {
9+
const index = await fetchApiIndex(url)
10+
versions = index.versions
11+
} catch (error) {
12+
versions = []
13+
}
814

915
const openApiSpec = {
1016
openapi: '3.0.0',

src/pages/api/versions.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import type { APIRoute } from 'astro'
22
import { createJsonResponse } from '../../utils/apiHelpers'
3-
import { versions as versionsData } from 'outputDir/apiIndex.json'
3+
import { fetchApiIndex } from '../../utils/apiIndex/fetch'
44

55
export const prerender = false
66

7-
export const GET: APIRoute = async () => {
8-
const versions = versionsData
9-
10-
return createJsonResponse(versions)
7+
export const GET: APIRoute = async ({ url }) => {
8+
try {
9+
const index = await fetchApiIndex(url)
10+
return createJsonResponse(index.versions)
11+
} catch (error) {
12+
return createJsonResponse(
13+
{ error: 'Failed to load API index' },
14+
500
15+
)
16+
}
1117
}

src/utils/apiIndex/fetch.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { ApiIndex } from './generate'
2+
3+
/**
4+
* Fetches the API index from the server as a static asset
5+
* Used by API routes at runtime instead of importing the JSON statically
6+
*
7+
* @param url - The URL object from the API route context
8+
* @returns Promise resolving to the API index structure
9+
*/
10+
export async function fetchApiIndex(url: URL): Promise<ApiIndex> {
11+
const apiIndexUrl = new URL('/apiIndex.json', url.origin)
12+
const response = await fetch(apiIndexUrl)
13+
14+
if (!response.ok) {
15+
throw new Error(`Failed to load API index: ${response.status} ${response.statusText}`)
16+
}
17+
18+
return response.json()
19+
}

0 commit comments

Comments
 (0)