Skip to content

Commit 1357900

Browse files
committed
temp fix for openapi
1 parent f008917 commit 1357900

3 files changed

Lines changed: 100 additions & 22 deletions

File tree

nitro.config.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,7 @@ export default defineNitroConfig({
3535
experimental: {
3636
openAPI: true,
3737
},
38-
hooks: {
39-
"prerender:generate"(entry) {
40-
if (/scalar|swagger/.test(entry.route)) {
41-
return (entry.skip = true);
42-
}
43-
if (entry.route === "/_openapi.json") {
44-
const json = JSON.parse(entry.contents);
45-
json.servers = [{ url: "https://ungh.cc" }];
46-
for (const key in json.paths) {
47-
if (json.paths[key].get?.tags?.includes("Internal")) {
48-
delete json.paths[key];
49-
} else {
50-
json.paths[key].get.tags = [];
51-
}
52-
}
53-
entry.contents = JSON.stringify(json, undefined, 2);
54-
}
55-
},
56-
},
5738
openAPI: {
58-
// production: "prerender",
59-
production: "runtime",
6039
meta: {
6140
title: "🐙 ungh.cc",
6241
description: `Unlimited access to GitHub API. <br><br> ⭐ [Star on GitHub](https://github.com/unjs/ungh) <br> 💛 Hosting sponsored by [Vercel](https://vercel.com/?utm_source=ungh)`,

routes/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defineRouteMeta({
1010
export default eventHandler((event) =>
1111
renderHTML({
1212
renderer: (getQuery(event).renderer as any) || "scalar",
13-
spec: "/_openapi.json",
13+
spec: "/openapi.json",
1414
meta: {
1515
title: "🐙 ungh.cc | Unlimited access to GitHub API",
1616
},

routes/openapi.json.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* Temporary fork from https://github.com/nitrojs/nitro/blob/v2/src/runtime/internal/routes/openapi.ts
3+
*/
4+
5+
import { eventHandler, getRequestURL } from "h3";
6+
import { joinURL } from "ufo";
7+
import { defu } from "defu";
8+
9+
// @ts-ignore
10+
import { handlersMeta } from "#nitro-internal-virtual/server-handlers-meta";
11+
12+
import { useRuntimeConfig } from "nitropack/runtime";
13+
14+
export default eventHandler((event) => {
15+
const runtimeConfig = useRuntimeConfig(event);
16+
const base = runtimeConfig.app?.baseURL;
17+
const url = joinURL(getRequestURL(event).origin, base);
18+
const meta = {
19+
title: "UNGH API",
20+
...runtimeConfig.nitro?.openAPI?.meta,
21+
};
22+
const {
23+
paths,
24+
globals: { components, ...globalsRest },
25+
} = getHandlersMeta() as any;
26+
const extensible = Object.fromEntries(
27+
Object.entries(globalsRest).filter(([key]) => key.startsWith("x-")),
28+
);
29+
return {
30+
openapi: "3.1.0",
31+
info: {
32+
title: meta?.title,
33+
version: meta?.version,
34+
description: meta?.description,
35+
},
36+
servers: [{ url }],
37+
paths,
38+
components,
39+
...extensible,
40+
};
41+
});
42+
function getHandlersMeta() {
43+
const paths = {};
44+
let globals = {};
45+
for (const h of handlersMeta) {
46+
const { route, parameters } = normalizeRoute(h.route || "");
47+
if (route === "/" || route.startsWith("/_") || route.endsWith(".json")) {
48+
continue; // Skip internal routes
49+
}
50+
const tags = [];
51+
const method = (h.method || "get").toLowerCase();
52+
const { $global, ...openAPI } = h.meta?.openAPI || {};
53+
const item = {
54+
[method]: {
55+
tags,
56+
parameters,
57+
responses: {
58+
200: { description: "OK" },
59+
},
60+
...openAPI,
61+
},
62+
};
63+
if ($global) {
64+
globals = defu($global, globals);
65+
}
66+
if (paths[route] === void 0) {
67+
paths[route] = item;
68+
} else {
69+
Object.assign(paths[route], item);
70+
}
71+
}
72+
return { paths, globals };
73+
}
74+
75+
function normalizeRoute(_route) {
76+
const parameters = [];
77+
let anonymousCtr = 0;
78+
const route = _route
79+
.replace(/:(\w+)/g, (_, name) => `{${name}}`)
80+
.replace(/\/(\*)\//g, () => `/{param${++anonymousCtr}}/`)
81+
.replace(/\*\*{/, "{")
82+
.replace(/\/(\*\*)$/g, () => `/{*param${++anonymousCtr}}`);
83+
const paramMatches = route.matchAll(/{(\*?\w+)}/g);
84+
for (const match of paramMatches) {
85+
const name = match[1];
86+
if (!parameters.some((p) => p.name === name)) {
87+
parameters.push({
88+
name,
89+
in: "path",
90+
required: true,
91+
schema: { type: "string" },
92+
});
93+
}
94+
}
95+
return {
96+
route,
97+
parameters,
98+
};
99+
}

0 commit comments

Comments
 (0)