@tsed/swagger 8.1.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.
Files changed (68) hide show
  1. package/lib/esm/SwaggerModule.js +27 -83
  2. package/lib/esm/SwaggerModule.js.map +1 -1
  3. package/lib/esm/constants.js +2 -1
  4. package/lib/esm/constants.js.map +1 -1
  5. package/lib/esm/exports.js +2 -0
  6. package/lib/esm/exports.js.map +1 -0
  7. package/lib/esm/index.js +1 -8
  8. package/lib/esm/index.js.map +1 -1
  9. package/lib/esm/middlewares/indexMiddleware.js +9 -5
  10. package/lib/esm/middlewares/indexMiddleware.js.map +1 -1
  11. package/lib/types/SwaggerModule.d.ts +13 -23
  12. package/lib/types/exports.d.ts +1 -0
  13. package/lib/types/index.d.ts +1 -8
  14. package/lib/types/interfaces/SwaggerSettings.d.ts +6 -82
  15. package/lib/types/middlewares/indexMiddleware.d.ts +1 -2
  16. package/lib/views/assets/swagger.css +16 -0
  17. package/lib/views/index.ejs +4 -53
  18. package/package.json +17 -19
  19. package/readme.md +8 -8
  20. package/src/SwaggerModule.spec.ts +7 -7
  21. package/src/SwaggerModule.ts +37 -104
  22. package/src/constants.ts +2 -1
  23. package/src/exports.ts +1 -0
  24. package/src/index.ts +1 -8
  25. package/src/interfaces/SwaggerSettings.ts +6 -85
  26. package/src/middlewares/indexMiddleware.spec.ts +5 -3
  27. package/src/middlewares/indexMiddleware.ts +10 -5
  28. package/views/assets/swagger.css +16 -0
  29. package/views/index.ejs +4 -53
  30. package/lib/esm/decorators/docs.js +0 -14
  31. package/lib/esm/decorators/docs.js.map +0 -1
  32. package/lib/esm/middlewares/cssMiddleware.js +0 -18
  33. package/lib/esm/middlewares/cssMiddleware.js.map +0 -1
  34. package/lib/esm/middlewares/jsMiddleware.js +0 -13
  35. package/lib/esm/middlewares/jsMiddleware.js.map +0 -1
  36. package/lib/esm/middlewares/redirectMiddleware.js +0 -12
  37. package/lib/esm/middlewares/redirectMiddleware.js.map +0 -1
  38. package/lib/esm/services/SwaggerService.js +0 -34
  39. package/lib/esm/services/SwaggerService.js.map +0 -1
  40. package/lib/esm/utils/includeRoute.js +0 -16
  41. package/lib/esm/utils/includeRoute.js.map +0 -1
  42. package/lib/esm/utils/matchPath.js +0 -5
  43. package/lib/esm/utils/matchPath.js.map +0 -1
  44. package/lib/esm/utils/readSpec.js +0 -12
  45. package/lib/esm/utils/readSpec.js.map +0 -1
  46. package/lib/types/decorators/docs.d.ts +0 -10
  47. package/lib/types/middlewares/cssMiddleware.d.ts +0 -6
  48. package/lib/types/middlewares/jsMiddleware.d.ts +0 -6
  49. package/lib/types/middlewares/redirectMiddleware.d.ts +0 -6
  50. package/lib/types/services/SwaggerService.d.ts +0 -15
  51. package/lib/types/utils/includeRoute.d.ts +0 -3
  52. package/lib/types/utils/matchPath.d.ts +0 -1
  53. package/lib/types/utils/readSpec.d.ts +0 -1
  54. package/src/decorators/docs.ts +0 -14
  55. package/src/middlewares/cssMiddleware.spec.ts +0 -24
  56. package/src/middlewares/cssMiddleware.ts +0 -19
  57. package/src/middlewares/jsMiddleware.spec.ts +0 -24
  58. package/src/middlewares/jsMiddleware.ts +0 -14
  59. package/src/middlewares/redirectMiddleware.spec.ts +0 -31
  60. package/src/middlewares/redirectMiddleware.ts +0 -13
  61. package/src/services/SwaggerService.spec.ts +0 -19
  62. package/src/services/SwaggerService.ts +0 -51
  63. package/src/services/__snapshots__/SwaggerService.spec.ts.snap +0 -11
  64. package/src/utils/includeRoute.spec.ts +0 -111
  65. package/src/utils/includeRoute.ts +0 -22
  66. package/src/utils/matchPath.spec.ts +0 -16
  67. package/src/utils/matchPath.ts +0 -5
  68. package/src/utils/readSpec.ts +0 -11
@@ -1,105 +1,49 @@
1
- import Fs from "node:fs";
2
1
  import { join } from "node:path";
3
- import { Env } from "@tsed/core";
4
- import { configuration, constant, inject, injectable, logger, ProviderType } from "@tsed/di";
2
+ import { constant, injectable, ProviderType } from "@tsed/di";
5
3
  import { normalizePath } from "@tsed/normalize-path";
6
- import { application } from "@tsed/platform-http";
7
- import { PlatformRouter, useContextHandler } from "@tsed/platform-router";
4
+ import { OpenAPIBaseModule } from "@tsed/openapi-utils";
5
+ import { useContextHandler } from "@tsed/platform-router";
8
6
  import { ROOT_DIR, SWAGGER_UI_DIST } from "./constants.js";
9
- import { cssMiddleware } from "./middlewares/cssMiddleware.js";
10
7
  import { indexMiddleware } from "./middlewares/indexMiddleware.js";
11
- import { jsMiddleware } from "./middlewares/jsMiddleware.js";
12
- import { redirectMiddleware } from "./middlewares/redirectMiddleware.js";
13
- import { SwaggerService } from "./services/SwaggerService.js";
14
- export class SwaggerModule {
8
+ export class SwaggerModule extends OpenAPIBaseModule {
15
9
  constructor() {
16
- this.swaggerService = inject(SwaggerService);
17
- this.env = constant("env");
18
- this.disableRoutesSummary = constant("logger.disableRoutesSummary");
19
- this.loaded = false;
10
+ super(...arguments);
11
+ this.name = "Swagger";
12
+ this.rootDir = ROOT_DIR;
20
13
  }
21
14
  get settings() {
22
- return constant("swagger", []).filter((o) => !!o);
23
- }
24
- /**
25
- *
26
- */
27
- $onRoutesInit() {
28
- if (this.loaded) {
29
- return;
30
- }
31
- const urls = this.getUrls();
32
- this.settings.forEach((conf) => {
33
- const { path = "/" } = conf;
34
- application().use(path, useContextHandler(redirectMiddleware(path)));
35
- application().use(path, this.createRouter(conf, urls));
15
+ const settings = constant("swagger", []).filter((o) => !!o);
16
+ return settings.map((conf) => {
17
+ return Object.assign({
18
+ disableSpec: false,
19
+ path: "/",
20
+ fileName: "swagger.json",
21
+ cssPath: join(ROOT_DIR, "views/assets/swagger.css"),
22
+ viewPath: join(ROOT_DIR, "views/index.ejs")
23
+ }, conf);
36
24
  });
37
- this.loaded = true;
38
25
  }
39
- $onReady() {
40
- // istanbul ignore next
41
- if (configuration().getBestHost && !this.disableRoutesSummary) {
42
- const host = configuration().getBestHost();
43
- const url = host.toString();
44
- const displayLog = (conf) => {
45
- const { path = "/", fileName = "swagger.json", doc } = conf;
46
- logger().info(`[${doc || "default"}] Swagger JSON is available on ${url}${normalizePath(path, fileName)}`);
47
- logger().info(`[${doc || "default"}] Swagger UI is available on ${url}${path}/`);
48
- };
49
- this.settings.forEach((conf) => {
50
- displayLog(conf);
51
- });
26
+ createRouter(conf) {
27
+ const { viewPath } = conf;
28
+ const router = super.createRouter(conf);
29
+ if (viewPath) {
30
+ router.get("/", useContextHandler(indexMiddleware(viewPath, {
31
+ urls: this.getUrls(),
32
+ ...conf
33
+ })));
34
+ router.statics("/", { root: SWAGGER_UI_DIST });
52
35
  }
53
- this.generateSpecFiles();
54
- }
55
- generateSpecFiles() {
56
- return Promise.all(this.settings.map(async (conf) => {
57
- const { outFile } = conf;
58
- if (this.env === Env.PROD || outFile) {
59
- const spec = await this.swaggerService.getOpenAPISpec(conf);
60
- if (outFile) {
61
- return Fs.writeFile(outFile, JSON.stringify(spec, null, 2), { encoding: "utf8" }, () => { });
62
- }
63
- }
64
- }));
36
+ return router;
65
37
  }
66
38
  getUrls() {
67
39
  return this.settings.reduce((acc, conf) => {
68
- const { path = "/", fileName = "swagger.json", doc, hidden } = conf;
40
+ const { path, fileName, doc, hidden } = conf;
69
41
  if (!hidden) {
70
42
  acc.push({ url: normalizePath(path, fileName), name: doc || path });
71
43
  }
72
44
  return acc;
73
45
  }, []);
74
46
  }
75
- /**
76
- *
77
- * @param conf
78
- * @param urls
79
- */
80
- createRouter(conf, urls) {
81
- const { disableSpec = false, fileName = "swagger.json", cssPath, jsPath, viewPath = join(ROOT_DIR, "../views/index.ejs") } = conf;
82
- const router = new PlatformRouter();
83
- if (!disableSpec) {
84
- router.get(normalizePath("/", fileName), useContextHandler(this.middlewareSwaggerJson(conf)));
85
- }
86
- if (viewPath) {
87
- if (cssPath) {
88
- router.get("/main.css", useContextHandler(cssMiddleware(cssPath)));
89
- }
90
- if (jsPath) {
91
- router.get("/main.js", useContextHandler(jsMiddleware(jsPath)));
92
- }
93
- router.get("/", useContextHandler(indexMiddleware(viewPath, { urls, ...conf })));
94
- router.statics("/", { root: SWAGGER_UI_DIST });
95
- }
96
- return router;
97
- }
98
- middlewareSwaggerJson(conf) {
99
- return async (ctx) => {
100
- ctx.response.status(200).body(await this.swaggerService.getOpenAPISpec(conf));
101
- };
102
- }
103
47
  }
104
48
  injectable(SwaggerModule).type(ProviderType.MODULE);
105
49
  //# sourceMappingURL=SwaggerModule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SwaggerModule.js","sourceRoot":"","sources":["../../src/SwaggerModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SwaggerModule.js","sourceRoot":"","sources":["../../src/SwaggerModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAE/B,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAC,QAAQ,EAAE,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAC,eAAe,EAAC,MAAM,kCAAkC,CAAC;AAEjE,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAApD;;QACW,SAAI,GAAG,SAAS,CAAC;QACjB,YAAO,GAAG,QAAQ,CAAC;IAkD9B,CAAC;IAhDC,IAAI,QAAQ;QACV,MAAM,QAAQ,GAAG,QAAQ,CAAoB,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/E,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,OAAO,MAAM,CAAC,MAAM,CAClB;gBACE,WAAW,EAAE,KAAK;gBAClB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,cAAc;gBACxB,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,0BAA0B,CAAC;gBACnD,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC;aAC5C,EACD,IAAI,CACL,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAES,YAAY,CAAC,IAAqB;QAC1C,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CACR,GAAG,EACH,iBAAiB,CACf,eAAe,CAAC,QAAQ,EAAE;gBACxB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE;gBACpB,GAAG,IAAI;aACR,CAAC,CACH,CACF,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,EAAC,IAAI,EAAE,eAAe,EAAC,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,OAAO;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAU,EAAE,IAAI,EAAE,EAAE;YAC/C,MAAM,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAC,GAAG,IAAI,CAAC;YAE3C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,IAAI,CAAC,EAAC,GAAG,EAAE,aAAa,CAAC,IAAI,EAAE,QAAS,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,EAAC,CAAC,CAAC;YACrE,CAAC;YAED,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;CACF;AAED,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
+ import { join } from "path";
1
2
  import getAbsoluteFSPath from "swagger-ui-dist/absolute-path.js";
2
3
  export const SWAGGER_UI_DIST = getAbsoluteFSPath();
3
- export const ROOT_DIR = import.meta.dirname;
4
+ export const ROOT_DIR = join(import.meta.dirname, "..");
4
5
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,EAAE,CAAC;AACnD,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAC1B,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,EAAE,CAAC;AACnD,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Docs, OpenAPIService as SwaggerService } from "@tsed/openapi-utils";
2
+ //# sourceMappingURL=exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../../src/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,cAAc,IAAI,cAAc,EAAC,MAAM,qBAAqB,CAAC"}
package/lib/esm/index.js CHANGED
@@ -2,16 +2,9 @@
2
2
  * @file Automatically generated by @tsed/barrels.
3
3
  */
4
4
  export * from "./constants.js";
5
- export * from "./decorators/docs.js";
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";
17
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,oBAAoB,CAAC"}
@@ -1,18 +1,22 @@
1
+ import { basename } from "node:path";
2
+ import { context } from "@tsed/di";
3
+ import { join } from "path";
1
4
  /**
2
5
  * @ignore
3
6
  * @param viewPath
4
7
  * @param conf
5
8
  */
6
9
  export function indexMiddleware(viewPath, conf) {
7
- return async (ctx) => {
8
- const { path = "/", options = {}, showExplorer, cssPath, jsPath, urls } = conf;
10
+ return async () => {
11
+ const ctx = context();
12
+ const { path, options = {}, fileName, showExplorer, cssPath, jsPath, urls } = conf;
9
13
  ctx.response.body(await ctx.response.render(viewPath, {
10
14
  spec: {},
11
- url: `${path}/swagger.json`,
15
+ url: `${path}/${fileName}`,
12
16
  urls,
13
17
  showExplorer,
14
- cssPath,
15
- jsPath,
18
+ cssPath: cssPath && join(path, basename(cssPath)),
19
+ jsPath: jsPath && join(path, basename(jsPath)),
16
20
  swaggerOptions: options
17
21
  }));
18
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"indexMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/indexMiddleware.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAwC;IACxF,OAAO,KAAK,EAAE,GAAoB,EAAE,EAAE;QACpC,MAAM,EAAC,IAAI,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC;QAE7E,GAAG,CAAC,QAAQ,CAAC,IAAI,CACf,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;YAClC,IAAI,EAAE,EAAE;YACR,GAAG,EAAE,GAAG,IAAI,eAAe;YAC3B,IAAI;YACJ,YAAY;YACZ,OAAO;YACP,MAAM;YACN,cAAc,EAAE,OAAO;SACxB,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"indexMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/indexMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AAEnC,OAAO,EAAC,OAAO,EAAC,MAAM,UAAU,CAAC;AAEjC,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAI1B;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAwC;IACxF,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,EAAC,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAC,GAAG,IAAI,CAAC;QAEjF,GAAG,CAAC,QAAQ,CAAC,IAAI,CACf,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;YAClC,IAAI,EAAE,EAAE;YACR,GAAG,EAAE,GAAG,IAAI,IAAI,QAAQ,EAAE;YAC1B,IAAI;YACJ,YAAY;YACZ,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjD,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9C,cAAc,EAAE,OAAO;SACxB,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -1,25 +1,15 @@
1
- import { Env } from "@tsed/core";
2
- import { OnReady, OnRoutesInit } from "@tsed/platform-http";
1
+ import { OpenAPIBaseModule } from "@tsed/openapi-utils";
3
2
  import { SwaggerSettings } from "./interfaces/SwaggerSettings.js";
4
- import { SwaggerService } from "./services/SwaggerService.js";
5
- export declare class SwaggerModule implements OnRoutesInit, OnReady {
6
- protected swaggerService: SwaggerService;
7
- protected env: Env | undefined;
8
- protected disableRoutesSummary: boolean | undefined;
9
- private loaded;
10
- get settings(): SwaggerSettings[];
11
- /**
12
- *
13
- */
14
- $onRoutesInit(): void;
15
- $onReady(): void;
16
- generateSpecFiles(): Promise<void[]>;
17
- private getUrls;
18
- /**
19
- *
20
- * @param conf
21
- * @param urls
22
- */
23
- private createRouter;
24
- private middlewareSwaggerJson;
3
+ export declare class SwaggerModule extends OpenAPIBaseModule {
4
+ readonly name = "Swagger";
5
+ readonly rootDir: string;
6
+ get settings(): ({
7
+ disableSpec: boolean;
8
+ path: string;
9
+ fileName: string;
10
+ cssPath: string;
11
+ viewPath: string;
12
+ } & SwaggerSettings)[];
13
+ protected createRouter(conf: SwaggerSettings): import("@tsed/platform-router").PlatformRouter;
14
+ protected getUrls(): any[];
25
15
  }
@@ -0,0 +1 @@
1
+ export { Docs, OpenAPIService as SwaggerService } from "@tsed/openapi-utils";
@@ -2,15 +2,8 @@
2
2
  * @file Automatically generated by @tsed/barrels.
3
3
  */
4
4
  export * from "./constants.js";
5
- export * from "./decorators/docs.js";
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 { OpenSpec2, OpenSpec3, OpenSpecVersions, OS2Versions, OS3Versions } from "@tsed/openspec";
1
+ import type { OpenAPI3Settings, OpenApiSettings, Swagger2Settings } from "@tsed/openapi-utils";
2
2
  export interface SwaggerUIOptions {
3
3
  configUrl?: string;
4
4
  url?: string;
@@ -13,88 +13,12 @@ export interface SwaggerUIOptions {
13
13
  authorize?: any;
14
14
  [key: string]: any;
15
15
  }
16
- export interface SwaggerSettingsBase {
17
- /**
18
- * The url subpath to access to the documentation.
19
- */
20
- path: string;
21
- /**
22
- * Specify the spec version you want to generate.
23
- */
24
- specVersion?: OpenSpecVersions;
25
- /**
26
- * Swagger file name. By default swagger.json
27
- */
28
- fileName?: string;
29
- /**
30
- * Hidden documentation. Use this to hide documentation link in the dropdown.
31
- */
32
- hidden?: string;
33
- /**
34
- * The documentation key used by `@Docs` decorator to create several swagger documentations.
35
- */
36
- doc?: string;
37
- /**
38
- * The path to the CSS file.
39
- */
40
- cssPath?: string;
41
- /**
42
- * The path to the JS file.
43
- */
44
- jsPath?: string;
45
- /**
46
- * The path to the ejs file to create html page.
47
- */
48
- viewPath?: string | false;
16
+ export type SwaggerOS2Settings = Swagger2Settings;
17
+ export type SwaggerOS3Settings = OpenAPI3Settings;
18
+ export type SwaggerSettings = OpenApiSettings & {
19
+ showExplorer?: boolean;
49
20
  /**
50
21
  * SwaggerUI options. See (https://github.com/swagger-api/swagger-ui/blob/HEAD/docs/usage/configuration.md)
51
22
  */
52
23
  options?: SwaggerUIOptions;
53
- /**
54
- * Display the search field in the navbar.
55
- */
56
- showExplorer?: boolean;
57
- /**
58
- * Load the base spec documentation from the specified path.
59
- */
60
- specPath?: string;
61
- /**
62
- * Write the `swagger.json` spec documentation on the specified path.
63
- */
64
- outFile?: string;
65
- /**
66
- * Sort paths by alphabetical order
67
- */
68
- sortPaths?: boolean;
69
- /**
70
- * A function to generate the operationId.
71
- */
72
- operationIdFormatter?: (name: string, propertyKey: string, path: string) => string;
73
- /**
74
- * A pattern to generate the operationId. Format of operationId field (%c: class name, %m: method name).
75
- */
76
- operationIdPattern?: string;
77
- /**
78
- *
79
- */
80
- disableSpec?: boolean;
81
- /**
82
- * Include only controllers whose paths match the pattern list provided.
83
- */
84
- pathPatterns?: string[];
85
- }
86
- export interface SwaggerOS2Settings extends SwaggerSettingsBase {
87
- specVersion?: OS2Versions;
88
- /**
89
- * OpenSpec 2
90
- */
91
- spec?: Partial<OpenSpec2>;
92
- }
93
- export interface SwaggerOS3Settings extends SwaggerSettingsBase {
94
- specVersion?: OS3Versions;
95
- /**
96
- * OpenSpec 3
97
- */
98
- spec?: Partial<OpenSpec3>;
99
- }
100
- export type SwaggerSettings = SwaggerOS2Settings | SwaggerOS3Settings;
24
+ };
@@ -1,4 +1,3 @@
1
- import { PlatformContext } from "@tsed/platform-http";
2
1
  import { SwaggerSettings } from "../interfaces/SwaggerSettings.js";
3
2
  /**
4
3
  * @ignore
@@ -7,4 +6,4 @@ import { SwaggerSettings } from "../interfaces/SwaggerSettings.js";
7
6
  */
8
7
  export declare function indexMiddleware(viewPath: string, conf: SwaggerSettings & {
9
8
  urls: string[];
10
- }): (ctx: PlatformContext) => Promise<void>;
9
+ }): () => Promise<void>;
@@ -0,0 +1,16 @@
1
+ html {
2
+ box-sizing: border-box;
3
+ overflow: -moz-scrollbars-vertical;
4
+ overflow-y: scroll;
5
+ }
6
+
7
+ *,
8
+ *:before,
9
+ *:after {
10
+ box-sizing: inherit;
11
+ }
12
+
13
+ body {
14
+ margin: 0;
15
+ background: #fafafa;
16
+ }
@@ -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="./main.css">
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="./main.js"></script>
86
+ <script src="<%= jsPath %>"></script>
136
87
  <% } %>
137
88
  <script>
138
89
  window.onload = function () {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tsed/swagger",
3
3
  "description": "Swagger package for Ts.ED framework",
4
4
  "type": "module",
5
- "version": "8.1.0",
5
+ "version": "8.3.0",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
@@ -17,43 +17,41 @@
17
17
  },
18
18
  "scripts": {
19
19
  "clean": "rm -rf lib",
20
- "build": "yarn clean && yarn barrels && yarn build:ts && yarn copy:views && monorepo build-hybrid",
20
+ "build": "yarn clean && yarn barrels && yarn build:ts && yarn copy:views",
21
21
  "copy:views": "cp -r ./views ./lib/views",
22
22
  "barrels": "barrels",
23
- "start": "ts-node test/app/index.ts",
23
+ "start": "node --import @swc-node/register/esm-register test/app/index.ts",
24
24
  "test": "vitest run",
25
25
  "build:ts": "tsc --build tsconfig.json",
26
26
  "test:ci": "vitest run --coverage.thresholds.autoUpdate=true"
27
27
  },
28
28
  "dependencies": {
29
- "@tsed/normalize-path": "8.1.0",
30
- "@tsed/openspec": "8.1.0",
31
- "fs-extra": "11.2.0",
32
- "micromatch": "4.0.8",
29
+ "@tsed/normalize-path": "8.3.0",
30
+ "@tsed/openapi-utils": "8.3.0",
31
+ "@tsed/openspec": "8.3.0",
33
32
  "swagger-ui-dist": ">=5.17.14",
34
33
  "tslib": "2.7.0"
35
34
  },
36
35
  "devDependencies": {
37
- "@tsed/barrels": "8.1.0",
38
- "@tsed/core": "8.1.0",
39
- "@tsed/di": "8.1.0",
40
- "@tsed/json-mapper": "8.1.0",
41
- "@tsed/monorepo-utils": "2.3.9",
42
- "@tsed/openspec": "8.1.0",
43
- "@tsed/platform-http": "8.1.0",
44
- "@tsed/schema": "8.1.0",
45
- "@tsed/typescript": "8.1.0",
36
+ "@tsed/barrels": "8.3.0",
37
+ "@tsed/core": "8.3.0",
38
+ "@tsed/di": "8.3.0",
39
+ "@tsed/json-mapper": "8.3.0",
40
+ "@tsed/openapi-utils": "8.3.0",
41
+ "@tsed/openspec": "8.3.0",
42
+ "@tsed/platform-http": "8.3.0",
43
+ "@tsed/schema": "8.3.0",
44
+ "@tsed/typescript": "8.3.0",
46
45
  "@types/swagger-ui-dist": "3.30.5",
47
46
  "eslint": "9.12.0",
48
- "ts-node": "10.9.2",
49
47
  "typescript": "5.4.5",
50
48
  "vitest": "2.1.2"
51
49
  },
52
50
  "peerDependencies": {
53
- "@tsed/platform-http": "8.1.0"
51
+ "@tsed/platform-http": "8.3.0"
54
52
  },
55
53
  "peerDependenciesMeta": {
56
- "@tsed/common": {
54
+ "@tsed/platform-http": {
57
55
  "optional": false
58
56
  }
59
57
  },
package/readme.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p style="text-align: center" align="center">
2
- <a href="https://tsed.dev" target="_blank"><img src="https://tsed.io/tsed-og.png" width="200" alt="Ts.ED logo"/></a>
2
+ <a href="https://tsed.dev" target="_blank"><img src="https://tsed.devtsed-og.png" width="200" alt="Ts.ED logo"/></a>
3
3
  </p>
4
4
 
5
5
  <div align="center">
@@ -16,9 +16,9 @@
16
16
  </div>
17
17
 
18
18
  <div align="center">
19
- <a href="https://tsed.io/">Website</a>
19
+ <a href="https://tsed.dev">Website</a>
20
20
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
21
- <a href="https://tsed.io/getting-started/">Getting started</a>
21
+ <a href="https://tsed.dev/getting-started/">Getting started</a>
22
22
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
23
23
  <a href="https://slack.tsed.io">Slack</a>
24
24
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
@@ -27,7 +27,7 @@
27
27
 
28
28
  <hr />
29
29
 
30
- A package of Ts.ED framework. See website: https://tsed.io/#/tutorials/swagger
30
+ A package of Ts.ED framework. See website: https://tsed.io/tutorials/swagger
31
31
 
32
32
  ## Installation
33
33
 
@@ -128,9 +128,9 @@ export class CalendarCtrl {}
128
128
  #### Model documentation
129
129
 
130
130
  One of the feature of Ts.ED is the model definition to serialize or deserialize a
131
- JSON Object (see [converters section](https://tsed.io/docs/components/converters.html)).
131
+ JSON Object (see [converters section](https://tsed.devdocs/components/converters.html)).
132
132
 
133
- This model can used on a method controller along with [@BodyParams](https://tsed.io/api/common/filters/decorators/BodyParams.html) or other decorators.
133
+ This model can used on a method controller along with [@BodyParams](https://tsed.devapi/common/filters/decorators/BodyParams.html) or other decorators.
134
134
 
135
135
  ```typescript
136
136
  import {JsonProperty, Title, Description, Example} from "@tsed/schema";
@@ -226,11 +226,11 @@ document.addEventListener("swagger.init", (evt) => {
226
226
 
227
227
  ## Documentation
228
228
 
229
- See our documentation https://tsed.io/#/api/index
229
+ See our documentation https://tsed.dev#/api/index
230
230
 
231
231
  ## Contributors
232
232
 
233
- Please read [contributing guidelines here](https://tsed.io/contributing.html).
233
+ Please read [contributing guidelines here](https://tsed.devcontributing.html).
234
234
 
235
235
  <a href="https://github.com/tsedio/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
236
236