@tsed/swagger 7.0.0-alpha.2 → 7.0.0-beta.11
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/jest.config.js +14 -0
- package/lib/cjs/SwaggerModule.js +130 -0
- package/lib/cjs/SwaggerModule.js.map +1 -0
- package/lib/cjs/decorators/docs.js +18 -0
- package/lib/cjs/decorators/docs.js.map +1 -0
- package/lib/cjs/decorators/hidden.js +40 -0
- package/lib/cjs/decorators/hidden.js.map +1 -0
- package/lib/cjs/index.js +19 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/interfaces/SwaggerSettings.js +3 -0
- package/lib/cjs/interfaces/SwaggerSettings.js.map +1 -0
- package/lib/cjs/interfaces/interfaces.js +3 -0
- package/lib/cjs/interfaces/interfaces.js.map +1 -0
- package/lib/cjs/middlewares/cssMiddleware.js +23 -0
- package/lib/cjs/middlewares/cssMiddleware.js.map +1 -0
- package/lib/cjs/middlewares/indexMiddleware.js +24 -0
- package/lib/cjs/middlewares/indexMiddleware.js.map +1 -0
- package/lib/cjs/middlewares/jsMiddleware.js +18 -0
- package/lib/cjs/middlewares/jsMiddleware.js.map +1 -0
- package/lib/cjs/middlewares/redirectMiddleware.js +16 -0
- package/lib/cjs/middlewares/redirectMiddleware.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/services/SwaggerService.js +44 -0
- package/lib/cjs/services/SwaggerService.js.map +1 -0
- package/lib/cjs/utils/includeRoute.js +20 -0
- package/lib/cjs/utils/includeRoute.js.map +1 -0
- package/lib/cjs/utils/matchPath.js +10 -0
- package/lib/cjs/utils/matchPath.js.map +1 -0
- package/lib/esm/SwaggerModule.js +127 -0
- package/lib/esm/SwaggerModule.js.map +1 -0
- package/lib/esm/decorators/docs.js +14 -0
- package/lib/esm/decorators/docs.js.map +1 -0
- package/lib/esm/decorators/hidden.js +36 -0
- package/lib/esm/decorators/hidden.js.map +1 -0
- package/lib/esm/index.js +16 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/interfaces/SwaggerSettings.js +2 -0
- package/lib/esm/interfaces/SwaggerSettings.js.map +1 -0
- package/lib/esm/interfaces/interfaces.js +2 -0
- package/lib/esm/interfaces/interfaces.js.map +1 -0
- package/lib/esm/middlewares/cssMiddleware.js +18 -0
- package/lib/esm/middlewares/cssMiddleware.js.map +1 -0
- package/lib/esm/middlewares/indexMiddleware.js +20 -0
- package/lib/esm/middlewares/indexMiddleware.js.map +1 -0
- package/lib/esm/middlewares/jsMiddleware.js +13 -0
- package/lib/esm/middlewares/jsMiddleware.js.map +1 -0
- package/lib/esm/middlewares/redirectMiddleware.js +12 -0
- package/lib/esm/middlewares/redirectMiddleware.js.map +1 -0
- package/lib/esm/package.json +3 -0
- package/lib/esm/services/SwaggerService.js +41 -0
- package/lib/esm/services/SwaggerService.js.map +1 -0
- package/lib/esm/utils/includeRoute.js +16 -0
- package/lib/esm/utils/includeRoute.js.map +1 -0
- package/lib/esm/utils/matchPath.js +5 -0
- package/lib/esm/utils/matchPath.js.map +1 -0
- package/lib/{SwaggerModule.d.ts → types/SwaggerModule.d.ts} +6 -4
- package/lib/{decorators → types/decorators}/docs.d.ts +0 -0
- package/lib/{decorators → types/decorators}/hidden.d.ts +0 -0
- package/lib/types/index.d.ts +15 -0
- package/lib/{interfaces → types/interfaces}/SwaggerSettings.d.ts +0 -3
- package/lib/{interfaces/index.d.ts → types/interfaces/interfaces.d.ts} +0 -1
- package/lib/{middlewares → types/middlewares}/cssMiddleware.d.ts +0 -0
- package/lib/{middlewares → types/middlewares}/indexMiddleware.d.ts +0 -0
- package/lib/{middlewares → types/middlewares}/jsMiddleware.d.ts +0 -0
- package/lib/{middlewares → types/middlewares}/redirectMiddleware.d.ts +0 -0
- package/lib/types/services/SwaggerService.d.ts +17 -0
- package/lib/{utils → types/utils}/includeRoute.d.ts +1 -1
- package/lib/{utils → types/utils}/matchPath.d.ts +0 -0
- package/lib/views/index.ejs +145 -0
- package/lib/views/index.html +144 -0
- package/package.json +35 -28
- package/readme.md +71 -85
- package/tsconfig.compile.esm.json +24 -0
- package/lib/index.d.ts +0 -5
- package/lib/index.js +0 -629
- package/lib/index.js.map +0 -1
- package/lib/index.modern.js +0 -626
- package/lib/index.modern.js.map +0 -1
- package/lib/services/SwaggerService.d.ts +0 -29
- package/lib/utils/getSpecType.d.ts +0 -12
- package/lib/utils/index.d.ts +0 -7
- package/lib/utils/mapOpenSpec.d.ts +0 -10
- package/lib/utils/mapOpenSpec2.d.ts +0 -9
- package/lib/utils/mapOpenSpec3.d.ts +0 -8
- package/lib/utils/mapOpenSpecInfo.d.ts +0 -6
|
@@ -0,0 +1,14 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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","sourcesContent":["import {StoreMerge} from \"@tsed/core\";\n\n/**\n * Set the type documentation for this class.\n *\n * See [swagger documentation](/tutorials/swagger.html)\n *\n * @decorator\n * @swagger\n * @param docs\n */\nexport function Docs(...docs: string[]) {\n return StoreMerge(\"docs\", docs);\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Hidden as H } from "@tsed/schema";
|
|
2
|
+
/**
|
|
3
|
+
* Disable documentation for the class and his endpoint.
|
|
4
|
+
*
|
|
5
|
+
* ````typescript
|
|
6
|
+
* @Controller('/')
|
|
7
|
+
* export class Ctrl {
|
|
8
|
+
*
|
|
9
|
+
* @Get('/')
|
|
10
|
+
* @Hidden()
|
|
11
|
+
* hiddenRoute(){
|
|
12
|
+
*
|
|
13
|
+
* }
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* @Controller('/')
|
|
17
|
+
* @Hidden()
|
|
18
|
+
* export class Ctrl {
|
|
19
|
+
* @Get('/')
|
|
20
|
+
* hiddenRoute() {
|
|
21
|
+
*
|
|
22
|
+
* }
|
|
23
|
+
* @Get('/2')
|
|
24
|
+
* hiddenRoute2() {
|
|
25
|
+
*
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @decorator
|
|
31
|
+
* @swagger
|
|
32
|
+
*/
|
|
33
|
+
export function Hidden() {
|
|
34
|
+
return H();
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=hidden.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hidden.js","sourceRoot":"","sources":["../../../src/decorators/hidden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,IAAI,CAAC,EAAC,MAAM,cAAc,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,CAAC,EAAE,CAAC;AACb,CAAC","sourcesContent":["import {Hidden as H} from \"@tsed/schema\";\n\n/**\n * Disable documentation for the class and his endpoint.\n *\n * ````typescript\n * @Controller('/')\n * export class Ctrl {\n *\n * @Get('/')\n * @Hidden()\n * hiddenRoute(){\n *\n * }\n * }\n *\n * @Controller('/')\n * @Hidden()\n * export class Ctrl {\n * @Get('/')\n * hiddenRoute() {\n *\n * }\n * @Get('/2')\n * hiddenRoute2() {\n *\n * }\n * }\n * ```\n *\n * @decorator\n * @swagger\n */\nexport function Hidden() {\n return H();\n}\n"]}
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Automatically generated by barrelsby.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./SwaggerModule.js";
|
|
5
|
+
export * from "./decorators/docs.js";
|
|
6
|
+
export * from "./decorators/hidden.js";
|
|
7
|
+
export * from "./interfaces/SwaggerSettings.js";
|
|
8
|
+
export * from "./interfaces/interfaces.js";
|
|
9
|
+
export * from "./middlewares/cssMiddleware.js";
|
|
10
|
+
export * from "./middlewares/indexMiddleware.js";
|
|
11
|
+
export * from "./middlewares/jsMiddleware.js";
|
|
12
|
+
export * from "./middlewares/redirectMiddleware.js";
|
|
13
|
+
export * from "./services/SwaggerService.js";
|
|
14
|
+
export * from "./utils/includeRoute.js";
|
|
15
|
+
export * from "./utils/matchPath.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./SwaggerModule\";\nexport * from \"./decorators/docs\";\nexport * from \"./decorators/hidden\";\nexport * from \"./interfaces/SwaggerSettings\";\nexport * from \"./interfaces/interfaces\";\nexport * from \"./middlewares/cssMiddleware\";\nexport * from \"./middlewares/indexMiddleware\";\nexport * from \"./middlewares/jsMiddleware\";\nexport * from \"./middlewares/redirectMiddleware\";\nexport * from \"./services/SwaggerService\";\nexport * from \"./utils/includeRoute\";\nexport * from \"./utils/matchPath\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwaggerSettings.js","sourceRoot":"","sources":["../../../src/interfaces/SwaggerSettings.ts"],"names":[],"mappings":"","sourcesContent":["import {OpenSpec2, OpenSpec3, OpenSpecVersions, OS2Versions, OS3Versions} from \"@tsed/openspec\";\n\nexport interface SwaggerUIOptions {\n configUrl?: string;\n url?: string;\n urls?: {url: string; name: string; primaryName?: string}[];\n layout?: string;\n validatorUrl?: string;\n oauth?: any;\n authorize?: any;\n\n [key: string]: any;\n}\n\nexport interface SwaggerSettingsBase {\n /**\n * The url subpath to access to the documentation.\n */\n path: string;\n /**\n * Specify the spec version you want to generate.\n */\n specVersion?: OpenSpecVersions;\n /**\n * Swagger file name. By default swagger.json\n */\n fileName?: string;\n /**\n * Hidden documentation. Use this to hide documentation link in the dropdown.\n */\n hidden?: string;\n /**\n * The documentation key used by `@Docs` decorator to create several swagger documentations.\n */\n doc?: string;\n /**\n * The path to the CSS file.\n */\n cssPath?: string;\n /**\n * The path to the JS file.\n */\n jsPath?: string;\n /**\n * The path to the ejs file to create html page.\n */\n viewPath?: string | false;\n /**\n * SwaggerUI options. See (https://github.com/swagger-api/swagger-ui/blob/HEAD/docs/usage/configuration.md)\n */\n options?: SwaggerUIOptions;\n /**\n * Display the search field in the navbar.\n */\n showExplorer?: boolean;\n /**\n * Load the base spec documentation from the specified path.\n */\n specPath?: string;\n /**\n * Write the `swagger.json` spec documentation on the specified path.\n */\n outFile?: string;\n /**\n * A function to generate the operationId.\n */\n operationIdFormatter?: (name: string, propertyKey: string, path: string) => string;\n /**\n * A pattern to generate the operationId. Format of operationId field (%c: class name, %m: method name).\n */\n operationIdPattern?: string;\n /**\n *\n */\n disableSpec?: boolean;\n /**\n * Include only controllers whose paths match the pattern list provided.\n */\n pathPatterns?: string[];\n}\n\nexport interface SwaggerOS2Settings extends SwaggerSettingsBase {\n specVersion?: OS2Versions;\n /**\n * OpenSpec 2\n */\n spec?: Partial<OpenSpec2>;\n}\n\nexport interface SwaggerOS3Settings extends SwaggerSettingsBase {\n specVersion?: OS3Versions;\n /**\n * OpenSpec 3\n */\n spec?: Partial<OpenSpec3>;\n}\n\nexport type SwaggerSettings = SwaggerOS2Settings | SwaggerOS3Settings;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import {SwaggerSettings} from \"./SwaggerSettings\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n swagger: SwaggerSettings[];\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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","sourcesContent":["import {PlatformContext} from \"@tsed/common\";\nimport Fs from \"fs\";\nimport {resolve} from \"path\";\n\n/**\n * @ignore\n * @param path\n */\nexport function cssMiddleware(path: string) {\n return (ctx: PlatformContext) => {\n const content = Fs.readFileSync(resolve(path), {encoding: \"utf8\"});\n ctx.response\n .setHeaders({\n \"Content-Type\": \"text/css\"\n })\n .status(200)\n .body(content);\n };\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ignore
|
|
3
|
+
* @param viewPath
|
|
4
|
+
* @param conf
|
|
5
|
+
*/
|
|
6
|
+
export function indexMiddleware(viewPath, conf) {
|
|
7
|
+
return async (ctx) => {
|
|
8
|
+
const { path = "/", options = {}, showExplorer, cssPath, jsPath, urls } = conf;
|
|
9
|
+
ctx.response.body(await ctx.response.render(viewPath, {
|
|
10
|
+
spec: {},
|
|
11
|
+
url: `${path}/swagger.json`,
|
|
12
|
+
urls,
|
|
13
|
+
showExplorer,
|
|
14
|
+
cssPath,
|
|
15
|
+
jsPath,
|
|
16
|
+
swaggerOptions: options
|
|
17
|
+
}));
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=indexMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/indexMiddleware.ts"],"names":[],"mappings":"AAGA;;;;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","sourcesContent":["import {PlatformContext} from \"@tsed/common\";\nimport {SwaggerSettings} from \"../interfaces/SwaggerSettings\";\n\n/**\n * @ignore\n * @param viewPath\n * @param conf\n */\nexport function indexMiddleware(viewPath: string, conf: SwaggerSettings & {urls: string[]}) {\n return async (ctx: PlatformContext) => {\n const {path = \"/\", options = {}, showExplorer, cssPath, jsPath, urls} = conf;\n\n ctx.response.body(\n await ctx.response.render(viewPath, {\n spec: {},\n url: `${path}/swagger.json`,\n urls,\n showExplorer,\n cssPath,\n jsPath,\n swaggerOptions: options\n })\n );\n };\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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","sourcesContent":["import {PlatformContext} from \"@tsed/common\";\nimport Fs from \"fs\";\nimport {resolve} from \"path\";\n\n/**\n * @ignore\n * @param path\n */\nexport function jsMiddleware(path: string) {\n return (ctx: PlatformContext) => {\n const content = Fs.readFileSync(resolve(path), {encoding: \"utf8\"});\n ctx.response.setHeaders({\"Content-Type\": \"application/javascript\"}).status(200).body(content);\n };\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ignore
|
|
3
|
+
* @param path
|
|
4
|
+
*/
|
|
5
|
+
export function redirectMiddleware(path) {
|
|
6
|
+
return (ctx) => {
|
|
7
|
+
if (ctx.request.url === path && !ctx.request.url.match(/\/$/)) {
|
|
8
|
+
ctx.response.redirect(302, `${path}/`);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=redirectMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YAC7D,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;SACxC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {PlatformContext} from \"@tsed/common\";\n\n/**\n * @ignore\n * @param path\n */\nexport function redirectMiddleware(path: string) {\n return (ctx: PlatformContext) => {\n if (ctx.request.url === path && !ctx.request.url.match(/\\/$/)) {\n ctx.response.redirect(302, `${path}/`);\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var _SwaggerService_specs;
|
|
2
|
+
import { __classPrivateFieldGet, __decorate, __metadata, __param } from "tslib";
|
|
3
|
+
import { Configuration, Injectable, InjectorService, Platform } from "@tsed/common";
|
|
4
|
+
import { generateSpec } from "@tsed/schema";
|
|
5
|
+
import { includeRoute } from "../utils/includeRoute.js";
|
|
6
|
+
let SwaggerService = class SwaggerService {
|
|
7
|
+
constructor(injectorService, platform, configuration) {
|
|
8
|
+
this.injectorService = injectorService;
|
|
9
|
+
this.platform = platform;
|
|
10
|
+
this.configuration = configuration;
|
|
11
|
+
_SwaggerService_specs.set(this, new Map());
|
|
12
|
+
}
|
|
13
|
+
async getOpenAPISpec(conf) {
|
|
14
|
+
if (!__classPrivateFieldGet(this, _SwaggerService_specs, "f").has(conf.path)) {
|
|
15
|
+
const { version = "1.0.0", acceptMimes } = this.configuration;
|
|
16
|
+
const specPath = conf.specPath ? this.configuration.resolve(conf.specPath) : conf.specPath;
|
|
17
|
+
const tokens = this.platform
|
|
18
|
+
.getMountedControllers()
|
|
19
|
+
.filter(({ route, provider }) => includeRoute(route, provider, conf))
|
|
20
|
+
.map(({ route, provider }) => ({ token: provider.token, rootPath: route.replace(provider.path, "") }));
|
|
21
|
+
const spec = await generateSpec({
|
|
22
|
+
tokens,
|
|
23
|
+
...conf,
|
|
24
|
+
specPath,
|
|
25
|
+
version,
|
|
26
|
+
acceptMimes
|
|
27
|
+
});
|
|
28
|
+
__classPrivateFieldGet(this, _SwaggerService_specs, "f").set(conf.path, spec);
|
|
29
|
+
}
|
|
30
|
+
return __classPrivateFieldGet(this, _SwaggerService_specs, "f").get(conf.path);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
_SwaggerService_specs = new WeakMap();
|
|
34
|
+
SwaggerService = __decorate([
|
|
35
|
+
Injectable(),
|
|
36
|
+
__param(2, Configuration()),
|
|
37
|
+
__metadata("design:paramtypes", [InjectorService,
|
|
38
|
+
Platform, Object])
|
|
39
|
+
], SwaggerService);
|
|
40
|
+
export { SwaggerService };
|
|
41
|
+
//# sourceMappingURL=SwaggerService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwaggerService.js","sourceRoot":"","sources":["../../../src/services/SwaggerService.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAC,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAElF,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAGnD,IAAa,cAAc,GAA3B,MAAa,cAAc;IAGzB,YACU,eAAgC,EAChC,QAAkB,EACD,aAA4B;QAF7C,oBAAe,GAAf,eAAe,CAAiB;QAChC,aAAQ,GAAR,QAAQ,CAAU;QACD,kBAAa,GAAb,aAAa,CAAe;QALvD,gCAA6C,IAAI,GAAG,EAAE,EAAC;IAMpD,CAAC;IASG,KAAK,CAAC,cAAc,CAAC,IAAqB;QAC/C,IAAI,CAAC,uBAAA,IAAI,6BAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC/B,MAAM,EAAC,OAAO,GAAG,OAAO,EAAE,WAAW,EAAC,GAAG,IAAI,CAAC,aAAa,CAAC;YAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;YAE3F,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ;iBACzB,qBAAqB,EAAE;iBACvB,MAAM,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;iBAClE,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;YAErG,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;gBAC9B,MAAM;gBACN,GAAG,IAAI;gBACP,QAAQ;gBACR,OAAO;gBACP,WAAW;aACZ,CAAC,CAAC;YAEH,uBAAA,IAAI,6BAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SAClC;QAED,OAAO,uBAAA,IAAI,6BAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF,CAAA;;AAvCY,cAAc;IAD1B,UAAU,EAAE;IAOR,WAAA,aAAa,EAAE,CAAA;qCAFS,eAAe;QACtB,QAAQ;GALjB,cAAc,CAuC1B;SAvCY,cAAc","sourcesContent":["import {Configuration, Injectable, InjectorService, Platform} from \"@tsed/common\";\nimport {OpenSpec2, OpenSpec3} from \"@tsed/openspec\";\nimport {generateSpec} from \"@tsed/schema\";\nimport {SwaggerOS2Settings, SwaggerOS3Settings, SwaggerSettings} from \"../interfaces/SwaggerSettings\";\nimport {includeRoute} from \"../utils/includeRoute\";\n\n@Injectable()\nexport class SwaggerService {\n #specs: Map<string, OpenSpec3 | OpenSpec2> = new Map();\n\n constructor(\n private injectorService: InjectorService,\n private platform: Platform,\n @Configuration() private configuration: Configuration\n ) {}\n\n /**\n * Generate Spec for the given configuration\n * @returns {Spec}\n */\n public async getOpenAPISpec(conf: SwaggerOS3Settings): Promise<OpenSpec3>;\n public async getOpenAPISpec(conf: SwaggerOS2Settings): Promise<OpenSpec2>;\n public async getOpenAPISpec(conf: SwaggerSettings): Promise<OpenSpec2>;\n public async getOpenAPISpec(conf: SwaggerSettings) {\n if (!this.#specs.has(conf.path)) {\n const {version = \"1.0.0\", acceptMimes} = this.configuration;\n const specPath = conf.specPath ? this.configuration.resolve(conf.specPath) : conf.specPath;\n\n const tokens = this.platform\n .getMountedControllers()\n .filter(({route, provider}) => includeRoute(route, provider, conf))\n .map(({route, provider}) => ({token: provider.token, rootPath: route.replace(provider.path, \"\")}));\n\n const spec = await generateSpec({\n tokens,\n ...conf,\n specPath,\n version,\n acceptMimes\n });\n\n this.#specs.set(conf.path, spec);\n }\n\n return this.#specs.get(conf.path);\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"includeRoute.js","sourceRoot":"","sources":["../../../src/utils/includeRoute.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAGtC,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAA4B,EAAE,IAAqB;IAC7F,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;QACV,OAAO,KAAK,CAAC;KACd;IAED,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE;QACzB,OAAO,IAAI,CAAC;KACb;IAED,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import {ControllerProvider} from \"@tsed/common\";\nimport {matchPath} from \"./matchPath\";\nimport {SwaggerSettings} from \"../interfaces/SwaggerSettings\";\n\nexport function includeRoute(route: string, provider: ControllerProvider, conf: SwaggerSettings): boolean {\n const hidden = provider.store.get(\"hidden\");\n const docs = provider.store.get(\"docs\") || [];\n const {doc, pathPatterns} = conf;\n const inDoc = doc && docs.indexOf(doc) > -1;\n const pathPatternMatch = pathPatterns && matchPath(route, pathPatterns);\n\n if (hidden) {\n return false;\n }\n\n if (!doc && !pathPatterns) {\n return true;\n }\n\n return !!(inDoc || pathPatternMatch);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchPath.js","sourceRoot":"","sources":["../../../src/utils/matchPath.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,QAAmB;IACzD,OAAO,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC","sourcesContent":["import micromatch from \"micromatch\";\n\nexport function matchPath(path: string, patterns?: string[]) {\n return patterns && patterns.length ? micromatch.isMatch(path, patterns) : true;\n}\n"]}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SwaggerSettings } from "./interfaces";
|
|
1
|
+
import { OnRoutesInit, Configuration, InjectorService, OnReady, PlatformApplication } from "@tsed/common";
|
|
2
|
+
import { SwaggerSettings } from "./interfaces/SwaggerSettings";
|
|
3
3
|
import { SwaggerService } from "./services/SwaggerService";
|
|
4
|
+
import { Env } from "@tsed/core";
|
|
4
5
|
/**
|
|
5
6
|
* @ignore
|
|
6
7
|
*/
|
|
7
|
-
export declare class SwaggerModule implements
|
|
8
|
+
export declare class SwaggerModule implements OnRoutesInit, OnReady {
|
|
8
9
|
injector: InjectorService;
|
|
9
10
|
app: PlatformApplication;
|
|
10
11
|
configuration: Configuration;
|
|
11
12
|
swaggerService: SwaggerService;
|
|
13
|
+
env: Env;
|
|
12
14
|
private loaded;
|
|
13
15
|
get settings(): SwaggerSettings[];
|
|
14
16
|
/**
|
|
15
17
|
*
|
|
16
18
|
*/
|
|
17
|
-
$
|
|
19
|
+
$onRoutesInit(): void;
|
|
18
20
|
$onReady(): void;
|
|
19
21
|
generateSpecFiles(): Promise<void[]>;
|
|
20
22
|
private getUrls;
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Automatically generated by barrelsby.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./SwaggerModule";
|
|
5
|
+
export * from "./decorators/docs";
|
|
6
|
+
export * from "./decorators/hidden";
|
|
7
|
+
export * from "./interfaces/SwaggerSettings";
|
|
8
|
+
export * from "./interfaces/interfaces";
|
|
9
|
+
export * from "./middlewares/cssMiddleware";
|
|
10
|
+
export * from "./middlewares/indexMiddleware";
|
|
11
|
+
export * from "./middlewares/jsMiddleware";
|
|
12
|
+
export * from "./middlewares/redirectMiddleware";
|
|
13
|
+
export * from "./services/SwaggerService";
|
|
14
|
+
export * from "./utils/includeRoute";
|
|
15
|
+
export * from "./utils/matchPath";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Configuration, InjectorService, Platform } from "@tsed/common";
|
|
2
|
+
import { OpenSpec2, OpenSpec3 } from "@tsed/openspec";
|
|
3
|
+
import { SwaggerOS2Settings, SwaggerOS3Settings, SwaggerSettings } from "../interfaces/SwaggerSettings";
|
|
4
|
+
export declare class SwaggerService {
|
|
5
|
+
#private;
|
|
6
|
+
private injectorService;
|
|
7
|
+
private platform;
|
|
8
|
+
private configuration;
|
|
9
|
+
constructor(injectorService: InjectorService, platform: Platform, configuration: Configuration);
|
|
10
|
+
/**
|
|
11
|
+
* Generate Spec for the given configuration
|
|
12
|
+
* @returns {Spec}
|
|
13
|
+
*/
|
|
14
|
+
getOpenAPISpec(conf: SwaggerOS3Settings): Promise<OpenSpec3>;
|
|
15
|
+
getOpenAPISpec(conf: SwaggerOS2Settings): Promise<OpenSpec2>;
|
|
16
|
+
getOpenAPISpec(conf: SwaggerSettings): Promise<OpenSpec2>;
|
|
17
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ControllerProvider } from "@tsed/common";
|
|
2
|
-
import { SwaggerSettings } from "
|
|
2
|
+
import { SwaggerSettings } from "../interfaces/SwaggerSettings";
|
|
3
3
|
export declare function includeRoute(route: string, provider: ControllerProvider, conf: SwaggerSettings): boolean;
|
|
File without changes
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Swagger UI</title>
|
|
6
|
+
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"
|
|
7
|
+
rel="stylesheet">
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
|
|
9
|
+
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32"/>
|
|
10
|
+
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16"/>
|
|
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
|
+
<% if (!showExplorer) { %>
|
|
30
|
+
.swagger-ui .topbar .download-url-wrapper {
|
|
31
|
+
display: none
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
<% } %>
|
|
35
|
+
</style>
|
|
36
|
+
<% if (cssPath) { %>
|
|
37
|
+
<link rel="stylesheet" type="text/css" href="./main.css">
|
|
38
|
+
<% } %>
|
|
39
|
+
</head>
|
|
40
|
+
|
|
41
|
+
<body>
|
|
42
|
+
<div id="swagger-ui"></div>
|
|
43
|
+
|
|
44
|
+
<script src="./swagger-ui-bundle.js"></script>
|
|
45
|
+
<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
|
+
|
|
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
|
+
<script>
|
|
78
|
+
const origin = window.location.origin;
|
|
79
|
+
const initialOptions = <%- JSON.stringify(swaggerOptions) %>;
|
|
80
|
+
const currentUrl = origin + "<%- url %>";
|
|
81
|
+
const urls = <%- JSON.stringify(urls) %>
|
|
82
|
+
.map(function (o) {
|
|
83
|
+
if (!o.url.match(/^https?:/)) {
|
|
84
|
+
const url = origin + o.url;
|
|
85
|
+
return {
|
|
86
|
+
name: o.name,
|
|
87
|
+
url: url,
|
|
88
|
+
selected: url === currentUrl
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return o;
|
|
92
|
+
})
|
|
93
|
+
.sort(function (a, b) {
|
|
94
|
+
return a.selected ? -1 : 1
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const SwaggerUIBuilder = {
|
|
98
|
+
config: Object.assign({
|
|
99
|
+
urls: urls,
|
|
100
|
+
dom_id: '#swagger-ui',
|
|
101
|
+
deepLinking: true,
|
|
102
|
+
presets: [
|
|
103
|
+
SwaggerUIBundle.presets.apis,
|
|
104
|
+
SwaggerUIStandalonePreset
|
|
105
|
+
],
|
|
106
|
+
plugins: [
|
|
107
|
+
SwaggerUIBundle.plugins.DownloadUrl
|
|
108
|
+
],
|
|
109
|
+
layout: "StandaloneLayout",
|
|
110
|
+
oauth2RedirectUrl: currentUrl.replace('swagger.json', 'oauth2-redirect.html'),
|
|
111
|
+
validatorUrl: origin.match('0.0.0.0') || origin.match('localhost') ? null : undefined
|
|
112
|
+
}, initialOptions),
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
*/
|
|
116
|
+
init: function () {
|
|
117
|
+
this.ui = SwaggerUIBundle(this.config);
|
|
118
|
+
|
|
119
|
+
if (this.config.oauth) {
|
|
120
|
+
this.ui.initOAuth(this.config.oauth);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (this.config.authorize) {
|
|
124
|
+
this.ui.authActions.authorize(this.config.authorize);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
window.ui = this.ui;
|
|
128
|
+
|
|
129
|
+
const event = new Event('swagger.init');
|
|
130
|
+
document.dispatchEvent(event);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
</script>
|
|
135
|
+
<% if (jsPath) { %>
|
|
136
|
+
<script src="./main.js"></script>
|
|
137
|
+
<% } %>
|
|
138
|
+
<script>
|
|
139
|
+
window.onload = function () {
|
|
140
|
+
SwaggerUIBuilder.init();
|
|
141
|
+
}
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
</body>
|
|
145
|
+
</html>
|