Skip to content

Commit ac4948b

Browse files
author
DylanBulmer
committed
improve dynamic route detection; add test cases; add 202 resp
1 parent f45a68e commit ac4948b

File tree

7 files changed

+96
-33
lines changed

7 files changed

+96
-33
lines changed

.swcrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "http://json.schemastore.org/swcrc",
2+
"$schema": "https://json.schemastore.org/swcrc.json",
33
"jsc": {
44
"parser": {
55
"syntax": "typescript",

jest.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"transform": {
3-
"^.+\\.(t|j)sx?$": ["@swc/jest"]
3+
"^.+\\.(t|j)sx?$": "@swc/jest"
44
},
5-
"testRegex": "/__tests__/.*\\.(test|spec)\\.(jsx?|tsx?)$",
5+
"testRegex": "/src/__tests__/.*\\.(test|spec)\\.(jsx?|tsx?)$",
66
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
77
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dylanbulmer/openapi",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"main": "index.js",
55
"author": "Dylan Bulmer <dylan@bulmersolutions.com>",
66
"license": "MIT",

src/__tests__/DynamicRoutes/DynamicRoutes.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import apiDoc from "../api-doc";
66

77
test("Dynamic routes", () => {
88
const app = express();
9-
109
return initialize({
1110
app,
1211
api: {
@@ -19,14 +18,15 @@ test("Dynamic routes", () => {
1918
// url: "/docs/elements"
2019
},
2120
}).then(doc => {
22-
// check if dynamic route exists
23-
expect(Object.keys(doc.paths as OpenAPIV3_1.PathsObject)).toContain(
24-
"/{test}",
21+
const paths = doc.paths as OpenAPIV3_1.PathsObject;
22+
const pathKeys = Object.keys(paths);
23+
// check if dynamic route file exists
24+
expect(pathKeys).toContain("/{test}");
25+
expect(paths["/{test}"]?.get?.description).toBe("Testing dynamic routes");
26+
// check if dynamic route folder exists
27+
expect(pathKeys).toContain("/{test2}");
28+
expect(paths["/{test2}"]?.get?.description).toBe(
29+
"Testing dynamic folder as route",
2530
);
26-
27-
// check if dynamic route's GET description is set
28-
expect(
29-
(doc.paths as OpenAPIV3_1.PathsObject)["/{test}"]?.get?.description,
30-
).toBe("Testing dynamic routes");
3131
});
3232
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Operation } from "../../../../types/Route";
2+
3+
export const GET: Operation =
4+
/* business middleware not expressible by OpenAPI documentation goes here */
5+
(req, res) => {
6+
res.status(200).json({ detail: { message: "OK" } });
7+
};
8+
9+
// 3.0 specification
10+
GET.apiDoc = {
11+
description: "Testing dynamic folder as route",
12+
tags: ["TEST"],
13+
responses: {
14+
"200": {
15+
$ref: "#/components/responses/200",
16+
content: {
17+
"application/json": {
18+
schema: {
19+
properties: {
20+
detail: {
21+
type: "object",
22+
properties: {
23+
message: {
24+
type: "string",
25+
examples: ["OK"],
26+
},
27+
},
28+
},
29+
},
30+
},
31+
},
32+
},
33+
},
34+
},
35+
};

src/classes/responses/202.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { OpenAPIV3_1 } from "openapi-types";
2+
3+
const R200: OpenAPIV3_1.ResponseObject = {
4+
description: `The HyperText Transfer Protocol (HTTP) \`202 Accepted\` response status code indicates that the request has been accepted for processing, but the processing has not been completed; in fact, processing may not have started yet. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
5+
6+
202 is non-committal, meaning that there is no way for the HTTP to later send an asynchronous response indicating the outcome of processing the request. It is intended for cases where another process or server handles the request, or for batch processing.
7+
([mdn docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202))`,
8+
content: {
9+
"application/json": {
10+
schema: {
11+
allOf: [{ $ref: "#/components/schemas/GenericSchema" }],
12+
properties: {
13+
detail: {
14+
type: "object",
15+
properties: {
16+
message: {
17+
type: "string",
18+
examples: ["accepted"],
19+
},
20+
},
21+
},
22+
},
23+
},
24+
},
25+
},
26+
};
27+
28+
export default R200;

src/index.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const initialize = function initialize({ app, api, ui }: IOptions) {
4646
: defaultDoc;
4747
}
4848

49+
// apply the route to express app.
4950
switch (key) {
5051
case "GET":
5152
app.get(r.url.express, operation);
@@ -124,33 +125,32 @@ const getFiles = async function* getFiles(
124125
} else {
125126
// else get file name and return details
126127
const routePath = dirent.name.replace(/\.(t|j)s/g, "");
127-
let routeName = routePath;
128-
let expressUrl: string;
129-
let openapiUrl: string;
128+
let currentPath;
130129

131-
// if route is dynamic, extract route name and adjust for express and openapi formating
132-
const nameRegex = /\[(?<name>.+)\]/i;
133-
if (nameRegex.test(routeName)) {
134-
routeName = routeName.match(nameRegex)?.groups?.name as string;
135-
expressUrl = `${basePath}:${routeName}`;
136-
openapiUrl = `${basePath}{${routeName}}`;
137-
} else if (routeName === "index") {
130+
// if route name is index, update url structure
131+
if (routePath === "index") {
132+
// if the base path is the root, change current path to root.
138133
if (basePath === "/") {
139-
expressUrl = `${basePath}`;
140-
openapiUrl = `${basePath}`;
141-
} else {
134+
currentPath = basePath;
135+
}
136+
// else update current path with the base path without the trailing slash.
137+
else {
142138
const base = basePath.substring(0, basePath.length - 1);
143-
expressUrl = `${base}`;
144-
openapiUrl = `${base}`;
139+
currentPath = base;
145140
}
146-
} else {
147-
expressUrl = `${basePath}${routeName}`;
148-
openapiUrl = `${basePath}${routeName}`;
141+
}
142+
// else set the current path to base path plus the route path
143+
else {
144+
currentPath = `${basePath}${routePath}`;
149145
}
150146

147+
// yeild result, replacing all dynamic routes to their appropriate form.
151148
yield {
152-
url: { express: expressUrl, openapi: openapiUrl },
153-
name: routeName,
149+
url: {
150+
express: currentPath.replace(/\[(?<name>.+)\]/i, ":$1"),
151+
openapi: currentPath.replace(/\[(?<name>.+)\]/i, "{$1}"),
152+
},
153+
name: routePath,
154154
path: `${basePath}${routePath}`,
155155
};
156156
}

0 commit comments

Comments
 (0)