@tsed/swagger 8.2.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/SwaggerModule.js +27 -83
- package/lib/esm/SwaggerModule.js.map +1 -1
- package/lib/esm/constants.js +2 -1
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/exports.js +2 -0
- package/lib/esm/exports.js.map +1 -0
- package/lib/esm/index.js +1 -8
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/middlewares/indexMiddleware.js +9 -5
- package/lib/esm/middlewares/indexMiddleware.js.map +1 -1
- package/lib/types/SwaggerModule.d.ts +13 -23
- package/lib/types/exports.d.ts +1 -0
- package/lib/types/index.d.ts +1 -8
- package/lib/types/interfaces/SwaggerSettings.d.ts +6 -82
- package/lib/types/middlewares/indexMiddleware.d.ts +1 -2
- package/lib/views/assets/swagger.css +16 -0
- package/lib/views/index.ejs +4 -53
- package/package.json +17 -19
- package/readme.md +8 -8
- package/src/SwaggerModule.spec.ts +7 -7
- package/src/SwaggerModule.ts +37 -104
- package/src/constants.ts +2 -1
- package/src/exports.ts +1 -0
- package/src/index.ts +1 -8
- package/src/interfaces/SwaggerSettings.ts +6 -85
- package/src/middlewares/indexMiddleware.spec.ts +5 -3
- package/src/middlewares/indexMiddleware.ts +10 -5
- package/views/assets/swagger.css +16 -0
- package/views/index.ejs +4 -53
- package/lib/esm/decorators/docs.js +0 -14
- package/lib/esm/decorators/docs.js.map +0 -1
- package/lib/esm/middlewares/cssMiddleware.js +0 -18
- package/lib/esm/middlewares/cssMiddleware.js.map +0 -1
- package/lib/esm/middlewares/jsMiddleware.js +0 -13
- package/lib/esm/middlewares/jsMiddleware.js.map +0 -1
- package/lib/esm/middlewares/redirectMiddleware.js +0 -12
- package/lib/esm/middlewares/redirectMiddleware.js.map +0 -1
- package/lib/esm/services/SwaggerService.js +0 -34
- package/lib/esm/services/SwaggerService.js.map +0 -1
- package/lib/esm/utils/includeRoute.js +0 -16
- package/lib/esm/utils/includeRoute.js.map +0 -1
- package/lib/esm/utils/matchPath.js +0 -5
- package/lib/esm/utils/matchPath.js.map +0 -1
- package/lib/esm/utils/readSpec.js +0 -12
- package/lib/esm/utils/readSpec.js.map +0 -1
- package/lib/types/decorators/docs.d.ts +0 -10
- package/lib/types/middlewares/cssMiddleware.d.ts +0 -6
- package/lib/types/middlewares/jsMiddleware.d.ts +0 -6
- package/lib/types/middlewares/redirectMiddleware.d.ts +0 -6
- package/lib/types/services/SwaggerService.d.ts +0 -15
- package/lib/types/utils/includeRoute.d.ts +0 -3
- package/lib/types/utils/matchPath.d.ts +0 -1
- package/lib/types/utils/readSpec.d.ts +0 -1
- package/src/decorators/docs.ts +0 -14
- package/src/middlewares/cssMiddleware.spec.ts +0 -24
- package/src/middlewares/cssMiddleware.ts +0 -19
- package/src/middlewares/jsMiddleware.spec.ts +0 -24
- package/src/middlewares/jsMiddleware.ts +0 -14
- package/src/middlewares/redirectMiddleware.spec.ts +0 -31
- package/src/middlewares/redirectMiddleware.ts +0 -13
- package/src/services/SwaggerService.spec.ts +0 -19
- package/src/services/SwaggerService.ts +0 -51
- package/src/services/__snapshots__/SwaggerService.spec.ts.snap +0 -11
- package/src/utils/includeRoute.spec.ts +0 -111
- package/src/utils/includeRoute.ts +0 -22
- package/src/utils/matchPath.spec.ts +0 -16
- package/src/utils/matchPath.ts +0 -5
- package/src/utils/readSpec.ts +0 -11
|
@@ -2,11 +2,12 @@ import {logger} from "@tsed/di";
|
|
|
2
2
|
import {application} from "@tsed/platform-http";
|
|
3
3
|
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
4
4
|
import {PlatformRouter} from "@tsed/platform-router";
|
|
5
|
-
import Fs from "fs";
|
|
6
5
|
import {absolutePath} from "swagger-ui-dist";
|
|
7
6
|
|
|
8
7
|
import {SwaggerModule} from "./SwaggerModule.js";
|
|
9
8
|
|
|
9
|
+
vi.mock("node:fs/promises");
|
|
10
|
+
|
|
10
11
|
describe("SwaggerModule", () => {
|
|
11
12
|
beforeEach(() =>
|
|
12
13
|
PlatformTest.create({
|
|
@@ -15,8 +16,8 @@ describe("SwaggerModule", () => {
|
|
|
15
16
|
swagger: [
|
|
16
17
|
{
|
|
17
18
|
path: "/doc",
|
|
18
|
-
cssPath: "/cssPath",
|
|
19
|
-
jsPath: "/jsPath",
|
|
19
|
+
cssPath: "/cssPath/style.css",
|
|
20
|
+
jsPath: "/jsPath/script.js",
|
|
20
21
|
viewPath: "/viewsPath",
|
|
21
22
|
outFile: "/spec.json"
|
|
22
23
|
}
|
|
@@ -40,8 +41,8 @@ describe("SwaggerModule", () => {
|
|
|
40
41
|
expect(application().use).toHaveBeenCalledWith("/doc", expect.any(Function));
|
|
41
42
|
expect(application().use).toHaveBeenCalledWith("/doc", expect.any(PlatformRouter));
|
|
42
43
|
expect(PlatformRouter.prototype.get).toHaveBeenCalledWith("/swagger.json", expect.any(Function));
|
|
43
|
-
expect(PlatformRouter.prototype.get).toHaveBeenCalledWith("/
|
|
44
|
-
expect(PlatformRouter.prototype.get).toHaveBeenCalledWith("/", expect.any(Function));
|
|
44
|
+
expect(PlatformRouter.prototype.get).toHaveBeenCalledWith("/style.css", expect.any(Function));
|
|
45
|
+
expect(PlatformRouter.prototype.get).toHaveBeenCalledWith("/script.js", expect.any(Function));
|
|
45
46
|
expect(PlatformRouter.prototype.statics).toHaveBeenCalledWith("/", {
|
|
46
47
|
root: absolutePath()
|
|
47
48
|
});
|
|
@@ -52,12 +53,11 @@ describe("SwaggerModule", () => {
|
|
|
52
53
|
it("should display the right log", async () => {
|
|
53
54
|
const mod = await PlatformTest.invoke<SwaggerModule>(SwaggerModule);
|
|
54
55
|
|
|
55
|
-
vi.spyOn(Fs, "writeFile");
|
|
56
56
|
vi.spyOn(logger(), "info");
|
|
57
57
|
|
|
58
58
|
mod.$onReady();
|
|
59
59
|
|
|
60
|
-
expect(logger().info).toHaveBeenCalledWith("[default]
|
|
60
|
+
expect(logger().info).toHaveBeenCalledWith("[default] OpenAPI JSON is available on https://0.0.0.0:8081/doc/swagger.json");
|
|
61
61
|
expect(logger().info).toHaveBeenCalledWith("[default] Swagger UI is available on https://0.0.0.0:8081/doc/");
|
|
62
62
|
});
|
|
63
63
|
});
|
package/src/SwaggerModule.ts
CHANGED
|
@@ -1,133 +1,66 @@
|
|
|
1
|
-
import Fs from "node:fs";
|
|
2
1
|
import {join} from "node:path";
|
|
3
2
|
|
|
4
|
-
import {
|
|
5
|
-
import {configuration, constant, inject, injectable, logger, ProviderType} from "@tsed/di";
|
|
3
|
+
import {constant, injectable, ProviderType} from "@tsed/di";
|
|
6
4
|
import {normalizePath} from "@tsed/normalize-path";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import {OpenAPIBaseModule} from "@tsed/openapi-utils";
|
|
6
|
+
import {useContextHandler} from "@tsed/platform-router";
|
|
9
7
|
|
|
10
8
|
import {ROOT_DIR, SWAGGER_UI_DIST} from "./constants.js";
|
|
11
9
|
import {SwaggerSettings} from "./interfaces/SwaggerSettings.js";
|
|
12
|
-
import {cssMiddleware} from "./middlewares/cssMiddleware.js";
|
|
13
10
|
import {indexMiddleware} from "./middlewares/indexMiddleware.js";
|
|
14
|
-
import {jsMiddleware} from "./middlewares/jsMiddleware.js";
|
|
15
|
-
import {redirectMiddleware} from "./middlewares/redirectMiddleware.js";
|
|
16
|
-
import {SwaggerService} from "./services/SwaggerService.js";
|
|
17
11
|
|
|
18
|
-
export class SwaggerModule
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
protected disableRoutesSummary = constant<boolean>("logger.disableRoutesSummary");
|
|
22
|
-
|
|
23
|
-
private loaded = false;
|
|
12
|
+
export class SwaggerModule extends OpenAPIBaseModule {
|
|
13
|
+
readonly name = "Swagger";
|
|
14
|
+
readonly rootDir = ROOT_DIR;
|
|
24
15
|
|
|
25
16
|
get settings() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.settings.forEach((conf: SwaggerSettings) => {
|
|
40
|
-
const {path = "/"} = conf;
|
|
41
|
-
|
|
42
|
-
application().use(path, useContextHandler(redirectMiddleware(path)));
|
|
43
|
-
application().use(path, this.createRouter(conf, urls));
|
|
17
|
+
const settings = constant<SwaggerSettings[]>("swagger", []).filter((o) => !!o);
|
|
18
|
+
|
|
19
|
+
return settings.map((conf) => {
|
|
20
|
+
return Object.assign(
|
|
21
|
+
{
|
|
22
|
+
disableSpec: false,
|
|
23
|
+
path: "/",
|
|
24
|
+
fileName: "swagger.json",
|
|
25
|
+
cssPath: join(ROOT_DIR, "views/assets/swagger.css"),
|
|
26
|
+
viewPath: join(ROOT_DIR, "views/index.ejs")
|
|
27
|
+
},
|
|
28
|
+
conf
|
|
29
|
+
);
|
|
44
30
|
});
|
|
45
|
-
|
|
46
|
-
this.loaded = true;
|
|
47
31
|
}
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const host = configuration().getBestHost();
|
|
53
|
-
const url = host.toString();
|
|
33
|
+
protected createRouter(conf: SwaggerSettings) {
|
|
34
|
+
const {viewPath} = conf;
|
|
35
|
+
const router = super.createRouter(conf);
|
|
54
36
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
37
|
+
if (viewPath) {
|
|
38
|
+
router.get(
|
|
39
|
+
"/",
|
|
40
|
+
useContextHandler(
|
|
41
|
+
indexMiddleware(viewPath, {
|
|
42
|
+
urls: this.getUrls(),
|
|
43
|
+
...conf
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
router.statics("/", {root: SWAGGER_UI_DIST});
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
generateSpecFiles() {
|
|
71
|
-
return Promise.all(
|
|
72
|
-
this.settings.map(async (conf) => {
|
|
73
|
-
const {outFile} = conf;
|
|
74
|
-
|
|
75
|
-
if (this.env === Env.PROD || outFile) {
|
|
76
|
-
const spec = await this.swaggerService.getOpenAPISpec(conf);
|
|
77
|
-
|
|
78
|
-
if (outFile) {
|
|
79
|
-
return Fs.writeFile(outFile, JSON.stringify(spec, null, 2), {encoding: "utf8"}, () => {});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
);
|
|
50
|
+
return router;
|
|
84
51
|
}
|
|
85
52
|
|
|
86
|
-
|
|
53
|
+
protected getUrls() {
|
|
87
54
|
return this.settings.reduce((acc: any[], conf) => {
|
|
88
|
-
const {path
|
|
55
|
+
const {path, fileName, doc, hidden} = conf;
|
|
89
56
|
|
|
90
57
|
if (!hidden) {
|
|
91
|
-
acc.push({url: normalizePath(path, fileName), name: doc || path});
|
|
58
|
+
acc.push({url: normalizePath(path, fileName!), name: doc || path});
|
|
92
59
|
}
|
|
93
60
|
|
|
94
61
|
return acc;
|
|
95
62
|
}, []);
|
|
96
63
|
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
*
|
|
100
|
-
* @param conf
|
|
101
|
-
* @param urls
|
|
102
|
-
*/
|
|
103
|
-
private createRouter(conf: SwaggerSettings, urls: string[]) {
|
|
104
|
-
const {disableSpec = false, fileName = "swagger.json", cssPath, jsPath, viewPath = join(ROOT_DIR, "../views/index.ejs")} = conf;
|
|
105
|
-
const router = new PlatformRouter();
|
|
106
|
-
|
|
107
|
-
if (!disableSpec) {
|
|
108
|
-
router.get(normalizePath("/", fileName), useContextHandler(this.middlewareSwaggerJson(conf)));
|
|
109
|
-
}
|
|
110
|
-
if (viewPath) {
|
|
111
|
-
if (cssPath) {
|
|
112
|
-
router.get("/main.css", useContextHandler(cssMiddleware(cssPath)));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (jsPath) {
|
|
116
|
-
router.get("/main.js", useContextHandler(jsMiddleware(jsPath)));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
router.get("/", useContextHandler(indexMiddleware(viewPath, {urls, ...conf})));
|
|
120
|
-
router.statics("/", {root: SWAGGER_UI_DIST});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return router;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private middlewareSwaggerJson(conf: SwaggerSettings) {
|
|
127
|
-
return async (ctx: PlatformContext) => {
|
|
128
|
-
ctx.response.status(200).body(await this.swaggerService.getOpenAPISpec(conf));
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
64
|
}
|
|
132
65
|
|
|
133
66
|
injectable(SwaggerModule).type(ProviderType.MODULE);
|
package/src/constants.ts
CHANGED
package/src/exports.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {Docs, OpenAPIService as SwaggerService} from "@tsed/openapi-utils";
|
package/src/index.ts
CHANGED
|
@@ -2,15 +2,8 @@
|
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
4
|
export * from "./constants.js";
|
|
5
|
-
export * from "./
|
|
5
|
+
export * from "./exports.js";
|
|
6
6
|
export * from "./interfaces/interfaces.js";
|
|
7
7
|
export * from "./interfaces/SwaggerSettings.js";
|
|
8
|
-
export * from "./middlewares/cssMiddleware.js";
|
|
9
8
|
export * from "./middlewares/indexMiddleware.js";
|
|
10
|
-
export * from "./middlewares/jsMiddleware.js";
|
|
11
|
-
export * from "./middlewares/redirectMiddleware.js";
|
|
12
|
-
export * from "./services/SwaggerService.js";
|
|
13
9
|
export * from "./SwaggerModule.js";
|
|
14
|
-
export * from "./utils/includeRoute.js";
|
|
15
|
-
export * from "./utils/matchPath.js";
|
|
16
|
-
export * from "./utils/readSpec.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {OpenAPI3Settings, OpenApiSettings, Swagger2Settings} from "@tsed/openapi-utils";
|
|
2
2
|
|
|
3
3
|
export interface SwaggerUIOptions {
|
|
4
4
|
configUrl?: string;
|
|
@@ -12,91 +12,12 @@ export interface SwaggerUIOptions {
|
|
|
12
12
|
[key: string]: any;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
path: string;
|
|
20
|
-
/**
|
|
21
|
-
* Specify the spec version you want to generate.
|
|
22
|
-
*/
|
|
23
|
-
specVersion?: OpenSpecVersions;
|
|
24
|
-
/**
|
|
25
|
-
* Swagger file name. By default swagger.json
|
|
26
|
-
*/
|
|
27
|
-
fileName?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Hidden documentation. Use this to hide documentation link in the dropdown.
|
|
30
|
-
*/
|
|
31
|
-
hidden?: string;
|
|
32
|
-
/**
|
|
33
|
-
* The documentation key used by `@Docs` decorator to create several swagger documentations.
|
|
34
|
-
*/
|
|
35
|
-
doc?: string;
|
|
36
|
-
/**
|
|
37
|
-
* The path to the CSS file.
|
|
38
|
-
*/
|
|
39
|
-
cssPath?: string;
|
|
40
|
-
/**
|
|
41
|
-
* The path to the JS file.
|
|
42
|
-
*/
|
|
43
|
-
jsPath?: string;
|
|
44
|
-
/**
|
|
45
|
-
* The path to the ejs file to create html page.
|
|
46
|
-
*/
|
|
47
|
-
viewPath?: string | false;
|
|
15
|
+
export type SwaggerOS2Settings = Swagger2Settings;
|
|
16
|
+
export type SwaggerOS3Settings = OpenAPI3Settings;
|
|
17
|
+
export type SwaggerSettings = OpenApiSettings & {
|
|
18
|
+
showExplorer?: boolean;
|
|
48
19
|
/**
|
|
49
20
|
* SwaggerUI options. See (https://github.com/swagger-api/swagger-ui/blob/HEAD/docs/usage/configuration.md)
|
|
50
21
|
*/
|
|
51
22
|
options?: SwaggerUIOptions;
|
|
52
|
-
|
|
53
|
-
* Display the search field in the navbar.
|
|
54
|
-
*/
|
|
55
|
-
showExplorer?: boolean;
|
|
56
|
-
/**
|
|
57
|
-
* Load the base spec documentation from the specified path.
|
|
58
|
-
*/
|
|
59
|
-
specPath?: string;
|
|
60
|
-
/**
|
|
61
|
-
* Write the `swagger.json` spec documentation on the specified path.
|
|
62
|
-
*/
|
|
63
|
-
outFile?: string;
|
|
64
|
-
/**
|
|
65
|
-
* Sort paths by alphabetical order
|
|
66
|
-
*/
|
|
67
|
-
sortPaths?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* A function to generate the operationId.
|
|
70
|
-
*/
|
|
71
|
-
operationIdFormatter?: (name: string, propertyKey: string, path: string) => string;
|
|
72
|
-
/**
|
|
73
|
-
* A pattern to generate the operationId. Format of operationId field (%c: class name, %m: method name).
|
|
74
|
-
*/
|
|
75
|
-
operationIdPattern?: string;
|
|
76
|
-
/**
|
|
77
|
-
*
|
|
78
|
-
*/
|
|
79
|
-
disableSpec?: boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Include only controllers whose paths match the pattern list provided.
|
|
82
|
-
*/
|
|
83
|
-
pathPatterns?: string[];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface SwaggerOS2Settings extends SwaggerSettingsBase {
|
|
87
|
-
specVersion?: OS2Versions;
|
|
88
|
-
/**
|
|
89
|
-
* OpenSpec 2
|
|
90
|
-
*/
|
|
91
|
-
spec?: Partial<OpenSpec2>;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface SwaggerOS3Settings extends SwaggerSettingsBase {
|
|
95
|
-
specVersion?: OS3Versions;
|
|
96
|
-
/**
|
|
97
|
-
* OpenSpec 3
|
|
98
|
-
*/
|
|
99
|
-
spec?: Partial<OpenSpec3>;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export type SwaggerSettings = SwaggerOS2Settings | SwaggerOS3Settings;
|
|
23
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {runInContext} from "@tsed/di";
|
|
1
2
|
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
2
3
|
|
|
3
4
|
import {indexMiddleware} from "./indexMiddleware.js";
|
|
@@ -13,18 +14,19 @@ describe("indexMiddleware and redirect", () => {
|
|
|
13
14
|
const conf = {
|
|
14
15
|
path: "/doc",
|
|
15
16
|
options: {},
|
|
17
|
+
fileName: "swagger.json",
|
|
16
18
|
showExplorer: false,
|
|
17
19
|
cssPath: "/path.css",
|
|
18
20
|
jsPath: "/path.js",
|
|
19
21
|
urls: []
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
await indexMiddleware(viewPath, conf)(
|
|
24
|
+
await runInContext(ctx, () => indexMiddleware(viewPath, conf)());
|
|
23
25
|
|
|
24
26
|
expect(ctx.response.render).toHaveBeenCalledWith(viewPath, {
|
|
25
27
|
spec: {},
|
|
26
|
-
cssPath: "/path.css",
|
|
27
|
-
jsPath: "/path.js",
|
|
28
|
+
cssPath: "/doc/path.css",
|
|
29
|
+
jsPath: "/doc/path.js",
|
|
28
30
|
showExplorer: false,
|
|
29
31
|
swaggerOptions: {},
|
|
30
32
|
url: "/doc/swagger.json",
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import {basename} from "node:path";
|
|
2
|
+
|
|
3
|
+
import {context} from "@tsed/di";
|
|
1
4
|
import {PlatformContext} from "@tsed/platform-http";
|
|
5
|
+
import {join} from "path";
|
|
2
6
|
|
|
3
7
|
import {SwaggerSettings} from "../interfaces/SwaggerSettings.js";
|
|
4
8
|
|
|
@@ -8,17 +12,18 @@ import {SwaggerSettings} from "../interfaces/SwaggerSettings.js";
|
|
|
8
12
|
* @param conf
|
|
9
13
|
*/
|
|
10
14
|
export function indexMiddleware(viewPath: string, conf: SwaggerSettings & {urls: string[]}) {
|
|
11
|
-
return async (
|
|
12
|
-
const
|
|
15
|
+
return async () => {
|
|
16
|
+
const ctx = context();
|
|
17
|
+
const {path, options = {}, fileName, showExplorer, cssPath, jsPath, urls} = conf;
|
|
13
18
|
|
|
14
19
|
ctx.response.body(
|
|
15
20
|
await ctx.response.render(viewPath, {
|
|
16
21
|
spec: {},
|
|
17
|
-
url: `${path}
|
|
22
|
+
url: `${path}/${fileName}`,
|
|
18
23
|
urls,
|
|
19
24
|
showExplorer,
|
|
20
|
-
cssPath,
|
|
21
|
-
jsPath,
|
|
25
|
+
cssPath: cssPath && join(path, basename(cssPath)),
|
|
26
|
+
jsPath: jsPath && join(path, basename(jsPath)),
|
|
22
27
|
swaggerOptions: options
|
|
23
28
|
})
|
|
24
29
|
);
|
package/views/index.ejs
CHANGED
|
@@ -9,32 +9,14 @@
|
|
|
9
9
|
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32"/>
|
|
10
10
|
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16"/>
|
|
11
11
|
<style>
|
|
12
|
-
html {
|
|
13
|
-
box-sizing: border-box;
|
|
14
|
-
overflow: -moz-scrollbars-vertical;
|
|
15
|
-
overflow-y: scroll;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
*,
|
|
19
|
-
*:before,
|
|
20
|
-
*:after {
|
|
21
|
-
box-sizing: inherit;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
body {
|
|
25
|
-
margin: 0;
|
|
26
|
-
background: #fafafa;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
12
|
<% if (!showExplorer) { %>
|
|
30
13
|
.swagger-ui .topbar .download-url-wrapper {
|
|
31
14
|
display: none
|
|
32
15
|
}
|
|
33
|
-
|
|
34
16
|
<% } %>
|
|
35
17
|
</style>
|
|
36
18
|
<% if (cssPath) { %>
|
|
37
|
-
<link rel="stylesheet" type="text/css" href="
|
|
19
|
+
<link rel="stylesheet" type="text/css" href="<%= cssPath %>">
|
|
38
20
|
<% } %>
|
|
39
21
|
</head>
|
|
40
22
|
|
|
@@ -43,45 +25,14 @@
|
|
|
43
25
|
|
|
44
26
|
<script src="./swagger-ui-bundle.js"></script>
|
|
45
27
|
<script src="./swagger-ui-standalone-preset.js"></script>
|
|
46
|
-
<script>
|
|
47
|
-
if (typeof Object.assign !== 'function') {
|
|
48
|
-
// Must be writable: true, enumerable: false, configurable: true
|
|
49
|
-
Object.defineProperty(Object, "assign", {
|
|
50
|
-
value: function assign(target, varArgs) { // .length of function is 2
|
|
51
|
-
'use strict';
|
|
52
|
-
if (target == null) { // TypeError if undefined or null
|
|
53
|
-
throw new TypeError('Cannot convert undefined or null to object');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var to = Object(target);
|
|
57
28
|
|
|
58
|
-
for (var index = 1; index < arguments.length; index++) {
|
|
59
|
-
var nextSource = arguments[index];
|
|
60
|
-
|
|
61
|
-
if (nextSource != null) { // Skip over if undefined or null
|
|
62
|
-
for (var nextKey in nextSource) {
|
|
63
|
-
// Avoid bugs when hasOwnProperty is shadowed
|
|
64
|
-
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
|
65
|
-
to[nextKey] = nextSource[nextKey];
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return to;
|
|
71
|
-
},
|
|
72
|
-
writable: true,
|
|
73
|
-
configurable: true
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
</script>
|
|
77
29
|
<script>
|
|
78
|
-
const origin = window.location.origin;
|
|
79
30
|
const initialOptions = <%- JSON.stringify(swaggerOptions) %>;
|
|
80
|
-
const currentUrl = origin + "<%- url %>";
|
|
31
|
+
const currentUrl = window.origin + "<%- url %>";
|
|
81
32
|
const urls = <%- JSON.stringify(urls) %>
|
|
82
33
|
.map(function (o) {
|
|
83
34
|
if (!o.url.match(/^https?:/)) {
|
|
84
|
-
const url = origin + o.url;
|
|
35
|
+
const url = window.origin + o.url;
|
|
85
36
|
return {
|
|
86
37
|
name: o.name,
|
|
87
38
|
url: url,
|
|
@@ -132,7 +83,7 @@
|
|
|
132
83
|
|
|
133
84
|
</script>
|
|
134
85
|
<% if (jsPath) { %>
|
|
135
|
-
<script src="
|
|
86
|
+
<script src="<%= jsPath %>"></script>
|
|
136
87
|
<% } %>
|
|
137
88
|
<script>
|
|
138
89
|
window.onload = function () {
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { StoreMerge } from "@tsed/core";
|
|
2
|
-
/**
|
|
3
|
-
* Set the type documentation for this class.
|
|
4
|
-
*
|
|
5
|
-
* See [swagger documentation](/tutorials/swagger.html)
|
|
6
|
-
*
|
|
7
|
-
* @decorator
|
|
8
|
-
* @swagger
|
|
9
|
-
* @param docs
|
|
10
|
-
*/
|
|
11
|
-
export function Docs(...docs) {
|
|
12
|
-
return StoreMerge("docs", docs);
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=docs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/decorators/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AAEtC;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAC,GAAG,IAAc;IACpC,OAAO,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import Fs from "fs";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
/**
|
|
4
|
-
* @ignore
|
|
5
|
-
* @param path
|
|
6
|
-
*/
|
|
7
|
-
export function cssMiddleware(path) {
|
|
8
|
-
return (ctx) => {
|
|
9
|
-
const content = Fs.readFileSync(resolve(path), { encoding: "utf8" });
|
|
10
|
-
ctx.response
|
|
11
|
-
.setHeaders({
|
|
12
|
-
"Content-Type": "text/css"
|
|
13
|
-
})
|
|
14
|
-
.status(200)
|
|
15
|
-
.body(content);
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=cssMiddleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cssMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/cssMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,CAAC,GAAoB,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,CAAC,CAAC;QACnE,GAAG,CAAC,QAAQ;aACT,UAAU,CAAC;YACV,cAAc,EAAE,UAAU;SAC3B,CAAC;aACD,MAAM,CAAC,GAAG,CAAC;aACX,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import Fs from "fs";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
/**
|
|
4
|
-
* @ignore
|
|
5
|
-
* @param path
|
|
6
|
-
*/
|
|
7
|
-
export function jsMiddleware(path) {
|
|
8
|
-
return (ctx) => {
|
|
9
|
-
const content = Fs.readFileSync(resolve(path), { encoding: "utf8" });
|
|
10
|
-
ctx.response.setHeaders({ "Content-Type": "application/javascript" }).status(200).body(content);
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=jsMiddleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/jsMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,CAAC,GAAoB,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,CAAC,CAAC;QACnE,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAC,cAAc,EAAE,wBAAwB,EAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChG,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @ignore
|
|
3
|
-
* @param path
|
|
4
|
-
*/
|
|
5
|
-
export function redirectMiddleware(path) {
|
|
6
|
-
return (ctx) => {
|
|
7
|
-
if (ctx.request.method?.toUpperCase() === "GET" && ctx.request.url === path && !ctx.request.url.match(/\/$/)) {
|
|
8
|
-
ctx.response.redirect(302, `${path}/`);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=redirectMiddleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"redirectMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/redirectMiddleware.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,CAAC,GAAoB,EAAE,EAAE;QAC9B,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7G,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { constant, inject, injectable } from "@tsed/di";
|
|
2
|
-
import { Platform } from "@tsed/platform-http";
|
|
3
|
-
import { generateSpec } from "@tsed/schema";
|
|
4
|
-
import { includeRoute } from "../utils/includeRoute.js";
|
|
5
|
-
import { readSpec } from "../utils/readSpec.js";
|
|
6
|
-
export class SwaggerService {
|
|
7
|
-
#specs;
|
|
8
|
-
constructor() {
|
|
9
|
-
this.platform = inject(Platform);
|
|
10
|
-
this.#specs = new Map();
|
|
11
|
-
}
|
|
12
|
-
async getOpenAPISpec(conf) {
|
|
13
|
-
if (!this.#specs.has(conf.path)) {
|
|
14
|
-
const version = constant("version", "1.0.0");
|
|
15
|
-
const acceptMimes = constant("acceptMimes");
|
|
16
|
-
const specPath = conf.specPath;
|
|
17
|
-
const tokens = this.platform
|
|
18
|
-
.getMountedControllers()
|
|
19
|
-
.filter(({ routes, provider }) => [...routes.values()].some((route) => includeRoute(route, provider, conf)))
|
|
20
|
-
.map(({ route, provider }) => ({ token: provider.token, rootPath: route }));
|
|
21
|
-
const spec = generateSpec({
|
|
22
|
-
tokens,
|
|
23
|
-
...conf,
|
|
24
|
-
fileSpec: specPath ? await readSpec(specPath) : {},
|
|
25
|
-
version,
|
|
26
|
-
acceptMimes
|
|
27
|
-
});
|
|
28
|
-
this.#specs.set(conf.path, spec);
|
|
29
|
-
}
|
|
30
|
-
return this.#specs.get(conf.path);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
injectable(SwaggerService);
|
|
34
|
-
//# sourceMappingURL=SwaggerService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SwaggerService.js","sourceRoot":"","sources":["../../../src/services/SwaggerService.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAE9C,MAAM,OAAO,cAAc;IAGzB,MAAM,CAAiD;IAEvD;QAJU,aAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEtC,WAAM,GAAuC,IAAI,GAAG,EAAE,CAAC;IAExC,CAAC;IAST,KAAK,CAAC,cAAc,CAAC,IAAqB;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,WAAW,GAAG,QAAQ,CAAS,aAAa,CAAC,CAAC;YACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAE/B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ;iBACzB,qBAAqB,EAAE;iBACvB,MAAM,CAAC,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;iBACzG,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAa,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;YAElF,MAAM,IAAI,GAAG,YAAY,CAAC;gBACxB,MAAM;gBACN,GAAG,IAAI;gBACP,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;gBAClD,OAAO;gBACP,WAAW;aACZ,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF;AAED,UAAU,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { matchPath } from "./matchPath.js";
|
|
2
|
-
export function includeRoute(route, provider, conf) {
|
|
3
|
-
const hidden = provider.store.get("hidden");
|
|
4
|
-
const docs = provider.store.get("docs") || [];
|
|
5
|
-
const { doc, pathPatterns } = conf;
|
|
6
|
-
const inDoc = doc && docs.indexOf(doc) > -1;
|
|
7
|
-
const pathPatternMatch = pathPatterns && matchPath(route, pathPatterns);
|
|
8
|
-
if (hidden) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
if (!doc && !pathPatterns) {
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
return !!(inDoc || pathPatternMatch);
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=includeRoute.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"includeRoute.js","sourceRoot":"","sources":["../../../src/utils/includeRoute.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAEzC,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAkB,EAAE,IAAqB;IACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,EAAC,GAAG,EAAE,YAAY,EAAC,GAAG,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,YAAY,IAAI,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAExE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAC;AACvC,CAAC"}
|