├── .editorconfig
├── .gitignore
├── .npmignore
├── .prettierrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── config.template.json
├── gulpfile.js
├── lib
└── swagger-express-ts-lib
│ ├── package.json
│ └── src
│ ├── api-model-property.decorator.ts
│ ├── api-model.decorator.ts
│ ├── api-operation-delete.decorator.ts
│ ├── api-operation-get.decorator.ts
│ ├── api-operation-patch.decorator.ts
│ ├── api-operation-post.decorator.ts
│ ├── api-operation-put.decorator.ts
│ ├── api-path.decorator.ts
│ ├── express.configurator.ts
│ ├── i-api-operation-args.base.ts
│ ├── i-swagger.ts
│ ├── index.ts
│ ├── swagger-definition.constant.spec.ts
│ ├── swagger-definition.constant.ts
│ ├── swagger.builder.ts
│ ├── swagger.service.spec.ts
│ └── swagger.service.ts
├── package-lock.json
├── package.json
├── src
├── cars
│ ├── car.controller.spec.ts
│ ├── car.controller.ts
│ ├── car.model.ts
│ ├── carbulk.controller.ts
│ ├── cars.controller.spec.ts
│ ├── cars.controller.ts
│ ├── cars.service.spec.ts
│ ├── cars.service.ts
│ └── wheel.model.ts
├── constructors
│ └── constructor.model.ts
└── index.ts
├── swagger
└── index.html
├── test
└── mocha.opts
├── tsconfig.dev.lib.json
├── tsconfig.json
├── tsconfig.lib.json
├── tslint.json
├── wiki
├── README.md
├── api-model-property.decorator.md
├── api-model.decorator.md
├── api-operation-delete.decorator.md
├── api-operation-get.decorator.md
├── api-operation-patch.decorator.md
├── api-operation-post.decorator.md
├── api-operation-put.decorator.md
├── api-path.decorator.md
├── configuration.md
├── i-api-body-operation-args-base-parameter.md
├── i-api-operation-args-base-parameter.md
├── i-api-operation-args-base-parameters.md
├── i-api-operation-args-base-response.md
├── i-api-property-body-operation-args-base-parameter.md
├── i-swagger-build-definition-model-property.md
├── i-swagger-build-definition-model.md
├── i-swagger-build-definition.md
├── i-swagger-contact.md
├── i-swagger-external-docs.md
├── i-swagger-info.md
├── i-swagger-license.md
├── i-swagger-security-definition.md
├── img
│ ├── logo.png
│ └── swagger-ui.png
├── installation.md
└── swagger-definition-constant.md
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # http://editorconfig.org/
4 |
5 | root = true
6 |
7 | [*]
8 | charset = utf-8
9 | end_of_line = lf
10 |
11 | [*.{js,ts}]
12 | indent_size = 2
13 | indent_style = space
14 | insert_final_newline = true
15 | trim_trailing_whitespace = true
16 |
17 | [*.md]
18 | trim_trailing_whitespace = false
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | built/
61 | dist/
62 | reports/
63 | config.json
64 | src/**/*.js
65 | example/**/*.js
66 | .idea
67 | .vscode
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | swagger
3 | lib
4 | node_modules
5 | test
6 | wiki
7 | config.*
8 | docs
9 | examples
10 | test
11 | lib-cov
12 | .editorconfig
13 | .jshintignore
14 | .jshintrc
15 | .travis.yml
16 | .prettierrc
17 | tsconfig.*
18 | tslint.*
19 | lcov.info
20 | logo.svg
21 | CHANGELOG.MD
22 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": true
6 | }
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | before_install:
5 | - npm i -g npm@latest
6 | - npm i
7 | install:
8 | - npm run tslint
9 | - npm run build
10 | script:
11 | - npm run test
12 | after_success:
13 | - npm run test:coverage
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # [1.0.1](2018-12-4)
4 |
5 | ## Features
6 |
7 | ### example
8 |
9 | Example:
10 |
11 | ```ts
12 | ...
13 | @ApiModelProperty({
14 | description: 'Id of car',
15 | required: true,
16 | example: ['123456789', '12345'],
17 | })
18 | id: string;
19 | ...
20 | }
21 | ```
22 |
23 | or
24 |
25 | ```ts
26 | ...
27 | app.use(
28 | swagger.express({
29 | ...
30 | models: {
31 | ApiError: {
32 | properties: {
33 | code: {
34 | type:
35 | SwaggerDefinitionConstant.Model.Property
36 | .Type.STRING,
37 | example: ['400'],
38 | },
39 | message: {
40 | type:
41 | SwaggerDefinitionConstant.Model.Property
42 | .Type.STRING,
43 | example: ['Name of car is required.'],
44 | },
45 | },
46 | },
47 | },
48 | ...
49 | },
50 | })
51 | );
52 | ...
53 | ```
54 |
55 | ### body in parameter
56 |
57 | Example:
58 |
59 | ```ts
60 | ...
61 | @ApiOperationPost({
62 | ...
63 | parameters: {
64 | body: {
65 | description: 'New car',
66 | required: true,
67 | model: 'Car',
68 | },
69 | },
70 | ...
71 | })
72 | ...
73 | ```
74 |
75 | or
76 |
77 | ```ts
78 | ...
79 | @ApiOperationPost({
80 | ...
81 | parameters: {
82 | body: {
83 | required: true,
84 | properties: {
85 | name: { type: SwaggerDefinitionConstant.Parameter.Type.STRING, required: true}
86 | }
87 | },
88 | },
89 | ...
90 | })
91 | ...
92 | ```
93 |
94 |
95 |
96 | # [1.0.0](2018-06-10)
97 |
98 | ## Features
99 |
100 | ### itemType
101 |
102 | Example:
103 |
104 | ```ts
105 | ...
106 | @ApiModelProperty({
107 | description: "Name of author",
108 | required: true,
109 | itemType: SwaggerDefinitionConstant.Model.Property.Type.STRING
110 | })
111 | name: string[];
112 | ...
113 | ```
114 |
115 | or
116 |
117 | ```ts
118 | ...
119 | app.use(
120 | swagger.express({
121 | definition: {
122 | ...
123 | models: {
124 | Author: {
125 | name: {
126 | description: "Name of author",
127 | type: SwaggerDefinitionConstant.Model.Property.Type.ARRAY,
128 | itemType:
129 | SwaggerDefinitionConstant.Model.Property.ItemType.STRING,
130 | required: true
131 | }
132 | }
133 | }
134 | }
135 | ...
136 | }
137 | })
138 | );
139 | ...
140 | ```
141 |
142 |
143 |
144 | # [1.0.0-rc.4](2018-05-18)
145 |
146 | ## Features
147 |
148 | ### Add global responses
149 |
150 | Example:
151 |
152 | ```ts
153 | swagger.express({
154 | definition: {
155 | ...
156 | responses: {
157 | 500: {}
158 | },
159 | ...
160 | }
161 | })
162 | ```
163 |
164 | ## Fixes
165 |
166 | ### Fix ApiModel when arg "name" and class name are equal.
167 |
168 |
169 |
170 | # [1.0.0-rc.3](2018-04-30)
171 |
172 | ## Fixes
173 |
174 | ### Merge models and path
175 |
176 |
177 |
178 | # [1.0.0-rc.2](2018-04-26)
179 |
180 | ## Features
181 |
182 | ### Name
183 |
184 | Merge name when several controllers that point to the same name .
185 |
186 | Example:
187 |
188 | ```ts
189 | @ApiPath({
190 | path: "/versions",
191 | name: "Version"
192 | })
193 | ...
194 | export class VersionsController implements interfaces.Controller {
195 | ...
196 | }
197 |
198 | @ApiPath({
199 | path: "/versions/:id",
200 | name: "Version"
201 | })
202 | ...
203 | export class VersionController implements interfaces.Controller {
204 | ...
205 | }
206 | ```
207 |
208 |
209 |
210 | # [1.0.0-rc.1](2018-04-08)
211 |
212 | ## Features
213 |
214 | ### Model
215 |
216 | #### Configuration
217 |
218 | example:
219 |
220 | ```ts
221 | definition : {
222 | ...
223 | models : {
224 | Version : {
225 | properties : {
226 | id : {
227 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING,
228 | required : true
229 | },
230 | name : {
231 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING,
232 | required : true
233 | },
234 | description : {
235 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING
236 | },
237 | version : {
238 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING
239 | },
240 | author: {
241 | model: "Author"
242 | }
243 | }
244 | },
245 | Author: {
246 | properties: {
247 | id: {
248 | type: SwaggerDefinitionConstant.Model.Property.Type.STRING,
249 | required : true
250 | },
251 | name : {
252 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING,
253 | required : true
254 | },
255 | }
256 | }
257 | },
258 | ...
259 | }
260 | ```
261 |
262 | or
263 |
264 | ```ts
265 | @ApiModel({
266 | description: 'Version description',
267 | name: 'Version',
268 | })
269 | export class VersionModel {
270 | @ApiModelProperty({
271 | description: 'Id of version',
272 | required: true,
273 | })
274 | id: number;
275 |
276 | @ApiModelProperty({
277 | description: '',
278 | required: true,
279 | })
280 | name: string;
281 |
282 | @ApiModelProperty({
283 | description: 'Description of version',
284 | required: true,
285 | })
286 | description: string;
287 |
288 | @ApiModelProperty({
289 | description: 'Author of version',
290 | model: 'Author',
291 | })
292 | author: AuthorModel;
293 | }
294 | ```
295 |
296 | #### Controller
297 |
298 | example:
299 |
300 | ```ts
301 | @ApiOperationGet( {
302 | ...
303 | responses : {
304 | 200 : { description : "Success" , type : SwaggerDefinitionConstant.Response.Type.ARRAY , model : "Version" }
305 | } ,
306 | ...
307 | } )
308 | ```
309 |
310 |
311 |
312 | # [1.0.0-beta.1](2018-03-02)
313 |
314 | ## Features
315 |
316 | ### Authentication
317 |
318 | #### Configuration
319 |
320 | example:
321 |
322 | ```ts
323 | app.use( swagger.express(
324 | {
325 | definition : {
326 | ...
327 | securityDefinitions : {
328 | basicAuth : {
329 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
330 | },
331 | apiKeyHeader : {
332 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
333 | in: SwaggerDefinitionConstant.Security.In.HEADER,
334 | name: "apiHeader"
335 | }
336 | }
337 | }
338 | }
339 | ) );
340 | ```
341 |
342 | #### Basic Authentication
343 |
344 | Example:
345 |
346 | ```ts
347 | ...
348 | @ApiOperationGet( {
349 | ...
350 | security : {
351 | basicAuth : []
352 | }
353 | } )
354 | ...
355 | ```
356 |
357 | #### API Keys
358 |
359 | Example:
360 |
361 | ```ts
362 | ...
363 | @ApiOperationGet( {
364 | ...
365 | security : {
366 | apiKeyHeader : []
367 | }
368 | } )
369 | ...
370 | ```
371 |
372 | ### Operations as deprecated
373 |
374 | Example in path:
375 |
376 | ```ts
377 | ...
378 | @ApiPath( {
379 | ...
380 | deprecated: true
381 | } )
382 | ...
383 | ```
384 |
385 | Example in operation:
386 |
387 | ```ts
388 | ...
389 | @ApiOperationGet( {
390 | ...
391 | deprecated: true
392 | } )
393 | ...
394 | ```
395 |
396 |
397 |
398 | # [1.0.0-alpha.5](2018-02-18)
399 |
400 | ## Features
401 |
402 | ### externalDocs
403 |
404 | Example:
405 |
406 | ```ts
407 | app.use(
408 | swagger.express({
409 | definition: {
410 | info: {
411 | title: 'My api',
412 | version: '1.0',
413 | },
414 | models: {
415 | Version: {
416 | properties: {
417 | id: {
418 | type:
419 | SwaggerDefinitionConstant.Model.Property.Type
420 | .STRING,
421 | required: true,
422 | },
423 | name: {
424 | type:
425 | SwaggerDefinitionConstant.Model.Property.Type
426 | .STRING,
427 | required: true,
428 | },
429 | description: {
430 | type:
431 | SwaggerDefinitionConstant.Model.Property.Type
432 | .STRING,
433 | },
434 | version: {
435 | type:
436 | SwaggerDefinitionConstant.Model.Property.Type
437 | .STRING,
438 | },
439 | },
440 | },
441 | },
442 | externalDocs: {
443 | url: 'My url',
444 | },
445 | },
446 | })
447 | );
448 | ```
449 |
450 |
451 |
452 | # [1.0.0-alpha.4](2018-01-19)
453 |
454 | Add keywords for npm.
455 |
456 |
457 |
458 | # [1.0.0-alpha.3](2018-01-18)
459 |
460 | Complete informations.
461 |
462 |
463 |
464 | # [1.0.0-alpha.2](2018-01-18)
465 |
466 | Complete informations.
467 |
468 |
469 |
470 | # [1.0.0-alpha.1](2018-01-18)
471 |
472 | Complete informations.
473 |
474 |
475 |
476 | # [1.0.0-alpha.0](2018-01-18)
477 |
478 | ## Features
479 |
480 | ### .express(options: ISwaggerExpressOptions)
481 |
482 | Example:
483 |
484 | ```ts
485 | app.use(
486 | swagger.express({
487 | definition: {
488 | setInfo: {
489 | title: 'My api',
490 | version: '1.0',
491 | },
492 | models: {
493 | Version: {
494 | properties: {
495 | id: {
496 | type:
497 | SwaggerDefinitionConstant.Definition.Property
498 | .Type.STRING,
499 | required: true,
500 | },
501 | name: {
502 | type:
503 | SwaggerDefinitionConstant.Definition.Property
504 | .Type.STRING,
505 | required: true,
506 | },
507 | description: {
508 | type:
509 | SwaggerDefinitionConstant.Definition.Property
510 | .Type.STRING,
511 | },
512 | version: {
513 | type:
514 | SwaggerDefinitionConstant.Definition.Property
515 | .Type.STRING,
516 | },
517 | },
518 | },
519 | },
520 | },
521 | })
522 | );
523 | ```
524 |
525 | ### @ApiPath(args: IApiPathArgs)
526 |
527 | Example:
528 |
529 | ```ts
530 | import { injectable } from 'inversify';
531 | import 'reflect-metadata';
532 | import { ApiPath } from 'swagger-express-ts';
533 | import { controller } from 'inversify-express-utils';
534 |
535 | @ApiPath({
536 | path: '/version',
537 | name: 'Version',
538 | })
539 | @controller('/version')
540 | @injectable()
541 | export class VersionController implements interfaces.Controller {
542 | public static TARGET_NAME: string = 'VersionController';
543 | }
544 | ```
545 |
546 | ### @ApiOperationDelete(args: IApiOperationDeleteArgs)
547 |
548 | Example:
549 |
550 | ```ts
551 | import * as express from 'express';
552 | import { injectable } from 'inversify';
553 | import {
554 | controller,
555 | interfaces,
556 | requestParam,
557 | httpDelete,
558 | } from 'inversify-express-utils';
559 | import {
560 | ApiPath,
561 | ApiOperationDelete,
562 | SwaggerDefinitionConstant,
563 | } from 'swagger-express-ts';
564 | import 'reflect-metadata';
565 |
566 | @ApiPath({
567 | path: '/versions',
568 | name: 'Version',
569 | })
570 | @controller('/versions')
571 | @injectable()
572 | export class VersionController implements interfaces.Controller {
573 | public static TARGET_NAME: string = 'VersionController';
574 | private data: [any] = [
575 | {
576 | id: '1',
577 | name: 'Version 1',
578 | description: 'Description Version 1',
579 | version: '1.0.0',
580 | },
581 | {
582 | id: '2',
583 | name: 'Version 2',
584 | description: 'Description Version 2',
585 | version: '2.0.0',
586 | },
587 | ];
588 |
589 | @ApiOperationDelete({
590 | path: '/{id}',
591 | parameters: {
592 | path: {
593 | id: {
594 | description: 'Id of version',
595 | type: SwaggerDefinitionConstant.Parameter.Type.STRING,
596 | required: true,
597 | },
598 | },
599 | },
600 | responses: {
601 | 200: { description: 'Success' },
602 | },
603 | })
604 | @httpDelete('/:id')
605 | public deleteVersion(
606 | @requestParam('id') id: string,
607 | request: express.Request,
608 | response: express.Response,
609 | next: express.NextFunction
610 | ): void {
611 | this.data.forEach((version: any, index: number) => {
612 | if (version.id === id) {
613 | this.data.splice(index, 1);
614 | return response.status(200).end();
615 | }
616 | });
617 | response.status(404).end();
618 | }
619 | }
620 | ```
621 |
622 | ### @ApiOperationGet(args: IApiOperationGetArgs)
623 |
624 | Decorate method for getting a resource in your controller.
625 |
626 | Example:
627 |
628 | ```ts
629 | import * as express from 'express';
630 | import { injectable } from 'inversify';
631 | import {
632 | controller,
633 | interfaces,
634 | requestParam,
635 | httpGet,
636 | } from 'inversify-express-utils';
637 | import {
638 | ApiPath,
639 | ApiOperationGet,
640 | SwaggerDefinitionConstant,
641 | } from 'swagger-express-ts';
642 | import 'reflect-metadata';
643 |
644 | @ApiPath({
645 | path: '/versions',
646 | name: 'Version',
647 | })
648 | @controller('/versions')
649 | @injectable()
650 | export class VersionController implements interfaces.Controller {
651 | public static TARGET_NAME: string = 'VersionController';
652 | private data: [any] = [
653 | {
654 | id: '1',
655 | name: 'Version 1',
656 | description: 'Description Version 1',
657 | version: '1.0.0',
658 | },
659 | {
660 | id: '2',
661 | name: 'Version 2',
662 | description: 'Description Version 2',
663 | version: '2.0.0',
664 | },
665 | ];
666 |
667 | @ApiOperationGet({
668 | description: 'Get version object',
669 | summary: 'Get version',
670 | responses: {
671 | 200: { description: 'Success', isArray: true, model: 'Version' },
672 | },
673 | })
674 | @httpGet('/')
675 | public getVersions(
676 | request: express.Request,
677 | response: express.Response,
678 | next: express.NextFunction
679 | ): void {
680 | response.json(this.data);
681 | }
682 | }
683 | ```
684 |
685 | ### @ApiOperationPatch(args: IApiOperationPatchArgs)
686 |
687 | Decorate method for updating a field of resource in your controller.
688 |
689 | Example:
690 |
691 | ```ts
692 | import * as express from 'express';
693 | import { injectable } from 'inversify';
694 | import {
695 | controller,
696 | interfaces,
697 | requestParam,
698 | httpPatch,
699 | } from 'inversify-express-utils';
700 | import {
701 | ApiPath,
702 | ApiOperationPatch,
703 | SwaggerDefinitionConstant,
704 | } from 'swagger-express-ts';
705 | import 'reflect-metadata';
706 |
707 | @ApiPath({
708 | path: '/versions',
709 | name: 'Version',
710 | })
711 | @controller('/versions')
712 | @injectable()
713 | export class VersionController implements interfaces.Controller {
714 | public static TARGET_NAME: string = 'VersionController';
715 | private data: [any] = [
716 | {
717 | id: '1',
718 | name: 'Version 1',
719 | description: 'Description Version 1',
720 | version: '1.0.0',
721 | },
722 | {
723 | id: '2',
724 | name: 'Version 2',
725 | description: 'Description Version 2',
726 | version: '2.0.0',
727 | },
728 | ];
729 |
730 | @ApiOperationPatch({
731 | path: '/{id}/description',
732 | description: 'Patch description in version object',
733 | summary: 'Patch description in version',
734 | parameters: {
735 | path: {
736 | id: {
737 | description: 'Id of version',
738 | type: SwaggerDefinitionConstant.Parameter.Type.STRING,
739 | required: true,
740 | },
741 | },
742 | body: {
743 | description: 'New version',
744 | required: true,
745 | model: 'Version',
746 | },
747 | },
748 | responses: {
749 | 200: { description: 'Success' },
750 | 400: { description: 'Parameters fail' },
751 | 404: { description: 'Version not found' },
752 | },
753 | })
754 | @httpPatch('/:id/description')
755 | public patchVersionDescription(
756 | @requestParam('id') id: string,
757 | request: express.Request,
758 | response: express.Response,
759 | next: express.NextFunction
760 | ): void {
761 | if (!request.body) {
762 | return response.status(400).end();
763 | }
764 | this.data.forEach((version: any) => {
765 | if (version.id === id) {
766 | version.description = request.body.description;
767 | return response.json(version);
768 | }
769 | });
770 | response.status(404).end();
771 | }
772 | }
773 | ```
774 |
775 | ### @ApiOperationPost(args: IApiOperationPostArgs)
776 |
777 | Decorate method for create a resource in your controller.
778 |
779 | Example:
780 |
781 | ```ts
782 | import * as express from 'express';
783 | import { injectable } from 'inversify';
784 | import {
785 | controller,
786 | interfaces,
787 | requestParam,
788 | httpPost,
789 | } from 'inversify-express-utils';
790 | import {
791 | ApiPath,
792 | ApiOperationPost,
793 | SwaggerDefinitionConstant,
794 | } from 'swagger-express-ts';
795 | import 'reflect-metadata';
796 |
797 | @ApiPath({
798 | path: '/versions',
799 | name: 'Version',
800 | })
801 | @controller('/versions')
802 | @injectable()
803 | export class VersionController implements interfaces.Controller {
804 | public static TARGET_NAME: string = 'VersionController';
805 | private data: [any] = [
806 | {
807 | id: '1',
808 | name: 'Version 1',
809 | description: 'Description Version 1',
810 | version: '1.0.0',
811 | },
812 | {
813 | id: '2',
814 | name: 'Version 2',
815 | description: 'Description Version 2',
816 | version: '2.0.0',
817 | },
818 | ];
819 |
820 | @ApiOperationPost({
821 | description: 'Post version object',
822 | summary: 'Post new version',
823 | parameters: {
824 | body: {
825 | description: 'New version',
826 | required: true,
827 | model: 'Version',
828 | },
829 | },
830 | responses: {
831 | 200: { description: 'Success' },
832 | 400: { description: 'Parameters fail' },
833 | },
834 | })
835 | @httpPost('/')
836 | public postVersion(
837 | request: express.Request,
838 | response: express.Response,
839 | next: express.NextFunction
840 | ): void {
841 | if (!request.body) {
842 | return response.status(400).end();
843 | }
844 | this.data.push(request.body);
845 | response.json(request.body);
846 | }
847 | }
848 | ```
849 |
850 | ### @ApiOperationPut(args: IApiOperationPutArgs)
851 |
852 | Decorate method for updating a resource in your controller.
853 |
854 | Example:
855 |
856 | ```ts
857 | import * as express from 'express';
858 | import { injectable } from 'inversify';
859 | import {
860 | controller,
861 | interfaces,
862 | requestParam,
863 | httpPut,
864 | } from 'inversify-express-utils';
865 | import {
866 | ApiPath,
867 | ApiOperationPut,
868 | SwaggerDefinitionConstant,
869 | } from 'swagger-express-ts';
870 | import 'reflect-metadata';
871 |
872 | @ApiPath({
873 | path: '/versions',
874 | name: 'Version',
875 | })
876 | @controller('/versions')
877 | @injectable()
878 | export class VersionController implements interfaces.Controller {
879 | public static TARGET_NAME: string = 'VersionController';
880 | private data: [any] = [
881 | {
882 | id: '1',
883 | name: 'Version 1',
884 | description: 'Description Version 1',
885 | version: '1.0.0',
886 | },
887 | {
888 | id: '2',
889 | name: 'Version 2',
890 | description: 'Description Version 2',
891 | version: '2.0.0',
892 | },
893 | ];
894 |
895 | @ApiOperationPut({
896 | path: '/{id}',
897 | parameters: {
898 | path: {
899 | id: {
900 | description: 'Id of version',
901 | type: SwaggerDefinitionConstant.Parameter.Type.STRING,
902 | required: true,
903 | },
904 | },
905 | body: {
906 | description: 'Updated version',
907 | model: 'Version',
908 | required: true,
909 | },
910 | },
911 | responses: {
912 | 200: { model: 'Version' },
913 | },
914 | })
915 | @httpPut('/:id')
916 | public putVersion(
917 | @requestParam('id') id: string,
918 | request: express.Request,
919 | response: express.Response,
920 | next: express.NextFunction
921 | ): void {
922 | if (!request.body) {
923 | return response.status(400).end();
924 | }
925 | this.data.forEach((version: any, index: number) => {
926 | if (version.id === id) {
927 | let newVersion = request.body;
928 | version.id = newVersion.id;
929 | version.name = newVersion.name;
930 | version.description = newVersion.description;
931 | version.version = newVersion.version;
932 | this.data[index] = version;
933 | return response.json(version);
934 | }
935 | });
936 | response.status(404).end();
937 | }
938 | }
939 | ```
940 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Olivier LIN-SI-CHENG
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # swagger-express-ts
4 | Automatically generate and serve swagger.json v2.0.
5 |
6 | ## Getting started
7 |
8 | First, install [swagger-express-ts](https://www.npmjs.com/package/swagger-express-ts).
9 |
10 | ```sh
11 | npm install swagger-express-ts --save
12 | ```
13 |
14 | and [init tsconfig.json](./wiki/installation.md)
15 |
16 | ## The Basics
17 |
18 | In the examples below, we use [inversify-express-utils](https://www.npmjs.com/package/inversify-express-utils). inversify-express-utils is not required to work with swagger-express-ts.
19 |
20 | ### Step 1: configure express
21 |
22 | ```ts
23 | import * as bodyParser from "body-parser";
24 | import * as express from "express";
25 | import "reflect-metadata";
26 | import { Container } from "inversify";
27 | import { interfaces, InversifyExpressServer, TYPE } from "inversify-express-utils";
28 | import { VersionController } from "./version/version.controller";
29 | import * as swagger from "swagger-express-ts";
30 | import { SwaggerDefinitionConstant } from "swagger-express-ts";
31 | const config = require ( "../config.json" );
32 |
33 | // set up container
34 | const container = new Container ();
35 |
36 | // note that you *must* bind your controllers to Controller
37 | container.bind ( TYPE.Controller )
38 | .to( VersionController ).inSingletonScope().whenTargetNamed( VersionController.TARGET_NAME );
39 |
40 | // create server
41 | const server = new InversifyExpressServer ( container );
42 |
43 | server.setConfig( ( app : any ) => {
44 | app.use( '/api-docs/swagger' , express.static( 'swagger' ) );
45 | app.use( '/api-docs/swagger/assets' , express.static( 'node_modules/swagger-ui-dist' ) );
46 | app.use( bodyParser.json() );
47 | app.use( swagger.express(
48 | {
49 | definition : {
50 | info : {
51 | title : "My api" ,
52 | version : "1.0"
53 | } ,
54 | externalDocs : {
55 | url : "My url"
56 | }
57 | // Models can be defined here
58 | }
59 | }
60 | ) );
61 | } );
62 |
63 | server.setErrorConfig( ( app : any ) => {
64 | app.use( ( err : Error , request : express.Request , response : express.Response , next : express.NextFunction ) => {
65 | console.error( err.stack );
66 | response.status( 500 ).send( "Something broke!" );
67 | } );
68 | } );
69 |
70 | const app = server.build();
71 |
72 | app.listen( config.port );
73 | console.info( "Server is listening on port : " + config.port );
74 |
75 | ```
76 |
77 | ### Step 2: Decorate your models
78 |
79 | ```ts
80 | @ApiModel( {
81 | description : "Version description" ,
82 | name : "Version"
83 | } )
84 | export class VersionModel {
85 |
86 | @ApiModelProperty( {
87 | description : "Id of version" ,
88 | required : true,
89 | example: ['123456789']
90 | } )
91 | id : number;
92 |
93 | @ApiModelProperty( {
94 | description : "" ,
95 | required : true
96 | } )
97 | name : string;
98 |
99 | @ApiModelProperty( {
100 | description : "Description of version" ,
101 | required : true
102 | } )
103 | description : string;
104 | }
105 | ```
106 |
107 | ### Step 3: Decorate your controllers
108 |
109 | ```ts
110 | @ApiPath({
111 | path: "/versions",
112 | name: "Version",
113 | security: { basicAuth: [] }
114 | })
115 | @controller("/versions")
116 | @injectable()
117 | export class VersionController implements interfaces.Controller {
118 | public static TARGET_NAME: string = "VersionController";
119 |
120 | private data = [{
121 | id: "1",
122 | name: "Version 1",
123 | description: "Description Version 1",
124 | version: "1.0.0"
125 | },
126 | {
127 | id: "2",
128 | name: "Version 2",
129 | description: "Description Version 2",
130 | version: "2.0.0"
131 | }];
132 |
133 | @ApiOperationGet({
134 | description: "Get versions objects list",
135 | summary: "Get versions list",
136 | responses: {
137 | 200: { description: "Success", type: SwaggerDefinitionConstant.Response.Type.ARRAY, model: "Version" }
138 | },
139 | security: {
140 | apiKeyHeader: []
141 | }
142 | })
143 | @httpGet("/")
144 | public getVersions(request: express.Request, response: express.Response, next: express.NextFunction): void {
145 | response.json(this.data);
146 | }
147 |
148 | @ApiOperationPost({
149 | description: "Post version object",
150 | summary: "Post new version",
151 | parameters: {
152 | body: { description: "New version", required: true, model: "Version" }
153 | },
154 | responses: {
155 | 200: { description: "Success" },
156 | 400: { description: "Parameters fail" }
157 | }
158 | })
159 | @httpPost("/")
160 | public postVersion(request: express.Request, response: express.Response, next: express.NextFunction): void {
161 | if (!request.body) {
162 | return response.status(400).end();
163 | }
164 | this.data.push(request.body);
165 | response.json(request.body);
166 | }
167 |
168 | }
169 | ```
170 |
171 | ### Step 4: Test
172 |
173 | Start your server and test on url : /api-docs/swagger.json
174 |
175 | ## Extra
176 |
177 | ### Serve swagger-ui in your API
178 |
179 | You can serve swagger.json and swagger-ui in your API.
180 |
181 | ```sh
182 | npm install swagger-ui-dist --save
183 | ```
184 |
185 | Create index.html in new directory "swagger".
186 |
187 | ```html
188 |
189 |
190 |
191 |
192 |
193 | Swagger UI
194 |
196 |
197 |
198 |
199 |
217 |
218 |
219 |
220 |
221 |
255 |
256 |
257 |
258 |
259 |
260 |
282 |
283 |
284 |
285 |
286 | ```
287 |
288 | Configure your server like that.
289 |
290 | ```ts
291 | app.use( '/api-docs/swagger', express.static( 'swagger' ) );
292 | app.use( '/api-docs/swagger/assets', express.static( 'node_modules/swagger-ui-dist' ) );
293 | ```
294 |
295 | Test it on url "/api-docs/swagger".
296 |
297 | 
298 |
299 | ## Project example
300 |
301 | You can quickly test swagger-express-ts with the project example [example-swagger-express-ts](https://github.com/olivierlsc/example-swagger-express-ts).
302 |
303 | ## Features and API
304 |
305 | - [Installation](./wiki/installation.md)
306 | - [Configuration](./wiki/configuration.md)
307 | - [@ApiModel](./wiki/api-model.decorator.md)
308 | - [@ApiModelProperty](./wiki/api-model-property.decorator.md)
309 | - [@ApiPath](./wiki/api-path.decorator.md)
310 | - [@ApiOperationGet](./wiki/api-operation-get.decorator.md)
311 | - [@ApiOperationPost](./wiki/api-operation-post.decorator.md)
312 | - [@ApiOperationPut](./wiki/api-operation-put.decorator.md)
313 | - [@ApiOperationPatch](./wiki/api-operation-patch.decorator.md)
314 | - [@ApiOperationDelete](./wiki/api-operation-delete.decorator.md)
315 |
316 | ## For any questions, suggestions, or feature requests
317 |
318 | [Please file an issue](https://github.com/olivierlsc/swagger-express-ts/issues)!
319 |
320 | ## Help wanted
321 |
322 | swagger-express-ts wants additional maintainers! To maintain and continue to develop this young library, [Please post in this issue](https://github.com/olivierlsc/swagger-express-ts/issues/34).
323 |
--------------------------------------------------------------------------------
/config.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "port": 9200
3 | }
4 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const ts = require('gulp-typescript');
3 | const sourcemaps = require('gulp-sourcemaps');
4 | const clean = require('gulp-clean');
5 | const tslint = require('gulp-tslint');
6 |
7 | const path = {
8 | src: 'src/**/*.ts',
9 | dist: 'dist',
10 | module: 'node_modules/swagger-express-ts',
11 | lib: {
12 | src: 'lib/swagger-express-ts-lib/src/**/*.ts',
13 | },
14 | };
15 |
16 | function cleanAll() {
17 | return gulp
18 | .src(['dist', path.module, '.nyc_output', 'coverage', '*.log*'], {
19 | read: false,
20 | allowEmpty: true,
21 | })
22 | .pipe(clean());
23 | }
24 |
25 | function buildLib() {
26 | var tsProjectLib = ts.createProject('tsconfig.lib.json', {});
27 | return gulp
28 | .src([path.lib.src])
29 | .pipe(sourcemaps.init({ loadMaps: true }))
30 | .pipe(tsProjectLib())
31 | .pipe(sourcemaps.write('.'))
32 | .pipe(gulp.dest(path.dist));
33 | }
34 |
35 | function buildModule() {
36 | var tsProjectModule = ts.createProject('tsconfig.dev.lib.json', {});
37 | return (
38 | gulp
39 | .src([path.lib.src])
40 | .pipe(sourcemaps.init({ loadMaps: true }))
41 | .pipe(tsProjectModule())
42 | //.on ("error", function (err) {
43 | // process.exit (1);
44 | //})
45 | .pipe(sourcemaps.write('.'))
46 | .pipe(gulp.dest(path.module))
47 | );
48 | }
49 |
50 | function copyFilesInDist() {
51 | return gulp
52 | .src([
53 | './README.md',
54 | './LICENSE',
55 | './CHANGELOG.md',
56 | './lib/swagger-express-ts-lib/package.json',
57 | ])
58 | .pipe(gulp.dest(path.dist));
59 | }
60 |
61 | function tsLint() {
62 | return gulp.src([path.src, path.lib.src]).pipe(
63 | tslint({
64 | formatter: 'verbose',
65 | fix: true,
66 | })
67 | );
68 | // .pipe(tslint.report())
69 | // .pipe(
70 | // tslintReporter({
71 | // sort: true,
72 | // filename: 'reports/checkstyle/results.xml',
73 | // severity: 'error',
74 | // })
75 | // );
76 | }
77 | gulp.task('tslint', tsLint);
78 | gulp.task('clean', cleanAll);
79 | gulp.task('build:lib', gulp.series('clean', buildLib, copyFilesInDist));
80 | gulp.task('build', gulp.series('clean', 'tslint', buildModule));
81 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "swagger-express-ts",
3 | "version": "1.1.0",
4 | "description": "Generate and serve swagger.json",
5 | "main": "index.js",
6 | "types": "index.d.ts",
7 | "typings": "index.d.ts",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/olivierlsc/swagger-express-ts.git"
11 | },
12 | "author": "Olivier LIN-SI-CHENG",
13 | "license": "MIT",
14 | "keywords": [
15 | "inversify",
16 | "inversifyjs",
17 | "swagger",
18 | "swagger2",
19 | "swagger-ui",
20 | "typescript",
21 | "expressjs",
22 | "express",
23 | "api rest",
24 | "documentation",
25 | "decorator",
26 | "generator",
27 | "swagger.json",
28 | "json",
29 | "rest"
30 | ],
31 | "bugs": {
32 | "url": "https://github.com/olivierlsc/swagger-express-ts/issues"
33 | },
34 | "homepage": "https://github.com/olivierlsc/swagger-express-ts#readme",
35 | "peerDependencies": {
36 | "@types/body-parser": "^1.19.0",
37 | "@types/compression": "1.7.0",
38 | "@types/express": "^4.17.11",
39 | "@types/helmet": "0.0.48",
40 | "@types/inversify": "^2.0.33",
41 | "@types/lodash": "^4.14.168",
42 | "body-parser": "^1.19.0",
43 | "compression": "^1.7.4",
44 | "express": "^4.17.1",
45 | "helmet": "^4.4.1",
46 | "inversify": "^4.13.0",
47 | "inversify-express-utils": "^4.2.2",
48 | "lodash": "^4.17.21",
49 | "reflect-metadata": "^0.1.13"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-model-property.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 |
4 | export interface IApiModelPropertyArgs {
5 | /**
6 | * Define if property is required.
7 | * Optional. Default is false.
8 | */
9 | required?: boolean;
10 |
11 | /**
12 | * Define format of property. Example: SwaggerDefinitionConstant.Definition.Property.Format.INT_64
13 | * Optional.
14 | */
15 | format?: string;
16 |
17 | /**
18 | * Define type of property. Example: SwaggerDefinitionConstant.Definition.Property.Type.STRING
19 | * Optional.
20 | */
21 | type?: string;
22 |
23 | /**
24 | * Define description.
25 | * Optional.
26 | */
27 | description?: string;
28 |
29 | /**
30 | * Define enum;
31 | * Optional.
32 | */
33 | enum?: string[];
34 |
35 | /**
36 | * Define model.
37 | * Optional.
38 | */
39 | model?: string;
40 |
41 | /**
42 | * Define type of item. Example: SwaggerDefinitionConstant.Definition.Property.Type.STRING
43 | * Optional.
44 | */
45 | itemType?: string;
46 |
47 | /**
48 | * Define example.
49 | */
50 | example?: any | any[];
51 | }
52 |
53 | export function ApiModelProperty(
54 | args?: IApiModelPropertyArgs
55 | ): PropertyDecorator {
56 | return (target: any, propertyKey: string | symbol) => {
57 | let propertyType = '';
58 |
59 | if (typeof args.itemType !== 'undefined' && args.itemType !== null) {
60 | propertyType = args.itemType;
61 | } else {
62 | try {
63 | propertyType = Reflect.getMetadata(
64 | 'design:type',
65 | target,
66 | propertyKey
67 | ).name;
68 | } catch (err) {
69 | if (err.message === "Cannot read property 'name' of undefined") {
70 | throw new Error(
71 | `${err.message}. This usually occours due to a circular reference between models. A possible solution is to set the itemType argument of the @ApiModelProperty to a string that matches the class name of the field type. The field in question is named ${String(propertyKey)}.`);
72 | } else {
73 | throw err;
74 | }
75 | }
76 | }
77 |
78 | SwaggerService.getInstance().addApiModelProperty(
79 | args,
80 | target,
81 | propertyKey,
82 | propertyType
83 | );
84 | };
85 | }
86 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-model.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 |
4 | export interface IApiModelArgs {
5 | description?: string;
6 | name?: string;
7 | }
8 |
9 | export function ApiModel(args?: IApiModelArgs): ClassDecorator {
10 | return (target: any) => {
11 | SwaggerService.getInstance().addApiModel(args, target);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-operation-delete.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 | export interface IApiOperationDeleteArgs extends IApiOperationArgsBase {}
4 |
5 | export function ApiOperationDelete(
6 | args: IApiOperationDeleteArgs
7 | ): MethodDecorator {
8 | return (
9 | target: any,
10 | propertyKey: string | symbol,
11 | descriptor: PropertyDescriptor
12 | ) => {
13 | SwaggerService.getInstance().addOperationDelete(
14 | args,
15 | target,
16 | propertyKey
17 | );
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-operation-get.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 | export interface IApiOperationGetArgs extends IApiOperationArgsBase {}
4 |
5 | export function ApiOperationGet(args: IApiOperationGetArgs): MethodDecorator {
6 | return (
7 | target: any,
8 | propertyKey: string | symbol,
9 | descriptor: PropertyDescriptor
10 | ) => {
11 | SwaggerService.getInstance().addOperationGet(args, target, propertyKey);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-operation-patch.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 | export interface IApiOperationPatchArgs extends IApiOperationArgsBase {}
4 |
5 | export function ApiOperationPatch(
6 | args: IApiOperationPatchArgs
7 | ): MethodDecorator {
8 | return (
9 | target: any,
10 | propertyKey: string | symbol,
11 | descriptor: PropertyDescriptor
12 | ) => {
13 | SwaggerService.getInstance().addOperationPatch(
14 | args,
15 | target,
16 | propertyKey
17 | );
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-operation-post.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 | export interface IApiOperationPostArgs extends IApiOperationArgsBase {}
4 |
5 | export function ApiOperationPost(args: IApiOperationPostArgs): MethodDecorator {
6 | return (
7 | target: any,
8 | propertyKey: string | symbol,
9 | descriptor: PropertyDescriptor
10 | ) => {
11 | SwaggerService.getInstance().addOperationPost(
12 | args,
13 | target,
14 | propertyKey
15 | );
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-operation-put.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | import { IApiOperationArgsBase } from './i-api-operation-args.base';
3 | export interface IApiOperationPutArgs extends IApiOperationArgsBase {}
4 |
5 | export function ApiOperationPut(args: IApiOperationPutArgs): MethodDecorator {
6 | return (
7 | target: any,
8 | propertyKey: string | symbol,
9 | descriptor: PropertyDescriptor
10 | ) => {
11 | SwaggerService.getInstance().addOperationPut(args, target, propertyKey);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/api-path.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SwaggerService } from './swagger.service';
2 | export interface IApiPathArgs {
3 | path: string;
4 | name: string;
5 | description?: string;
6 | security?: { [key: string]: any[] };
7 | deprecated?: boolean;
8 | }
9 | export function ApiPath(args: IApiPathArgs): ClassDecorator {
10 | return (target: any) => {
11 | SwaggerService.getInstance().addPath(args, target);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/express.configurator.ts:
--------------------------------------------------------------------------------
1 | import { Router, Request, Response, NextFunction } from 'express';
2 | import { SwaggerService } from './swagger.service';
3 | import * as assert from 'assert';
4 | import { build, ISwaggerBuildDefinition } from './swagger.builder';
5 | import { ISwagger } from './i-swagger';
6 |
7 | export interface ISwaggerExpressOptions {
8 | /**
9 | * Path of resource.
10 | * Default is "/api-docs/swagger.json".
11 | */
12 | path?: string;
13 |
14 | /**
15 | * Swagger Definition.
16 | */
17 | definition?: ISwaggerBuildDefinition;
18 | }
19 |
20 | export function express(options?: ISwaggerExpressOptions): Router {
21 | let path: string = '/api-docs/swagger.json';
22 | if (options) {
23 | assert.ok(options.definition, 'Definition is required.');
24 | if (options.path) {
25 | path = options.path;
26 | }
27 | if (options.definition) {
28 | build(options.definition);
29 | }
30 | }
31 | const router = buildRouter(path);
32 | return router;
33 | }
34 |
35 | function buildRouter(path: string): Router {
36 | const router: Router = Router();
37 | router.get(
38 | path,
39 | (request: Request, response: Response, next: NextFunction) => {
40 | const data: ISwagger = SwaggerService.getInstance().getData();
41 | response.json(data);
42 | }
43 | );
44 | return router;
45 | }
46 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/i-api-operation-args.base.ts:
--------------------------------------------------------------------------------
1 | export interface IApiOperationArgsBaseParameter {
2 | name?: string; // Override [key: string]. Default [key: string].
3 | description?: string;
4 | type?: string;
5 | required?: boolean;
6 | format?: string;
7 | minimum?: number;
8 | maximum?: number;
9 | default?: number;
10 | deprecated?: boolean;
11 | allowEmptyValue?: boolean;
12 | items?: {
13 | type?: string;
14 | }
15 | }
16 |
17 | export interface IApiPropertyBodyOperationArgsBaseParameter {
18 | type: string;
19 | required?: boolean;
20 | }
21 |
22 | export interface IApiBodyOperationArgsBaseParameter
23 | extends IApiOperationArgsBaseParameter {
24 | properties?: { [key: string]: IApiPropertyBodyOperationArgsBaseParameter };
25 | model?: string;
26 | }
27 |
28 | export interface IApiOperationArgsBaseResponse {
29 | description?: string;
30 | type?: string;
31 | model?: string;
32 | }
33 |
34 | export interface IApiOperationArgsBaseParameters {
35 | header?: { [key: string]: IApiOperationArgsBaseParameter };
36 | path?: { [key: string]: IApiOperationArgsBaseParameter };
37 | query?: { [key: string]: IApiOperationArgsBaseParameter };
38 | body?: IApiBodyOperationArgsBaseParameter; // use only for POST, PUT and PATCH
39 | formData?: { [key: string]: IApiOperationArgsBaseParameter };
40 | }
41 |
42 | export interface IApiOperationArgsBase {
43 | /**
44 | * Define description
45 | * Optional.
46 | */
47 | description?: string;
48 |
49 | /**
50 | * Define summary
51 | * Optional.
52 | */
53 | summary?: string;
54 |
55 | /**
56 | * Define produces
57 | * Optional.
58 | */
59 | produces?: string[];
60 |
61 | /**
62 | * Define consumes
63 | * Optional.
64 | */
65 | consumes?: string[];
66 |
67 | /**
68 | * Define tags
69 | * Optional.
70 | */
71 | tags?: string[];
72 |
73 | /**
74 | * Define path
75 | * Optional.
76 | */
77 | path?: string;
78 |
79 | /**
80 | * Define parameters
81 | * Optional.
82 | */
83 | parameters?: IApiOperationArgsBaseParameters;
84 |
85 | /**
86 | * Define responses
87 | */
88 | responses: { [key: string]: IApiOperationArgsBaseResponse };
89 |
90 | /**
91 | * Define security
92 | * Optional.
93 | */
94 | security?: { [key: string]: any[] };
95 |
96 | /**
97 | * Define deprecated
98 | * Optional.
99 | */
100 | deprecated?: boolean;
101 | }
102 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/i-swagger.ts:
--------------------------------------------------------------------------------
1 | import { ISwaggerSecurityDefinition } from './swagger.builder';
2 | export interface ISwaggerLicense {
3 | name: string;
4 | url?: string;
5 | }
6 |
7 | export interface ISwaggerContact {
8 | name?: string;
9 | url?: string;
10 | email?: string;
11 | }
12 |
13 | export interface ISwaggerInfo {
14 | title: string;
15 | description?: string;
16 | termsOfService?: string;
17 | contact?: ISwaggerContact;
18 | license?: ISwaggerLicense;
19 | version: string;
20 | }
21 |
22 | export interface ISwaggerVariableServer {
23 | enum?: [string];
24 | default: string;
25 | description?: string;
26 | }
27 |
28 | export interface ISwaggerServer {
29 | url: string;
30 | description?: string;
31 | variables: [ISwaggerVariableServer]; // TODO : Fix it
32 | }
33 |
34 | export interface ISwaggerExternalDocs {
35 | description?: string;
36 | url: string;
37 | }
38 |
39 | export interface ISwaggerOperationParameter {
40 | name: string;
41 | in: string;
42 | type?: string;
43 | items?: {
44 | type?: string;
45 | };
46 | format?: string;
47 | description?: string;
48 | required?: boolean;
49 | minimum?: number;
50 | maximum?: number;
51 | default?: number;
52 | deprecated?: boolean;
53 | allowEmptyValue?: boolean;
54 | schema?: ISwaggerOperationSchema;
55 | }
56 |
57 | export interface ISwaggerPropertySchemaOperation {
58 | type: string;
59 | }
60 |
61 | export interface ISwaggerOperationSchema {
62 | type?: string;
63 | items?: { $ref: string };
64 | $ref?: string;
65 | format?: string;
66 | required?: string[]; // Array content name of property
67 | properties?: {[key: string] : ISwaggerPropertySchemaOperation}
68 | }
69 |
70 | export interface ISwaggerOperationSchemaItems {
71 | $ref: string;
72 | }
73 |
74 | export interface ISwaggerOperationResponse {
75 | description?: string;
76 | schema?: ISwaggerOperationSchema;
77 | }
78 |
79 | export interface ISwaggerOperation {
80 | tags?: string[];
81 | summary?: string;
82 | description?: string;
83 | operationId: string | symbol;
84 | parameters?: ISwaggerOperationParameter[];
85 | produces?: string[];
86 | consumes?: string[];
87 | responses?: { [key: string]: ISwaggerOperationResponse };
88 | security?: { [key: string]: any[] }[];
89 | deprecated?: boolean;
90 | }
91 |
92 | export interface ISwaggerTag {
93 | name: string;
94 | description: string;
95 | }
96 |
97 | export interface ISwaggerPath {
98 | get?: ISwaggerOperation;
99 | post?: ISwaggerOperation;
100 | put?: ISwaggerOperation;
101 | patch?: ISwaggerOperation;
102 | delete?: ISwaggerOperation;
103 | }
104 |
105 | export interface ISwaggerDefinitionPropertyItems {
106 | $ref?: string;
107 | type?: string;
108 | }
109 |
110 | export interface ISwaggerDefinitionProperty {
111 | type?: string; // Example : SwaggerDefinition.Definition.Property.Type.INTEGER
112 | format?: string; // Example : SwaggerDefinition.Definition.Property.Format.INT_64
113 | required?: boolean;
114 | description?: string;
115 | enum?: string[];
116 | items?: ISwaggerDefinitionPropertyItems;
117 | $ref?: string;
118 | example?: any []
119 | }
120 |
121 | export interface ISwaggerDefinitionXML {
122 | name: string;
123 | }
124 |
125 | export interface ISwaggerDefinition {
126 | type: string; // Example : SwaggerDefinition.Definition.Type.OBJECT
127 | required?: string[];
128 | properties: { [key: string]: ISwaggerDefinitionProperty };
129 | xml?: ISwaggerDefinitionXML;
130 | description?: string;
131 | }
132 |
133 | export interface ISwagger {
134 | basePath?: string;
135 | openapi?: string;
136 | info: ISwaggerInfo;
137 | servers?: [ISwaggerServer];
138 | paths?: { [key: string]: ISwaggerPath };
139 | host?: string;
140 | swagger: string;
141 | tags?: ISwaggerTag[];
142 | schemes: string[]; // Example : SwaggerDefinition.Scheme.HTTP
143 | produces: string[]; // Example : SwaggerDefinition.Produce.JSON
144 | consumes: string[]; // Example : SwaggerDefinition.Consume.JSON
145 | definitions: { [key: string]: ISwaggerDefinition };
146 | externalDocs?: ISwaggerExternalDocs;
147 | securityDefinitions?: { [key: string]: ISwaggerSecurityDefinition };
148 | }
149 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/index.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 |
3 | export { IApiPathArgs, ApiPath } from './api-path.decorator';
4 | export {
5 | IApiOperationGetArgs,
6 | ApiOperationGet,
7 | } from './api-operation-get.decorator';
8 | export {
9 | IApiOperationPostArgs,
10 | ApiOperationPost,
11 | } from './api-operation-post.decorator';
12 | export {
13 | IApiOperationPutArgs,
14 | ApiOperationPut,
15 | } from './api-operation-put.decorator';
16 | export {
17 | IApiOperationPatchArgs,
18 | ApiOperationPatch,
19 | } from './api-operation-patch.decorator';
20 | export {
21 | IApiOperationDeleteArgs,
22 | ApiOperationDelete,
23 | } from './api-operation-delete.decorator';
24 |
25 | export {
26 | IApiModelPropertyArgs,
27 | ApiModelProperty,
28 | } from './api-model-property.decorator';
29 | export { IApiModelArgs, ApiModel } from './api-model.decorator';
30 |
31 | export { SwaggerDefinitionConstant } from './swagger-definition.constant';
32 | export { express, ISwaggerExpressOptions } from './express.configurator';
33 | export { build } from './swagger.builder';
34 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/swagger-definition.constant.spec.ts:
--------------------------------------------------------------------------------
1 | import * as chai from 'chai';
2 | import { SwaggerDefinitionConstant } from '.';
3 | const expect = chai.expect;
4 |
5 | describe('SwaggerDefinitionConstant', () => {
6 | describe('Produce', () => {
7 | it('expect JSON', () => {
8 | expect(SwaggerDefinitionConstant.Produce.JSON).exist;
9 | });
10 | it('expect XML', () => {
11 | expect(SwaggerDefinitionConstant.Produce.XML).exist;
12 | });
13 | it('expect ZIP', () => {
14 | expect(SwaggerDefinitionConstant.Produce.ZIP).exist;
15 | });
16 | it('expect PDF', () => {
17 | expect(SwaggerDefinitionConstant.Produce.PDF).exist;
18 | });
19 | it('expect X_WWW_FORM_URLENCODED', () => {
20 | expect(SwaggerDefinitionConstant.Produce.X_WWW_FORM_URLENCODED)
21 | .exist;
22 | });
23 | it('expect FORM_DATA', () => {
24 | expect(SwaggerDefinitionConstant.Produce.FORM_DATA).exist;
25 | });
26 | it('expect TEXT_PLAIN', () => {
27 | expect(SwaggerDefinitionConstant.Produce.TEXT_PLAIN).exist;
28 | });
29 | it('expect TEXT_HTML', () => {
30 | expect(SwaggerDefinitionConstant.Produce.TEXT_HTML).exist;
31 | });
32 | it('expect PNG', () => {
33 | expect(SwaggerDefinitionConstant.Produce.PNG).exist;
34 | });
35 | it('expect GIF', () => {
36 | expect(SwaggerDefinitionConstant.Produce.GIF).exist;
37 | });
38 | it('expect JPEG', () => {
39 | expect(SwaggerDefinitionConstant.Produce.JPEG).exist;
40 | });
41 | });
42 |
43 | describe('Scheme', () => {
44 | it('expect HTTP', () => {
45 | expect(SwaggerDefinitionConstant.Scheme.HTTP).exist;
46 | });
47 | it('expect HTTPS', () => {
48 | expect(SwaggerDefinitionConstant.Scheme.HTTPS).exist;
49 | });
50 | });
51 |
52 | describe('Model', () => {
53 | describe('Type', () => {
54 | it('expect OBJECT', () => {
55 | expect(SwaggerDefinitionConstant.Model.Type.OBJECT).exist;
56 | });
57 | it('expect ARRAY', () => {
58 | expect(SwaggerDefinitionConstant.Model.Type.ARRAY).exist;
59 | });
60 | });
61 | describe('Property', () => {
62 | describe('Type', () => {
63 | expectType(SwaggerDefinitionConstant.Model.Property.Type);
64 | });
65 | describe('Format', () => {
66 | it('expect INT_64', () => {
67 | expect(
68 | SwaggerDefinitionConstant.Model.Property.Format.INT_64
69 | ).exist;
70 | });
71 | });
72 | });
73 | });
74 |
75 | describe('Parameter', () => {
76 | describe('Type', () => {
77 | expectType(SwaggerDefinitionConstant.Parameter.Type);
78 | });
79 | describe('In', () => {
80 | it('expect HEADER', () => {
81 | expect(SwaggerDefinitionConstant.Parameter.In.HEADER).exist;
82 | });
83 | it('expect PATH', () => {
84 | expect(SwaggerDefinitionConstant.Parameter.In.PATH).exist;
85 | });
86 | it('expect QUERY', () => {
87 | expect(SwaggerDefinitionConstant.Parameter.In.QUERY).exist;
88 | });
89 | it('expect BODY', () => {
90 | expect(SwaggerDefinitionConstant.Parameter.In.BODY).exist;
91 | });
92 | it('expect FORM_DATA', () => {
93 | expect(SwaggerDefinitionConstant.Parameter.In.FORM_DATA).exist;
94 | });
95 | });
96 | });
97 |
98 | describe('Response', () => {
99 | describe('Type', () => {
100 | expectType(SwaggerDefinitionConstant.Response.Type);
101 | });
102 | });
103 |
104 | describe('Security', () => {
105 | describe('Type', () => {
106 | it('expect BASIC_AUTHENTICATION', () => {
107 | expect(
108 | SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
109 | ).exist;
110 | });
111 | it('expect API_KEY', () => {
112 | expect(SwaggerDefinitionConstant.Security.Type.API_KEY).exist;
113 | });
114 | });
115 | describe('In', () => {
116 | it('expect HEADER', () => {
117 | expect(SwaggerDefinitionConstant.Security.In.HEADER).exist;
118 | });
119 | it('expect QUERY', () => {
120 | expect(SwaggerDefinitionConstant.Security.In.QUERY).exist;
121 | });
122 | });
123 | });
124 | });
125 |
126 | function expectType(Type: any) {
127 | it('expect STRING', () => {
128 | expect(Type.STRING).exist;
129 | });
130 | it('expect NUMBER', () => {
131 | expect(Type.NUMBER).exist;
132 | });
133 | it('expect INTEGER', () => {
134 | expect(Type.INTEGER).exist;
135 | });
136 | it('expect BOOLEAN', () => {
137 | expect(Type.BOOLEAN).exist;
138 | });
139 | it('expect ARRAY', () => {
140 | expect(Type.ARRAY).exist;
141 | });
142 | it('expect OBJECT', () => {
143 | expect(Type.OBJECT).exist;
144 | });
145 | }
146 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/swagger-definition.constant.ts:
--------------------------------------------------------------------------------
1 | export class SwaggerDefinitionConstant {
2 | public static JSON: string = 'application/json';
3 | public static XML: string = 'application/xml';
4 | public static ZIP: string = 'application/zip';
5 | public static PDF: string = 'application/pdf';
6 | public static X_WWW_FORM_URLENCODED: string = 'application/x-www-form-urlencoded';
7 | public static FORM_DATA: string = 'multipart/form-data';
8 | public static TEXT_PLAIN: string = 'text/plain';
9 | public static TEXT_HTML: string = 'text/html';
10 | public static PNG: string = 'image/png';
11 | public static GIF: string = 'image/gif';
12 | public static JPEG: string = 'image/jpeg';
13 | public static STRING: string = 'string';
14 | public static NUMBER: string = 'number';
15 | public static INTEGER: string = 'integer';
16 | public static BOOLEAN: string = 'boolean';
17 | public static ARRAY: string = 'array';
18 | public static OBJECT: string = 'object';
19 | public static QUERY: string = 'query';
20 |
21 | public static Produce = {
22 | FORM_DATA: SwaggerDefinitionConstant.FORM_DATA,
23 | GIF: SwaggerDefinitionConstant.GIF,
24 | JPEG: SwaggerDefinitionConstant.JPEG,
25 | JSON: SwaggerDefinitionConstant.JSON,
26 | PDF: SwaggerDefinitionConstant.PDF,
27 | PNG: SwaggerDefinitionConstant.PNG,
28 | TEXT_HTML: SwaggerDefinitionConstant.TEXT_HTML,
29 | TEXT_PLAIN: SwaggerDefinitionConstant.TEXT_PLAIN,
30 | XML: SwaggerDefinitionConstant.XML,
31 | X_WWW_FORM_URLENCODED: SwaggerDefinitionConstant.X_WWW_FORM_URLENCODED,
32 | ZIP: SwaggerDefinitionConstant.ZIP,
33 | };
34 |
35 | public static Scheme = {
36 | HTTP: 'http',
37 | HTTPS: 'https',
38 | };
39 |
40 | public static Consume = {
41 | JSON: SwaggerDefinitionConstant.JSON,
42 | XML: SwaggerDefinitionConstant.XML,
43 | };
44 |
45 | public static Model = {
46 | Property: {
47 | Format: {
48 | INT_64: 'int64',
49 | INT_32: 'int32',
50 | FLOAT: 'float',
51 | DOUBLE: 'double',
52 | BYTE: 'byte',
53 | BINARY: 'binary',
54 | DATE: 'date',
55 | DATE_TIME: 'date-time',
56 | PASSWORD: 'password'
57 | },
58 | ItemType: {
59 | BOOLEAN: SwaggerDefinitionConstant.BOOLEAN,
60 | INTEGER: SwaggerDefinitionConstant.INTEGER,
61 | NUMBER: SwaggerDefinitionConstant.NUMBER,
62 | STRING: SwaggerDefinitionConstant.STRING,
63 | },
64 | Type: {
65 | ARRAY: SwaggerDefinitionConstant.ARRAY,
66 | BOOLEAN: SwaggerDefinitionConstant.BOOLEAN,
67 | INTEGER: SwaggerDefinitionConstant.INTEGER,
68 | NUMBER: SwaggerDefinitionConstant.NUMBER,
69 | OBJECT: SwaggerDefinitionConstant.OBJECT,
70 | STRING: SwaggerDefinitionConstant.STRING,
71 | },
72 | },
73 | Type: {
74 | OBJECT: SwaggerDefinitionConstant.OBJECT,
75 | ARRAY: SwaggerDefinitionConstant.ARRAY,
76 | },
77 | };
78 |
79 | public static Parameter = {
80 | In: {
81 | HEADER: 'header',
82 | BODY: 'body',
83 | FORM_DATA: 'formData',
84 | PATH: 'path',
85 | QUERY: SwaggerDefinitionConstant.QUERY,
86 | },
87 | Type: {
88 | ARRAY: SwaggerDefinitionConstant.ARRAY,
89 | BOOLEAN: SwaggerDefinitionConstant.BOOLEAN,
90 | INTEGER: SwaggerDefinitionConstant.INTEGER,
91 | NUMBER: SwaggerDefinitionConstant.NUMBER,
92 | OBJECT: SwaggerDefinitionConstant.OBJECT,
93 | STRING: SwaggerDefinitionConstant.STRING,
94 | },
95 | };
96 |
97 | public static Response = {
98 | Type: {
99 | ARRAY: SwaggerDefinitionConstant.ARRAY,
100 | BOOLEAN: SwaggerDefinitionConstant.BOOLEAN,
101 | INTEGER: SwaggerDefinitionConstant.INTEGER,
102 | NUMBER: SwaggerDefinitionConstant.NUMBER,
103 | OBJECT: SwaggerDefinitionConstant.OBJECT,
104 | STRING: SwaggerDefinitionConstant.STRING,
105 | },
106 | };
107 |
108 | public static Security = {
109 | In: {
110 | HEADER: 'header',
111 | QUERY: SwaggerDefinitionConstant.QUERY,
112 | },
113 | Type: {
114 | API_KEY: 'apiKey',
115 | BASIC_AUTHENTICATION: 'basic',
116 | },
117 | };
118 | }
119 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/swagger.builder.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ISwaggerInfo,
3 | ISwaggerDefinition,
4 | ISwaggerDefinitionProperty,
5 | ISwaggerExternalDocs,
6 | ISwaggerOperationResponse,
7 | } from './i-swagger';
8 | import * as assert from 'assert';
9 | import { SwaggerService } from './swagger.service';
10 | import { SwaggerDefinitionConstant } from './swagger-definition.constant';
11 | import {
12 | IApiOperationArgsBaseParameter,
13 | IApiOperationArgsBaseResponse,
14 | } from './i-api-operation-args.base';
15 |
16 | export interface ISwaggerBuildDefinitionModelPropertyType {
17 | type?: string | ISwaggerBuildDefinitionModelPropertyType;
18 | }
19 |
20 | export interface ISwaggerBuildDefinitionModelProperty {
21 | /**
22 | * Define type of property. Example: SwaggerDefinitionConstant.Definition.Property.Type.STRING
23 | * Optional.
24 | */
25 | type?: string;
26 |
27 | /**
28 | * Define format of property. Example: SwaggerDefinitionConstant.Definition.Property.Format.INT_64
29 | * Optional.
30 | */
31 | format?: string;
32 |
33 | /**
34 | * Define if property is required.
35 | * Optional. Default is false.
36 | */
37 | required?: boolean;
38 |
39 | /**
40 | * Define model.
41 | * Optional.
42 | */
43 | model?: string;
44 |
45 | /**
46 | * Define enum;
47 | * Optional.
48 | */
49 | enum?: string[];
50 |
51 | /**
52 | * Define description.
53 | * Optional.
54 | */
55 | description?: string;
56 |
57 | /**
58 | * Define type of item. Example: SwaggerDefinitionConstant.Definition.Property.Type.STRING
59 | * Optional.
60 | */
61 | itemType?: string;
62 |
63 | /**
64 | * Define example.
65 | */
66 | example?: any[];
67 | }
68 |
69 | export interface ISwaggerBuildDefinitionModel {
70 | /**
71 | * Define description.
72 | */
73 | description?: string;
74 |
75 | /**
76 | * Define all properties of model.
77 | */
78 | properties: { [key: string]: ISwaggerBuildDefinitionModelProperty };
79 | }
80 |
81 | export interface ISwaggerSecurityDefinition {
82 | /**
83 | * Define type of security.
84 | */
85 | type: string;
86 |
87 | /**
88 | * Define where security set.
89 | * Optional.
90 | */
91 | in?: string;
92 |
93 | /**
94 | * Define name of security.
95 | * Optional.
96 | */
97 | name?: string;
98 | }
99 |
100 | export interface ISwaggerBuildDefinition {
101 | /**
102 | * Base URL for all API.
103 | * Optional. Default is "/".
104 | */
105 | basePath?: string;
106 |
107 | /**
108 | * Version Open API
109 | * Optional.
110 | */
111 | openapi?: string;
112 |
113 | /**
114 | * Metadata.
115 | */
116 | info: ISwaggerInfo;
117 |
118 | /**
119 | * Define the MIME types supported by the API for consumes. The root-level definition can be overridden in individual operations.
120 | * Optional. Default is SwaggerDefinition.Consume.JSON = "application/json".
121 | */
122 | consumes?: string[];
123 |
124 | /**
125 | * Define the MIME types supported by the API for produces. The root-level definition can be overridden in individual operations.
126 | * Optional. Default is SwaggerDefinition.Produce.JSON = "application/json".
127 | */
128 | produces?: string[];
129 |
130 | /**
131 | * Define schemes.
132 | * Optional. Default is SwaggerDefinition.Scheme.HTTP = "http".
133 | */
134 | schemes?: string[];
135 |
136 | /**
137 | * Define host.
138 | * Optional.
139 | */
140 | host?: string;
141 |
142 | /**
143 | * Define All Definitions.
144 | * Optional.
145 | */
146 | models?: { [key: string]: ISwaggerBuildDefinitionModel };
147 |
148 | /**
149 | * Define external doc
150 | * Optional.
151 | */
152 | externalDocs?: ISwaggerExternalDocs;
153 |
154 | /**
155 | * Define security definitions list.
156 | * Optional.
157 | */
158 | securityDefinitions?: { [key: string]: ISwaggerSecurityDefinition };
159 |
160 | /**
161 | * Define global responses.
162 | * Optional.
163 | */
164 | responses?: { [key: string]: IApiOperationArgsBaseResponse };
165 | }
166 |
167 | export function build(buildDefinition: ISwaggerBuildDefinition): void {
168 | assert.ok(buildDefinition, 'Definition are required.');
169 | assert.ok(
170 | buildDefinition.info,
171 | 'Informations are required. Base is { title: "Title of my API", version: "1.0.0"}'
172 | );
173 | if (buildDefinition.basePath) {
174 | SwaggerService.getInstance().setBasePath(buildDefinition.basePath);
175 | }
176 | if (buildDefinition.openapi) {
177 | SwaggerService.getInstance().setOpenapi(buildDefinition.openapi);
178 | }
179 | if (buildDefinition.info) {
180 | SwaggerService.getInstance().setInfo(buildDefinition.info);
181 | }
182 | if (buildDefinition.schemes) {
183 | SwaggerService.getInstance().setSchemes(buildDefinition.schemes);
184 | }
185 | if (buildDefinition.produces) {
186 | SwaggerService.getInstance().setProduces(buildDefinition.produces);
187 | }
188 | if (buildDefinition.consumes) {
189 | SwaggerService.getInstance().setConsumes(buildDefinition.consumes);
190 | }
191 | if (buildDefinition.host) {
192 | SwaggerService.getInstance().setHost(buildDefinition.host);
193 | }
194 | if (buildDefinition.externalDocs) {
195 | SwaggerService.getInstance().setExternalDocs(
196 | buildDefinition.externalDocs
197 | );
198 | }
199 | if (buildDefinition.securityDefinitions) {
200 | SwaggerService.getInstance().addSecurityDefinitions(
201 | buildDefinition.securityDefinitions
202 | );
203 | }
204 | if (buildDefinition.models) {
205 | SwaggerService.getInstance().setDefinitions(buildDefinition.models);
206 | }
207 | if (buildDefinition.responses) {
208 | SwaggerService.getInstance().setGlobalResponses(
209 | buildDefinition.responses
210 | );
211 | }
212 | SwaggerService.getInstance().buildSwagger();
213 | }
214 |
--------------------------------------------------------------------------------
/lib/swagger-express-ts-lib/src/swagger.service.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import * as _ from 'lodash';
3 | import { IApiModelArgs } from '.';
4 | import { IApiModelPropertyArgs } from './api-model-property.decorator';
5 | import { IApiOperationGetArgs } from './api-operation-get.decorator';
6 | import { IApiOperationPostArgs } from './api-operation-post.decorator';
7 | import { IApiPathArgs } from './api-path.decorator';
8 | import {
9 | IApiBodyOperationArgsBaseParameter,
10 | IApiOperationArgsBase,
11 | IApiOperationArgsBaseParameter,
12 | IApiOperationArgsBaseResponse,
13 | } from './i-api-operation-args.base';
14 | import {
15 | ISwagger,
16 | ISwaggerDefinition,
17 | ISwaggerDefinitionProperty,
18 | ISwaggerDefinitionPropertyItems,
19 | ISwaggerExternalDocs,
20 | ISwaggerInfo,
21 | ISwaggerOperation,
22 | ISwaggerOperationParameter,
23 | ISwaggerOperationResponse,
24 | ISwaggerOperationSchema,
25 | ISwaggerOperationSchemaItems,
26 | ISwaggerPath,
27 | ISwaggerPropertySchemaOperation,
28 | ISwaggerTag,
29 | } from './i-swagger';
30 | import { SwaggerDefinitionConstant } from './swagger-definition.constant';
31 | import {
32 | ISwaggerBuildDefinitionModel,
33 | ISwaggerBuildDefinitionModelProperty,
34 | ISwaggerSecurityDefinition,
35 | } from './swagger.builder';
36 |
37 | interface IPath {
38 | path: string;
39 | get?: ISwaggerOperation;
40 | post?: ISwaggerOperation;
41 | put?: ISwaggerOperation;
42 | patch?: ISwaggerOperation;
43 | delete?: ISwaggerOperation;
44 | }
45 |
46 | interface IController {
47 | path?: string;
48 | paths?: { [key: string]: IPath };
49 | name?: string;
50 | description?: string;
51 | security?: { [key: string]: any[] };
52 | deprecated?: boolean;
53 | }
54 |
55 | export class SwaggerService {
56 | public static getInstance(): SwaggerService {
57 | if (!SwaggerService.instance) {
58 | const newSwaggerService: SwaggerService = new SwaggerService();
59 | newSwaggerService.initData();
60 | SwaggerService.instance = newSwaggerService;
61 | }
62 | return SwaggerService.instance;
63 | }
64 | private static instance: SwaggerService;
65 | private controllerMap: { [key: string]: IController } = {};
66 | private data: ISwagger;
67 | private modelsMap: { [key: string]: ISwaggerBuildDefinitionModel } = {};
68 | private globalResponses: { [key: string]: IApiOperationArgsBaseResponse };
69 |
70 | public resetData(): void {
71 | this.controllerMap = {};
72 | this.initData();
73 | }
74 |
75 | public getData(): ISwagger {
76 | return _.cloneDeep(this.data);
77 | }
78 |
79 | public setBasePath(basePath: string): void {
80 | this.data.basePath = basePath;
81 | }
82 |
83 | public setOpenapi(openapi: string): void {
84 | this.data.openapi = openapi;
85 | }
86 |
87 | public setInfo(info: ISwaggerInfo): void {
88 | this.data.info = info;
89 | }
90 |
91 | public setSchemes(schemes: string[]): void {
92 | this.data.schemes = schemes;
93 | }
94 |
95 | public setProduces(produces: string[]): void {
96 | this.data.produces = produces;
97 | }
98 |
99 | public setConsumes(consumes: string[]): void {
100 | this.data.consumes = consumes;
101 | }
102 |
103 | public setHost(host: string): void {
104 | this.data.host = host;
105 | }
106 |
107 | public setDefinitions(models: {
108 | [key: string]: ISwaggerBuildDefinitionModel;
109 | }): void {
110 | const definitions: { [key: string]: ISwaggerDefinition } = {};
111 | for (const modelIndex in models) {
112 | const model: ISwaggerBuildDefinitionModel = models[modelIndex];
113 | const newDefinition: ISwaggerDefinition = {
114 | type: SwaggerDefinitionConstant.Model.Type.OBJECT,
115 | properties: {},
116 | required: [],
117 | };
118 | if (model.description) {
119 | newDefinition.description = model.description;
120 | }
121 | for (const propertyIndex in model.properties) {
122 | const property: ISwaggerBuildDefinitionModelProperty =
123 | model.properties[propertyIndex];
124 | const newProperty: ISwaggerDefinitionProperty = {
125 | type: property.type,
126 | };
127 | newProperty.format = property.format;
128 | newProperty.description = property.description;
129 | newProperty.enum = property.enum;
130 | newProperty.example = property.example;
131 | if (property.itemType) {
132 | newProperty.items = {
133 | type: property.itemType,
134 | } as ISwaggerDefinitionPropertyItems;
135 | }
136 | if (property.model) {
137 | if (
138 | _.isEqual(
139 | SwaggerDefinitionConstant.Model.Property.Type.ARRAY,
140 | property.type
141 | )
142 | ) {
143 | newProperty.items = {
144 | $ref: this.buildRef(property.model),
145 | } as ISwaggerDefinitionPropertyItems;
146 | } else {
147 | newProperty.$ref = this.buildRef(property.model);
148 | }
149 | }
150 | if (property.required) {
151 | newDefinition.required.push(propertyIndex);
152 | }
153 | newDefinition.properties[propertyIndex] = newProperty;
154 | }
155 | definitions[modelIndex] = newDefinition;
156 | }
157 | this.data.definitions = _.mergeWith(this.data.definitions, definitions);
158 | }
159 |
160 | public setExternalDocs(externalDocs: ISwaggerExternalDocs): void {
161 | this.data.externalDocs = externalDocs;
162 | }
163 |
164 | public setGlobalResponses(globalResponses: {
165 | [key: string]: IApiOperationArgsBaseResponse;
166 | }): void {
167 | this.globalResponses = this.buildOperationResponses(globalResponses);
168 | }
169 |
170 | public addPath(args: IApiPathArgs, target: any): void {
171 | let currentController: IController = {
172 | path: args.path,
173 | name: args.name,
174 | paths: {},
175 | };
176 | for (const controllerIndex in this.controllerMap) {
177 | const controller: IController = this.controllerMap[controllerIndex];
178 | if (controllerIndex === target.name) {
179 | currentController = controller;
180 | currentController.path = args.path;
181 | currentController.name = args.name;
182 | currentController.description = args.description;
183 | currentController.security = args.security;
184 | currentController.deprecated = args.deprecated;
185 | }
186 | }
187 | this.controllerMap[target.name] = _.mergeWith(
188 | this.controllerMap[target.name],
189 | currentController
190 | );
191 | }
192 |
193 | public addOperationGet(
194 | args: IApiOperationGetArgs,
195 | target: any,
196 | propertyKey: string | symbol
197 | ): void {
198 | assert.ok(args, 'Args are required.');
199 | assert.ok(args.responses, 'Responses are required.');
200 | if (args.parameters) {
201 | assert.ok(!args.parameters.body, 'Parameter body is not required.');
202 | }
203 | this.addOperation('get', args, target, propertyKey);
204 | }
205 |
206 | public addOperationPost(
207 | args: IApiOperationPostArgs,
208 | target: any,
209 | propertyKey: string | symbol
210 | ): void {
211 | assert.ok(args, 'Args are required.');
212 | assert.ok(args.parameters, 'Parameters are required.');
213 | assert.ok(args.responses, 'Responses are required.');
214 | this.addOperation('post', args, target, propertyKey);
215 | }
216 |
217 | public addOperationPut(
218 | args: IApiOperationPostArgs,
219 | target: any,
220 | propertyKey: string | symbol
221 | ): void {
222 | assert.ok(args, 'Args are required.');
223 | assert.ok(args.parameters, 'Parameters are required.');
224 | assert.ok(args.responses, 'Responses are required.');
225 | this.addOperation('put', args, target, propertyKey);
226 | }
227 |
228 | public addOperationPatch(
229 | args: IApiOperationPostArgs,
230 | target: any,
231 | propertyKey: string | symbol
232 | ): void {
233 | assert.ok(args, 'Args are required.');
234 | assert.ok(args.parameters, 'Parameters are required.');
235 | assert.ok(args.responses, 'Responses are required.');
236 | this.addOperation('patch', args, target, propertyKey);
237 | }
238 |
239 | public addOperationDelete(
240 | args: IApiOperationPostArgs,
241 | target: any,
242 | propertyKey: string | symbol
243 | ): void {
244 | assert.ok(args, 'Args are required.');
245 | assert.ok(args.parameters, 'Parameters are required.');
246 | assert.ok(!args.parameters.body, 'Parameter body is not required.');
247 | assert.ok(args.responses, 'Responses are required.');
248 | this.addOperation('delete', args, target, propertyKey);
249 | }
250 |
251 | public addSecurityDefinitions(securityDefinitions: {
252 | [key: string]: ISwaggerSecurityDefinition;
253 | }): void {
254 | this.data.securityDefinitions = securityDefinitions;
255 | }
256 |
257 | public buildSwagger(): void {
258 | const data: ISwagger = _.cloneDeep(this.data);
259 | for (const controllerIndex in this.controllerMap) {
260 | const controller: IController = this.controllerMap[controllerIndex];
261 | if (_.toArray(controller.paths).length > 0) {
262 | for (const pathIndex in controller.paths) {
263 | const path: IPath = controller.paths[pathIndex];
264 | const swaggerPath: ISwaggerPath = {};
265 | if (path.get) {
266 | swaggerPath.get = this.buildSwaggerOperation(
267 | path.get,
268 | controller
269 | );
270 | }
271 | if (path.post) {
272 | swaggerPath.post = this.buildSwaggerOperation(
273 | path.post,
274 | controller
275 | );
276 | }
277 | if (path.put) {
278 | swaggerPath.put = this.buildSwaggerOperation(
279 | path.put,
280 | controller
281 | );
282 | }
283 | if (path.patch) {
284 | swaggerPath.patch = this.buildSwaggerOperation(
285 | path.patch,
286 | controller
287 | );
288 | }
289 | if (path.delete) {
290 | swaggerPath.delete = this.buildSwaggerOperation(
291 | path.delete,
292 | controller
293 | );
294 | }
295 | if (path.path && path.path.length > 0) {
296 | data.paths[controller.path.concat(path.path)] = {...data.paths[controller.path.concat(path.path)],...swaggerPath};
297 | } else {
298 | data.paths[controller.path] = swaggerPath;
299 | }
300 | }
301 | } else {
302 | const swaggerPath: ISwaggerPath = {};
303 | data.paths[controller.path] = swaggerPath;
304 | }
305 |
306 | if (!_.find(data.tags, (tag: ISwaggerTag) => tag.name === _.upperFirst(controller.name))) {
307 | data.tags.push({
308 | name: _.upperFirst(controller.name),
309 | description: controller.description,
310 | } as ISwaggerTag);
311 | }
312 | }
313 | this.data = data;
314 | }
315 |
316 | public addApiModelProperty(
317 | args: IApiModelPropertyArgs,
318 | target: any,
319 | propertyKey: string | symbol,
320 | propertyType: string
321 | ) {
322 | const definitionKey = target.constructor.name;
323 | let swaggerBuildDefinitionModel: ISwaggerBuildDefinitionModel = this
324 | .modelsMap[definitionKey];
325 | if (!swaggerBuildDefinitionModel) {
326 | swaggerBuildDefinitionModel = {
327 | properties: {},
328 | };
329 | this.modelsMap[definitionKey] = swaggerBuildDefinitionModel;
330 | }
331 |
332 | const swaggerBuildDefinitionModelProperty: ISwaggerBuildDefinitionModelProperty = {
333 | type: _.lowerCase(propertyType),
334 | };
335 | if (args) {
336 | swaggerBuildDefinitionModelProperty.required = args.required;
337 | swaggerBuildDefinitionModelProperty.description = args.description;
338 | swaggerBuildDefinitionModelProperty.enum = args.enum;
339 | swaggerBuildDefinitionModelProperty.itemType = args.itemType;
340 | swaggerBuildDefinitionModelProperty.example = args.example;
341 | swaggerBuildDefinitionModelProperty.format = args.format;
342 | if (args.model) {
343 | swaggerBuildDefinitionModelProperty.model = args.model;
344 | if (!_.isEqual('Array', propertyType)) {
345 | swaggerBuildDefinitionModelProperty.type = undefined;
346 | }
347 | }
348 | if (args.type) {
349 | swaggerBuildDefinitionModelProperty.type = args.type;
350 | }
351 | }
352 | swaggerBuildDefinitionModel.properties[
353 | propertyKey.toString()
354 | ] = swaggerBuildDefinitionModelProperty;
355 | this.setDefinitions(this.modelsMap);
356 | }
357 |
358 | public addApiModel(args: IApiModelArgs, target: any): any {
359 | const definitionKey = target.name;
360 | let swaggerBuildDefinitionModel: ISwaggerBuildDefinitionModel = this
361 | .modelsMap[definitionKey];
362 | if (!swaggerBuildDefinitionModel) {
363 | swaggerBuildDefinitionModel = {
364 | properties: {},
365 | };
366 | this.modelsMap[definitionKey] = swaggerBuildDefinitionModel;
367 | }
368 | if (args) {
369 | swaggerBuildDefinitionModel.description = args.description;
370 | if (args.name) {
371 | const name: string = _.upperFirst(args.name);
372 | this.modelsMap[name] = _.cloneDeep(
373 | this.modelsMap[definitionKey]
374 | );
375 | if (!_.isEqual(name, definitionKey)) {
376 | delete this.modelsMap[definitionKey];
377 | delete this.data.definitions[definitionKey];
378 | }
379 | }
380 | }
381 | this.setDefinitions(this.modelsMap);
382 | }
383 |
384 | private initData(): void {
385 | this.data = {
386 | basePath: '/',
387 | info: {
388 | title: '',
389 | version: '',
390 | } as ISwaggerInfo,
391 | paths: {},
392 | tags: [],
393 | schemes: [SwaggerDefinitionConstant.Scheme.HTTP],
394 | produces: [SwaggerDefinitionConstant.Produce.JSON],
395 | consumes: [SwaggerDefinitionConstant.Consume.JSON],
396 | definitions: {},
397 | swagger: '2.0',
398 | };
399 | }
400 |
401 | private addOperation(
402 | operation: string,
403 | args: IApiOperationArgsBase,
404 | target: any,
405 | propertyKey: string | symbol
406 | ): void {
407 | let currentController: IController = {
408 | paths: {},
409 | };
410 | for (const index in this.controllerMap) {
411 | const controller = this.controllerMap[index];
412 | if (index === target.constructor.name) {
413 | currentController = controller;
414 | }
415 | }
416 |
417 | let currentPath: IPath;
418 | if (args.path && args.path.length > 0) {
419 | if (!currentController.paths[args.path]) {
420 | currentController.paths[args.path] = {} as IPath;
421 | }
422 | currentPath = currentController.paths[args.path];
423 | currentPath.path = args.path;
424 | } else {
425 | if (!currentController.paths['/']) {
426 | currentController.paths['/'] = {} as IPath;
427 | }
428 | currentPath = currentController.paths['/'];
429 | }
430 |
431 | if ('get' === operation) {
432 | currentPath.get = this.buildOperation(args, target, propertyKey);
433 | }
434 |
435 | if ('post' === operation) {
436 | currentPath.post = this.buildOperation(args, target, propertyKey);
437 | }
438 |
439 | if ('put' === operation) {
440 | currentPath.put = this.buildOperation(args, target, propertyKey);
441 | }
442 |
443 | if ('patch' === operation) {
444 | currentPath.patch = this.buildOperation(args, target, propertyKey);
445 | }
446 |
447 | if ('delete' === operation) {
448 | currentPath.delete = this.buildOperation(args, target, propertyKey);
449 | }
450 |
451 | this.controllerMap[target.constructor.name] = currentController;
452 | }
453 |
454 | private buildOperation(
455 | args: IApiOperationArgsBase,
456 | target: any,
457 | propertyKey: string | symbol
458 | ): ISwaggerOperation {
459 | const operation: ISwaggerOperation = {
460 | operationId: propertyKey,
461 | tags: [],
462 | };
463 | if (args.description) {
464 | operation.description = args.description;
465 | }
466 | if (args.summary) {
467 | operation.summary = args.summary;
468 | }
469 | if (args.produces && args.produces.length > 0) {
470 | operation.produces = args.produces;
471 | }
472 |
473 | if (args.consumes && args.consumes.length > 0) {
474 | operation.consumes = args.consumes;
475 | }
476 |
477 | if (args.tags && args.tags.length > 0) {
478 | operation.tags = args.tags;
479 | }
480 |
481 | if (args.deprecated) {
482 | operation.deprecated = args.deprecated;
483 | }
484 |
485 | if (args.parameters) {
486 | operation.parameters = [];
487 | if (args.parameters.header) {
488 | operation.parameters = _.concat(
489 | operation.parameters,
490 | this.buildParameters(
491 | SwaggerDefinitionConstant.Parameter.In.HEADER,
492 | args.parameters.header
493 | )
494 | );
495 | }
496 | if (args.parameters.path) {
497 | operation.parameters = _.concat(
498 | operation.parameters,
499 | this.buildParameters(
500 | SwaggerDefinitionConstant.Parameter.In.PATH,
501 | args.parameters.path
502 | )
503 | );
504 | }
505 | if (args.parameters.query) {
506 | operation.parameters = _.concat(
507 | operation.parameters,
508 | this.buildParameters(
509 | SwaggerDefinitionConstant.Parameter.In.QUERY,
510 | args.parameters.query
511 | )
512 | );
513 | }
514 | if (args.parameters.body) {
515 | operation.parameters = _.concat(
516 | operation.parameters,
517 | this.buildBodyOperationParameter(args.parameters.body)
518 | );
519 | }
520 | if (args.parameters.formData) {
521 | operation.parameters = _.concat(
522 | operation.parameters,
523 | this.buildParameters(
524 | SwaggerDefinitionConstant.Parameter.In.FORM_DATA,
525 | args.parameters.formData
526 | )
527 | );
528 | }
529 | }
530 |
531 | if (args.responses) {
532 | operation.responses = this.buildOperationResponses(args.responses);
533 | }
534 |
535 | if (args.security) {
536 | operation.security = this.buildOperationSecurity(args.security);
537 | }
538 |
539 | return operation;
540 | }
541 |
542 | private buildOperationResponses(responses: {
543 | [key: string]: IApiOperationArgsBaseResponse;
544 | }): {
545 | [key: string]: ISwaggerOperationResponse;
546 | } {
547 | const swaggerOperationResponses: {
548 | [key: string]: ISwaggerOperationResponse;
549 | } = {};
550 | for (const responseIndex in responses) {
551 | const response: IApiOperationArgsBaseResponse =
552 | responses[responseIndex];
553 | const newSwaggerOperationResponse: ISwaggerOperationResponse = {};
554 | if (response.description) {
555 | newSwaggerOperationResponse.description = response.description;
556 | } else {
557 | switch (responseIndex) {
558 | case '200':
559 | newSwaggerOperationResponse.description = 'Success';
560 | break;
561 | case '201':
562 | newSwaggerOperationResponse.description = 'Created';
563 | break;
564 | case '202':
565 | newSwaggerOperationResponse.description = 'Accepted';
566 | break;
567 | case '203':
568 | newSwaggerOperationResponse.description =
569 | 'Non-Authoritative Information';
570 | break;
571 | case '204':
572 | newSwaggerOperationResponse.description = 'No Content';
573 | break;
574 | case '205':
575 | newSwaggerOperationResponse.description =
576 | 'Reset Content';
577 | break;
578 | case '206':
579 | newSwaggerOperationResponse.description =
580 | 'Partial Content';
581 | break;
582 | case '400':
583 | newSwaggerOperationResponse.description =
584 | 'Client error and Bad Request';
585 | break;
586 | case '401':
587 | newSwaggerOperationResponse.description =
588 | 'Client error and Unauthorized';
589 | break;
590 | case '404':
591 | newSwaggerOperationResponse.description =
592 | 'Client error and Not Found';
593 | break;
594 | case '406':
595 | newSwaggerOperationResponse.description =
596 | 'Client error and Not Acceptable';
597 | break;
598 | case '500':
599 | newSwaggerOperationResponse.description =
600 | 'Internal Server Error';
601 | break;
602 | case '501':
603 | newSwaggerOperationResponse.description =
604 | 'Not Implemented';
605 | break;
606 | case '503':
607 | newSwaggerOperationResponse.description =
608 | 'Service Unavailable';
609 | break;
610 | default:
611 | newSwaggerOperationResponse.description = null;
612 | }
613 | }
614 | if (response.model) {
615 | const ref = this.buildRef(response.model);
616 | let newSwaggerOperationResponseSchema: ISwaggerOperationSchema = {
617 | $ref: ref,
618 | };
619 | if (
620 | _.isEqual(
621 | response.type,
622 | SwaggerDefinitionConstant.Response.Type.ARRAY
623 | )
624 | ) {
625 | newSwaggerOperationResponseSchema = {
626 | items: {
627 | $ref: ref,
628 | } as ISwaggerOperationSchemaItems,
629 | type: SwaggerDefinitionConstant.Response.Type.ARRAY,
630 | };
631 | }
632 | newSwaggerOperationResponse.schema = newSwaggerOperationResponseSchema;
633 | }
634 | swaggerOperationResponses[
635 | responseIndex
636 | ] = newSwaggerOperationResponse;
637 | }
638 | return swaggerOperationResponses;
639 | }
640 |
641 | private buildBodyOperationParameter(
642 | bodyOperationArgsBaseParameter: IApiBodyOperationArgsBaseParameter
643 | ): ISwaggerOperationParameter[] {
644 | const swaggerOperationParameterList: ISwaggerOperationParameter[] = [];
645 | const swaggerOperationParameter = {} as ISwaggerOperationParameter;
646 | swaggerOperationParameter.name = bodyOperationArgsBaseParameter.name
647 | ? bodyOperationArgsBaseParameter.name
648 | : 'body';
649 | swaggerOperationParameter.in = 'body';
650 | swaggerOperationParameter.type = bodyOperationArgsBaseParameter.type;
651 | swaggerOperationParameter.description =
652 | bodyOperationArgsBaseParameter.description;
653 | swaggerOperationParameter.required =
654 | bodyOperationArgsBaseParameter.required;
655 | swaggerOperationParameter.format =
656 | bodyOperationArgsBaseParameter.format;
657 | swaggerOperationParameter.deprecated =
658 | bodyOperationArgsBaseParameter.deprecated;
659 | swaggerOperationParameter.allowEmptyValue =
660 | bodyOperationArgsBaseParameter.allowEmptyValue;
661 | swaggerOperationParameter.minimum =
662 | bodyOperationArgsBaseParameter.minimum;
663 | swaggerOperationParameter.maximum =
664 | bodyOperationArgsBaseParameter.maximum;
665 | swaggerOperationParameter.default =
666 | bodyOperationArgsBaseParameter.default;
667 | let schema = {} as ISwaggerOperationSchema;
668 | if (bodyOperationArgsBaseParameter.properties) {
669 | schema.type = 'object';
670 | schema.required = [];
671 | schema.properties = {} as {
672 | [key: string]: ISwaggerPropertySchemaOperation;
673 | };
674 | for (const propetyIndex in bodyOperationArgsBaseParameter.properties) {
675 | const propertyBodyOperationArgsBaseParameter =
676 | bodyOperationArgsBaseParameter.properties[propetyIndex];
677 | const propertySchemaOperation = {} as ISwaggerPropertySchemaOperation;
678 | propertySchemaOperation.type =
679 | propertyBodyOperationArgsBaseParameter.type;
680 | schema.properties[propetyIndex] = propertySchemaOperation;
681 | if (propertyBodyOperationArgsBaseParameter.required) {
682 | schema.required.push(propetyIndex);
683 | }
684 | }
685 | }
686 | if (bodyOperationArgsBaseParameter.model) {
687 | const swaggerOperationSchema: ISwaggerOperationSchema = {
688 | $ref: this.buildRef(bodyOperationArgsBaseParameter.model),
689 | };
690 |
691 | if (bodyOperationArgsBaseParameter.type !== 'array') {
692 | schema = swaggerOperationSchema;
693 | } else {
694 | schema.type = bodyOperationArgsBaseParameter.type;
695 | schema.items = {
696 | $ref: this.buildRef(bodyOperationArgsBaseParameter.model),
697 | };
698 | }
699 | }
700 | swaggerOperationParameter.schema = schema;
701 | swaggerOperationParameterList.push(swaggerOperationParameter);
702 | return swaggerOperationParameterList;
703 | }
704 |
705 | private buildOperationSecurity(argsSecurity: {
706 | [key: string]: any[];
707 | }): { [key: string]: any[] }[] {
708 | const securityToReturn = [];
709 | for (const securityIndex in argsSecurity) {
710 | const security: any[] = argsSecurity[securityIndex];
711 | const result: { [key: string]: any[] } = {};
712 | result[securityIndex] = security;
713 | securityToReturn.push(result);
714 | }
715 | return securityToReturn;
716 | }
717 |
718 | private buildParameters(
719 | type: string,
720 | parameters: { [key: string]: IApiOperationArgsBaseParameter }
721 | ): ISwaggerOperationParameter[] {
722 | const swaggerOperationParameter: ISwaggerOperationParameter[] = [];
723 | for (const parameterIndex in parameters) {
724 | const parameter: IApiOperationArgsBaseParameter =
725 | parameters[parameterIndex];
726 | const newSwaggerOperationParameter: ISwaggerOperationParameter = {
727 | name: parameterIndex,
728 | in: type,
729 | type: parameter.type,
730 | items: parameter.items
731 | };
732 | if (parameter.name) {
733 | newSwaggerOperationParameter.name = parameter.name;
734 | }
735 | newSwaggerOperationParameter.description = parameter.description;
736 | newSwaggerOperationParameter.required = parameter.required;
737 | newSwaggerOperationParameter.format = parameter.format;
738 | newSwaggerOperationParameter.deprecated = parameter.deprecated;
739 | newSwaggerOperationParameter.allowEmptyValue =
740 | parameter.allowEmptyValue;
741 | newSwaggerOperationParameter.minimum = parameter.minimum;
742 | newSwaggerOperationParameter.maximum = parameter.maximum;
743 | newSwaggerOperationParameter.default = parameter.default;
744 | swaggerOperationParameter.push(newSwaggerOperationParameter);
745 | }
746 | return swaggerOperationParameter;
747 | }
748 |
749 | private buildSwaggerOperation(
750 | operation: ISwaggerOperation,
751 | controller: IController
752 | ): ISwaggerOperation {
753 | if (_.isUndefined(operation.produces)) {
754 | operation.produces = this.data.produces;
755 | }
756 | if (_.isUndefined(operation.consumes)) {
757 | operation.consumes = this.data.consumes;
758 | }
759 | if (_.isUndefined(operation.security) && controller.security) {
760 | operation.security = this.buildOperationSecurity(
761 | controller.security
762 | );
763 | }
764 | if (_.isUndefined(operation.deprecated) && controller.deprecated) {
765 | operation.deprecated = controller.deprecated;
766 | }
767 | if (this.globalResponses) {
768 | operation.responses = _.mergeWith(
769 | _.cloneDeep(this.globalResponses),
770 | operation.responses
771 | );
772 | }
773 | if (operation.tags && operation.tags.length > 0) {
774 | operation.tags.unshift(_.upperFirst(controller.name));
775 | } else {
776 | operation.tags = [_.upperFirst(controller.name)];
777 | }
778 | return operation;
779 | }
780 |
781 | private buildRef(definition: string): string {
782 | return '#/definitions/'.concat(_.upperFirst(definition));
783 | }
784 | }
785 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "swagger-express-ts",
3 | "version": "1.1.1",
4 | "description": "Generate and serve swagger.json",
5 | "main": "index.js",
6 | "types": "index.d.ts",
7 | "typings": "index.d.ts",
8 | "scripts": {
9 | "build:lib": "echo \"Building lib...\" && gulp build:lib",
10 | "build": "echo \"Building...\" && gulp build",
11 | "clean": "echo \"Cleaning...\" && gulp clean",
12 | "test": "echo \"Testing...\" && npm run build && nyc mocha",
13 | "dev": "echo \"Developing...\" && nodemon",
14 | "start": "echo \"Starting...\" && npm run build && ts-node --project tsconfig.json src/index.ts",
15 | "publish": "npm publish dist",
16 | "prepare": "npm run build:lib"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/olivierlsc/swagger-express-ts.git"
21 | },
22 | "author": "Olivier LIN-SI-CHENG",
23 | "license": "MIT",
24 | "keywords": [
25 | "inversify",
26 | "inversifyjs",
27 | "swagger",
28 | "swagger2",
29 | "swagger-ui",
30 | "typescript",
31 | "expressjs",
32 | "express",
33 | "api rest",
34 | "documentation",
35 | "decorator",
36 | "generator",
37 | "swagger.json",
38 | "json",
39 | "rest"
40 | ],
41 | "bugs": {
42 | "url": "https://github.com/olivierlsc/swagger-express-ts/issues"
43 | },
44 | "homepage": "https://github.com/olivierlsc/swagger-express-ts#readme",
45 | "dependencies": {
46 | "@types/body-parser": "^1.19.0",
47 | "@types/compression": "1.7.0",
48 | "@types/express": "^4.17.12",
49 | "@types/helmet": "0.0.48",
50 | "@types/inversify": "^2.0.33",
51 | "@types/lodash": "^4.14.170",
52 | "body-parser": "^1.19.0",
53 | "compression": "^1.7.4",
54 | "express": "^4.17.1",
55 | "helmet": "^4.6.0",
56 | "inversify": "^4.13.0",
57 | "inversify-express-utils": "^4.2.2",
58 | "lodash": "^4.17.21",
59 | "reflect-metadata": "^0.1.13",
60 | "save": "^2.4.0"
61 | },
62 | "devDependencies": {
63 | "@types/chai": "^4.2.18",
64 | "@types/mocha": "^8.2.2",
65 | "@types/sinon": "^9.0.11",
66 | "chai": "^4.3.4",
67 | "gulp": "^4.0.2",
68 | "gulp-clean": "^0.4.0",
69 | "gulp-sourcemaps": "^3.0.0",
70 | "gulp-tslint": "^8.1.4",
71 | "gulp-typescript": "^5.0.1",
72 | "mocha": "^8.4.0",
73 | "nodemon": "^2.0.7",
74 | "nyc": "^15.1.0",
75 | "prettier": "2.2.1",
76 | "pretty-quick": "^3.1.1",
77 | "rimraf": "^3.0.2",
78 | "sinon": "^10.0.0",
79 | "source-map-support": "^0.5.19",
80 | "swagger-ui-dist": "^3.50.0",
81 | "ts-node": "^9.1.1",
82 | "tslint": "^6.1.3",
83 | "tslint-config-prettier": "^1.18.0",
84 | "typescript": "^4.3.4"
85 | },
86 | "nyc": {
87 | "include": [
88 | "src/**/*.ts",
89 | "lib/swagger-express-ts-lib/src/**/*.ts"
90 | ],
91 | "exclude": [
92 | "src/index.ts"
93 | ],
94 | "extension": [
95 | ".ts"
96 | ],
97 | "require": [
98 | "ts-node/register"
99 | ],
100 | "reporter": [
101 | "html",
102 | "cobertura"
103 | ],
104 | "sourceMap": true,
105 | "instrument": true
106 | },
107 | "nodemonConfig": {
108 | "restartable": "rs",
109 | "watch": [
110 | "src/**/*.ts",
111 | "lib/**/*.ts"
112 | ],
113 | "ext": "ts",
114 | "ignore": [
115 | "test/*",
116 | "wiki/*",
117 | "swagger/*",
118 | "node_modules/*",
119 | "dist/*"
120 | ],
121 | "delay": "2500",
122 | "exec": "gulp build && ts-node --project tsconfig.json src/index.ts"
123 | },
124 | "husky": {
125 | "hooks": {
126 | "pre-commit": "pretty-quick --staged"
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/cars/car.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import * as chai from 'chai';
2 | import { CarController } from './car.controller';
3 | import { CarsService } from './cars.service';
4 | const expect = chai.expect;
5 | import * as express from 'express';
6 | import * as sinon from 'sinon';
7 | import { CarModel } from './car.model';
8 |
9 | describe('CarController', () => {
10 | let carController: CarController;
11 | let carService: CarsService;
12 |
13 | beforeEach(() => {
14 | carService = {} as CarsService;
15 | carController = new CarController(carService);
16 | });
17 |
18 | describe('getCar', () => {
19 | it('expect car', () => {
20 | const request: express.Request = null;
21 | const response: express.Response = {} as express.Response;
22 | const next: express.NextFunction = null;
23 | const id: string = '1';
24 | const car: CarModel = {} as CarModel;
25 | const carsServiceGetCarByIdStub = sinon.stub().returns(car);
26 | carService.getCarById = carsServiceGetCarByIdStub;
27 | const responseJsonSpy = sinon.spy();
28 | response.json = responseJsonSpy;
29 |
30 | carController.getCar(id, request, response, next);
31 |
32 | expect(carsServiceGetCarByIdStub.called).is.true;
33 | expect(responseJsonSpy.calledWith(car)).is.true;
34 | });
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/src/cars/car.controller.ts:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import 'reflect-metadata';
3 | import {
4 | interfaces,
5 | controller,
6 | httpGet,
7 | requestParam,
8 | } from 'inversify-express-utils';
9 | import {
10 | ApiPath,
11 | SwaggerDefinitionConstant,
12 | ApiOperationGet,
13 | } from 'swagger-express-ts';
14 | import * as express from 'express';
15 | import { CarsService } from './cars.service';
16 |
17 | @ApiPath({
18 | name: 'Cars',
19 | path: '/cars/{id}',
20 | })
21 | @controller('/cars/:id')
22 | @injectable()
23 | export class CarController implements interfaces.Controller {
24 | constructor(
25 | @inject(CarsService.name) private carsService: CarsService
26 | ) {}
27 |
28 | @ApiOperationGet({
29 | description: 'Get car object',
30 | parameters: {
31 | header: {
32 | 'x-custom-header': {
33 | required: true,
34 | type: SwaggerDefinitionConstant.Parameter.Type.STRING,
35 | },
36 | },
37 | path: {
38 | id: {
39 | required: true,
40 | type: SwaggerDefinitionConstant.Parameter.Type.STRING,
41 | },
42 | },
43 | },
44 | responses: {
45 | 200: {
46 | model: 'Car',
47 | },
48 | 400: {},
49 | },
50 | })
51 | @httpGet('/')
52 | public getCar(
53 | @requestParam('id') id: string,
54 | request: express.Request,
55 | response: express.Response,
56 | next: express.NextFunction
57 | ): void {
58 | response.json(this.carsService.getCarById(id));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/cars/car.model.ts:
--------------------------------------------------------------------------------
1 | import { ApiModel, ApiModelProperty } from 'swagger-express-ts';
2 | import { ConstructorModel } from '../constructors/constructor.model';
3 | import { WheelModel } from './wheel.model';
4 |
5 | @ApiModel({
6 | description: 'Car description',
7 | name: 'Car',
8 | })
9 | export class CarModel {
10 | @ApiModelProperty({
11 | description: 'Id of car',
12 | required: true,
13 | example: ['123456789', '12345'],
14 | })
15 | public id: string;
16 |
17 | @ApiModelProperty({
18 | description: '',
19 | required: true,
20 | })
21 | public name: string;
22 |
23 | @ApiModelProperty({
24 | description: 'Description of car',
25 | required: true,
26 | })
27 | public description: string;
28 |
29 | @ApiModelProperty({
30 | description: 'Constructor of car',
31 | model: 'Constructor',
32 | })
33 | public author: ConstructorModel;
34 |
35 | @ApiModelProperty({
36 | description: 'Wheel car has. This is to demonstarte a cicrular reference works.',
37 | required: true,
38 | model: 'Wheel'
39 | })
40 | public wheel: WheelModel | undefined;
41 | }
42 |
--------------------------------------------------------------------------------
/src/cars/carbulk.controller.ts:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import 'reflect-metadata';
3 | import { interfaces, controller, httpPost, httpGet } from 'inversify-express-utils';
4 | import { ApiPath, ApiOperationPost, ApiOperationGet, SwaggerDefinitionConstant } from 'swagger-express-ts';
5 | import * as express from 'express';
6 | import { CarsService } from './cars.service';
7 |
8 | @ApiPath({
9 | name: 'Cars',
10 | path: '/cars-bulk',
11 | })
12 | @controller('/cars-bulk')
13 | @injectable()
14 | export class CarBulkController implements interfaces.Controller {
15 | constructor(@inject(CarsService.name) private carsService: CarsService) {}
16 |
17 | @ApiOperationPost({
18 | description: 'Post car objects',
19 | summary: 'Post new cars',
20 | parameters: {
21 | body: {
22 | description: 'New car',
23 | required: true,
24 | model: 'Car',
25 | type: 'array',
26 | },
27 | },
28 | responses: {
29 | 200: {
30 | model: 'Car',
31 | },
32 | 400: { description: 'Parameters fail' },
33 | },
34 | })
35 | @httpPost('/')
36 | public postBulkCar(
37 | request: express.Request,
38 | response: express.Response
39 | ): void {
40 | if (!request.body) {
41 | return response.status(400).end();
42 | }
43 |
44 | response.json(request.body);
45 | }
46 |
47 | @ApiOperationGet({
48 | description: 'Get cars objects list by ids',
49 | summary: 'Get cars list by ids',
50 | parameters: {
51 | query: {
52 | ids: {
53 | type: 'array',
54 | required: true,
55 | items: {
56 | type: 'string'
57 | }
58 | }
59 | },
60 | },
61 | responses: {
62 | 200: {
63 | type: SwaggerDefinitionConstant.Response.Type.ARRAY,
64 | model: 'Car',
65 | },
66 | },
67 | security: {
68 | apiKeyHeader: [],
69 | },
70 | })
71 | @httpGet('/')
72 | public getCarsByIds(
73 | request: express.Request,
74 | response: express.Response
75 | ): void {
76 | response.json(this.carsService.getCarsByIds(request.query.ids as string[]));
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/cars/cars.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import * as chai from 'chai';
2 | import { CarsController } from './cars.controller';
3 | import { CarsService } from './cars.service';
4 | const expect = chai.expect;
5 | import * as express from 'express';
6 | import * as sinon from 'sinon';
7 | import { CarModel } from './car.model';
8 |
9 | describe('CarsController', () => {
10 | let carsController: CarsController;
11 | let carsService: CarsService;
12 |
13 | beforeEach(() => {
14 | carsService = {} as CarsService;
15 | carsController = new CarsController(carsService);
16 | });
17 | describe('GET:/cars', () => {
18 | it('expect cars list', () => {
19 | let request: express.Request;
20 | const response: express.Response = {} as express.Response;
21 | let next: express.NextFunction;
22 | const carsList: CarModel[] = [];
23 | const carsServiceGetCarsStub = sinon
24 | .stub()
25 | .returns(carsList);
26 | carsService.getCars = carsServiceGetCarsStub;
27 | const responseJsonSpy = sinon.spy();
28 | response.json = responseJsonSpy;
29 |
30 | carsController.getCars(request, response, next);
31 |
32 | expect(carsServiceGetCarsStub.called).is.true;
33 | expect(responseJsonSpy.calledWith(carsList)).is.true;
34 | });
35 | });
36 |
37 | describe('POST:/cars', () => {
38 | it('expect post car', () => {
39 | const request: express.Request = {} as express.Request;
40 | const response: express.Response = {} as express.Response;
41 | let next: express.NextFunction;
42 | const car: CarModel = {} as CarModel;
43 | const carsServiceAddCarStub = sinon.stub().returns(car);
44 | carsService.addCar = carsServiceAddCarStub;
45 | const responseJsonSpy = sinon.spy();
46 | response.json = responseJsonSpy;
47 | request.body = {};
48 |
49 | carsController.postCar(request, response, next);
50 |
51 | expect(carsServiceAddCarStub.calledWith(request.body)).is
52 | .true;
53 | expect(responseJsonSpy.calledWith(car)).is.true;
54 | });
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/src/cars/cars.controller.ts:
--------------------------------------------------------------------------------
1 | import * as express from 'express';
2 | import { injectable, inject } from 'inversify';
3 | import 'reflect-metadata';
4 | import {
5 | controller,
6 | httpGet,
7 | interfaces,
8 | httpPost,
9 | requestParam,
10 | httpPut,
11 | } from 'inversify-express-utils';
12 | import {
13 | ApiPath,
14 | ApiOperationGet,
15 | ApiOperationPost,
16 | SwaggerDefinitionConstant,
17 | ApiOperationPut,
18 | } from 'swagger-express-ts';
19 | import { CarsService } from './cars.service';
20 | import { CarModel } from './car.model';
21 |
22 | @ApiPath({
23 | path: '/cars',
24 | name: 'Cars',
25 | security: { apiKeyHeader: [] },
26 | })
27 | @controller('/cars')
28 | @injectable()
29 | export class CarsController implements interfaces.Controller {
30 | constructor(@inject(CarsService.name) private carsService: CarsService) {}
31 |
32 | @ApiOperationGet({
33 | description: 'Get cars objects list',
34 | summary: 'Get cars list',
35 | responses: {
36 | 200: {
37 | type: SwaggerDefinitionConstant.Response.Type.ARRAY,
38 | model: 'Car',
39 | },
40 | },
41 | security: {
42 | apiKeyHeader: [],
43 | },
44 | })
45 | @httpGet('/')
46 | public getCars(
47 | request: express.Request,
48 | response: express.Response,
49 | next: express.NextFunction
50 | ): void {
51 | response.json(this.carsService.getCars());
52 | }
53 |
54 | @ApiOperationPost({
55 | description: 'Post car object',
56 | summary: 'Post new car',
57 | parameters: {
58 | body: {
59 | description: 'New car',
60 | required: true,
61 | model: 'Car',
62 | },
63 | },
64 | responses: {
65 | 200: {
66 | model: 'Car',
67 | },
68 | 400: { description: 'Parameters fail' },
69 | },
70 | })
71 | @httpPost('/')
72 | public postCar(
73 | request: express.Request,
74 | response: express.Response,
75 | next: express.NextFunction
76 | ): void {
77 | if (!request.body) {
78 | return response.status(400).end();
79 | }
80 | const newCar = new CarModel();
81 | newCar.id = request.body.id;
82 | newCar.name = request.body.name;
83 | newCar.description = request.body.description;
84 | newCar.author = request.body.author;
85 | this.carsService.addCar(request.body);
86 | response.json(request.body);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/cars/cars.service.spec.ts:
--------------------------------------------------------------------------------
1 | import * as chai from 'chai';
2 | import { CarsService } from './cars.service';
3 | import { CarModel } from './car.model';
4 | const expect = chai.expect;
5 |
6 | describe('CarsService', () => {
7 | let carsService: CarsService;
8 |
9 | beforeEach(() => {
10 | carsService = new CarsService();
11 | });
12 |
13 | describe('getCars', () => {
14 | it('expect cars list', () => {
15 | const cars = carsService.getCars();
16 |
17 | expect(cars).exist;
18 | });
19 | });
20 |
21 | describe('addCar', () => {
22 | it('expect new car', () => {
23 | const newCar: CarModel = {} as CarModel;
24 | const lengthBeforeAddCar = carsService.getCars().length;
25 |
26 | const car = carsService.addCar(newCar);
27 |
28 | expect(car).exist;
29 | const lengthAfterAddCar = carsService.getCars().length;
30 | expect(lengthBeforeAddCar < lengthAfterAddCar).is.true;
31 | });
32 | });
33 |
34 | describe('getCarById', () => {
35 | it('expect car by id', () => {
36 | const car = carsService.getCarById('1');
37 |
38 | expect(car).exist;
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/src/cars/cars.service.ts:
--------------------------------------------------------------------------------
1 | import { injectable } from 'inversify';
2 | import 'reflect-metadata';
3 | import { CarModel } from './car.model';
4 | import * as _ from 'lodash';
5 |
6 | @injectable()
7 | export class CarsService {
8 | private carsList: CarModel[] = [
9 | {
10 | id: '1',
11 | name: 'Car 1',
12 | description: 'Description Car 1',
13 | version: '1.0.0',
14 | author: {
15 | id: '1',
16 | name: ['John DOE'],
17 | },
18 | } as unknown as CarModel,
19 | {
20 | id: '2',
21 | name: 'Car 2',
22 | description: 'Description Car 2',
23 | version: '2.0.0',
24 | author: {
25 | id: '1',
26 | name: ['John DOE'],
27 | },
28 | } as unknown as CarModel,
29 | ];
30 |
31 | public getCars(): CarModel[] {
32 | return this.carsList;
33 | }
34 |
35 | public getCarsByIds(ids: string[]): CarModel[] {
36 | return this.carsList.filter(car => ids.includes(car.id));
37 | }
38 |
39 | public addCar(car: CarModel): CarModel {
40 | this.carsList.push(car);
41 | return car;
42 | }
43 |
44 | public getCarById(id: string): CarModel {
45 | return _.find(this.carsList, (car: CarModel) => {
46 | return _.isEqual(car.id, id);
47 | });
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/cars/wheel.model.ts:
--------------------------------------------------------------------------------
1 | import { ApiModel, ApiModelProperty } from 'swagger-express-ts';
2 | import { CarModel } from './car.model';
3 |
4 | @ApiModel({
5 | description: 'Car description',
6 | name: 'Wheel',
7 | })
8 | export class WheelModel {
9 | @ApiModelProperty({
10 | description: 'Id of wheel.',
11 | required: true,
12 | example: ['123456789', '12345'],
13 | })
14 | public id: string;
15 |
16 | @ApiModelProperty({
17 | description: 'Car wheel belongs to. This is to demonstrate a circular reference works.',
18 | required: true,
19 | model: 'Car',
20 | itemType: 'CarModel'
21 | })
22 | public car: CarModel | undefined;
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/constructors/constructor.model.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ApiModel,
3 | ApiModelProperty,
4 | SwaggerDefinitionConstant,
5 | } from 'swagger-express-ts';
6 |
7 | @ApiModel({
8 | description: 'Description Constructor.',
9 | name: 'Constructor',
10 | })
11 | export class ConstructorModel {
12 | @ApiModelProperty({
13 | description: 'Id of Constructor',
14 | required: true,
15 | })
16 | public id: string;
17 |
18 | @ApiModelProperty({
19 | description: 'Name of Constructor',
20 | required: true,
21 | itemType: SwaggerDefinitionConstant.Model.Property.Type.STRING,
22 | })
23 | public name: string[];
24 | }
25 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as bodyParser from 'body-parser';
2 | import * as express from 'express';
3 | import 'reflect-metadata';
4 | import { Container } from 'inversify';
5 | import {
6 | interfaces,
7 | InversifyExpressServer,
8 | TYPE,
9 | } from 'inversify-express-utils';
10 | import { CarsController } from './cars/cars.controller';
11 | import * as swagger from 'swagger-express-ts';
12 | // tslint:disable-next-line: no-duplicate-imports
13 | import { SwaggerDefinitionConstant } from 'swagger-express-ts';
14 | const config = require('../config.json');
15 | import { CarController } from './cars/car.controller';
16 | import { CarBulkController } from './cars/carbulk.controller';
17 | import { CarsService } from './cars/cars.service';
18 |
19 | import * as _ from 'lodash';
20 |
21 | // import models
22 | import { CarModel } from './cars/car.model';
23 | import { WheelModel } from './cars/wheel.model';
24 | import './constructors/constructor.model';
25 |
26 | // set up container
27 | const container = new Container();
28 |
29 | // note that you *must* bind your controllers to Controller
30 | container
31 | .bind(TYPE.Controller)
32 | .to(CarsController)
33 | .inSingletonScope()
34 | .whenTargetNamed(CarsController.name);
35 | container
36 | .bind(TYPE.Controller)
37 | .to(CarBulkController)
38 | .inSingletonScope()
39 | .whenTargetNamed(CarBulkController.name);
40 | container
41 | .bind(TYPE.Controller)
42 | .to(CarController)
43 | .inSingletonScope()
44 | .whenTargetNamed(CarController.name);
45 | container
46 | .bind(CarsService.name)
47 | .to(CarsService)
48 | .inSingletonScope();
49 |
50 | container.bind(CarModel.name).to(CarModel);
51 | container.bind(WheelModel.name).to(WheelModel);
52 |
53 |
54 | // create server
55 | const server = new InversifyExpressServer(container);
56 |
57 | server.setConfig((app: any) => {
58 | app.use('/api-docs/swagger', express.static('swagger'));
59 | app.use(
60 | '/api-docs/swagger/assets',
61 | express.static('node_modules/swagger-ui-dist')
62 | );
63 | app.use(bodyParser.json());
64 | app.use(
65 | swagger.express({
66 | definition: {
67 | info: {
68 | title: 'My api',
69 | version: '1.0',
70 | },
71 | models: {
72 | ApiError: {
73 | properties: {
74 | code: {
75 | type:
76 | SwaggerDefinitionConstant.Model.Property
77 | .Type.STRING,
78 | example: ['400'],
79 | },
80 | message: {
81 | type:
82 | SwaggerDefinitionConstant.Model.Property
83 | .Type.STRING,
84 | example: ['Name of car is required.'],
85 | },
86 | },
87 | },
88 | },
89 | responses: {
90 | 500: {},
91 | },
92 | externalDocs: {
93 | url: 'My url',
94 | },
95 | securityDefinitions: {
96 | apiKeyHeader: {
97 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
98 | in: SwaggerDefinitionConstant.Security.In.HEADER,
99 | name: 'apiHeader',
100 | },
101 | },
102 | },
103 | })
104 | );
105 | });
106 |
107 | server.setErrorConfig((app: any) => {
108 | app.use(
109 | (
110 | err: Error,
111 | request: express.Request,
112 | response: express.Response,
113 | next: express.NextFunction
114 | ) => {
115 | console.error(err.stack);
116 | response.status(500).send('Something broke!');
117 | }
118 | );
119 | });
120 |
121 | const app = server.build();
122 |
123 | if (!_.isEqual(process.env.NODE_ENV, 'test')) {
124 | app.listen(config.port);
125 | console.info('Server is listening on port : ' + config.port);
126 | }
127 |
--------------------------------------------------------------------------------
/swagger/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Swagger UI
7 |
9 |
10 |
11 |
12 |
30 |
31 |
32 |
33 |
34 |
68 |
69 |
70 |
71 |
72 |
73 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --compilers ts-node/register
2 | --require source-map-support/register
3 | --full-trace
4 | --bail
5 | src/**/*.spec.ts lib/swagger-express-ts-lib/src/**/*.spec.ts
--------------------------------------------------------------------------------
/tsconfig.dev.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.lib.json",
3 | "compilerOptions": {
4 | "outDir": "./node_modules/swagger-express-ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target":
5 | "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */,
6 | "module":
7 | "commonjs" /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
8 | "lib": [
9 | "es2017",
10 | "dom"
11 | ] /* Specify library files to be included in the compilation: */,
12 | // "allowJs": true, /* Allow javascript files to be compiled. */
13 | // "checkJs": true, /* Report errors in .js files. */
14 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
15 | "declaration": false /* Generates corresponding '.d.ts' file. */,
16 | "sourceMap": true /* Generates corresponding '.map' file. */,
17 | //"outFile": "index.js", /* Concatenate and emit output to single file. */
18 | "outDir": "./built" /* Redirect output structure to the directory. */,
19 | //"rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
20 | // "removeComments": true, /* Do not emit comments to output. */
21 | // "noEmit": true, /* Do not emit outputs. */
22 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
23 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
24 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
25 |
26 | /* Strict Type-Checking Options */
27 | //"strict": true, /* Enable all strict type-checking options. */
28 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
29 | "strictNullChecks": false /* Enable strict null checks. */,
30 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
31 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
32 |
33 | /* Additional Checks */
34 | // "noUnusedLocals": true, /* Report errors on unused locals. */
35 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
36 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
37 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
38 |
39 | /* Module Resolution Options */
40 | "moduleResolution":
41 | "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
42 | "baseUrl":
43 | "./" /* Base directory to resolve non-absolute module names. */,
44 | //"paths": {
45 | //} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
46 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
47 | "typeRoots": [
48 | "node_modules/@types",
49 | "node_modules/swagger-express-ts"
50 | ] /* List of folders to include type definitions from. */,
51 | //"types": [
52 | // "express",
53 | // "inversify",
54 | // "reflect-metadata",
55 | // "compression",
56 | // "helmet",
57 | // "mocha",
58 | // "sinon",
59 | // "lodash",
60 | // "chai"
61 | //] /* Type declaration files to be included in compilation. */,
62 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
63 |
64 | /* Source Map Options */
65 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
66 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
67 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
68 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
69 |
70 | /* Experimental Options */
71 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
72 | "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */
73 | },
74 | "exclude": ["node_modules"],
75 | "include": ["src/**/*.ts"]
76 | }
77 |
--------------------------------------------------------------------------------
/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "declaration": true,
5 | "outDir": "./dist/swagger-express-ts",
6 | "baseUrl": "./",
7 | "typeRoots": ["node_modules/@types"],
8 | "paths": {}
9 | },
10 | "exclude": ["node_modules", "lib/swagger-express-ts-lib/src/**/*.spec.ts"],
11 | "include": ["lib/swagger-express-ts-lib/src/**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "error",
3 | "extends": ["tslint:latest", "tslint-config-prettier"],
4 | "jsRules": {},
5 | "rules": {
6 | "no-console": false,
7 | "ordered-imports": false,
8 | "no-unused-expression": false,
9 | "no-shadowed-variable": false,
10 | "no-var-requires": false,
11 | "member-ordering": false,
12 | "no-implicit-dependencies": false,
13 | "no-empty-interface": false,
14 | "object-literal-sort-keys": false,
15 | "no-object-literal-type-assertion": false,
16 | "forin": false
17 | },
18 | "rulesDirectory": []
19 | }
20 |
--------------------------------------------------------------------------------
/wiki/README.md:
--------------------------------------------------------------------------------
1 | # Wiki
2 |
3 | Welcome to the SwaggerExpressTS wiki!
4 |
5 | ## Installation and environment support
6 |
7 | - [Installation](./installation.md)
8 |
9 | ## Features and API
10 |
11 | - [Installation](./installation.md)
12 | - [Configuration](./configuration.md)
13 | - [@ApiModel](./api-model.decorator.md)
14 | - [@ApiModelProperty](./api-model-property.decorator.md)
15 | - [@ApiPath](./api-path.decorator.md)
16 | - [@ApiOperationGet](./api-operation-get.decorator.md)
17 | - [@ApiOperationPost](./api-operation-post.decorator.md)
18 | - [@ApiOperationPut](./api-operation-put.decorator.md)
19 | - [@ApiOperationPatch](./api-operation-patch.decorator.md)
20 | - [@ApiOperationDelete](./api-operation-delete.decorator.md)
21 |
22 | ## Test
23 |
24 | - [example-swagger-express-ts](https://github.com/olivierlsc/example-swagger-express-ts)
--------------------------------------------------------------------------------
/wiki/api-model-property.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiModelProperty(args?: IApiModelPropertyArgs)
2 |
3 | Decorate property in model class.
4 |
5 | Example:
6 |
7 | ```ts
8 | @ApiModel({
9 | description: "Version description",
10 | name: "Version"
11 | })
12 | export class VersionModel {
13 |
14 | @ApiModelProperty({
15 | description: "number value",
16 | enum : ['1', '2']
17 | })
18 | number: number;
19 | ...
20 | }
21 | ```
22 |
23 | # IApiModelPropertyArgs
24 |
25 | ## required: boolean
26 |
27 | Define if property is required.
28 |
29 | * Optional
30 |
31 | ## format: string
32 |
33 | Define format.
34 |
35 | * Optional
36 |
37 | ## type: string
38 |
39 | Define type of property.
40 |
41 | * Optional
42 |
43 | ## description: string
44 |
45 | Define description of property.
46 |
47 | * Optional
48 |
49 | ## enum: string[]
50 |
51 | Define enum of property.
52 |
53 | * Optional
54 |
55 | ## model: string
56 |
57 | Define model
58 |
59 | * Optional
60 |
61 | ## itemType: string
62 |
63 | Define item type.
64 |
65 | * Optional
66 |
67 | ## example: any[]
68 |
69 | Define example.
70 |
71 | * Optional
72 |
--------------------------------------------------------------------------------
/wiki/api-model.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiModel(args?: IApiModelArgs)
2 |
3 | Decorate model class.
4 |
5 | Example:
6 |
7 | ```ts
8 | @ApiModel({
9 | description: "Version description",
10 | name: "Version"
11 | })
12 | export class VersionModel {
13 | ...
14 | }
15 | ```
16 |
17 | # IApiModelArgs
18 |
19 | ## description: string
20 |
21 | Define description
22 | - Optional
23 |
24 | ## name: string
25 |
26 | Define name
27 | - Optional
28 | - Default is name of model class
--------------------------------------------------------------------------------
/wiki/api-operation-delete.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiOperationDelete(args: IApiOperationDeleteArgs)
2 | Decorate method for deleting a resource in your controller.
3 |
4 | Example:
5 |
6 | ```ts
7 | @ApiPath( {
8 | path : "/versions",
9 | name : "Version"
10 | } )
11 | @controller( "/versions" )
12 | @injectable()
13 | export class VersionController implements interfaces.Controller {
14 | public static TARGET_NAME: string = "VersionController";
15 | private data: [any] = [
16 | {
17 | id : "1",
18 | name : "Version 1",
19 | description : "Description Version 1",
20 | version : "1.0.0"
21 | },
22 | {
23 | id : "2",
24 | name : "Version 2",
25 | description : "Description Version 2",
26 | version : "2.0.0"
27 | }
28 | ];
29 |
30 | @ApiOperationDelete( {
31 | path : "/{id}",
32 | parameters : {
33 | path : {
34 | id : {
35 | description : "Id of version",
36 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
37 | required : true
38 | }
39 | }
40 | },
41 | responses : {
42 | 200 : { description: "Success" }
43 | }
44 | } )
45 | @httpDelete( "/:id" )
46 | public deleteVersion( @requestParam( "id" ) id: string, request: express.Request, response: express.Response, next: express.NextFunction ): void {
47 | this.data.forEach( ( version: any, index: number )=> {
48 | if ( version.id === id ) {
49 | this.data.splice(index, 1);
50 | return response.status(200).end();
51 | }
52 | } );
53 | response.status( 404 ).end();
54 | }
55 | }
56 |
57 | ```
58 |
59 | # IApiOperationDeleteArgs
60 |
61 | ## path: string
62 | Define particular path of operation. Default is path parameter in [@ApiPath](./api-path.decorator.md).
63 | - Optional
64 |
65 | ## description: string
66 | Define description of operation.
67 | - Optional
68 |
69 | ## summary: string
70 | Define summary of operation.
71 | - Optional
72 |
73 | ## parameters: [IApiOperationArgsBaseParameters](./i-api-operation-args-base-parameters.md)
74 | Define parameters in path, body, query and formData.
75 | - Required
76 |
77 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
78 | Define all responses.
79 | - Required
80 |
81 | ## produces: string[]
82 | Define type list that resource produce.
83 | - Optional
84 | - Default is global type list defined in ISwaggerBuildDefinition when execute [.express(options: ISwaggerExpressOptions)](./configuration.md)
85 |
86 | ## security: {[key: string]: any[]}
87 | Define security
88 | - Optional
89 |
90 | Example:
91 |
92 | ```ts
93 | ...
94 | @ApiOperationDelete( {
95 | path : "/{id}",
96 | parameters : {
97 | path : {
98 | id : {
99 | description : "Id of version",
100 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
101 | required : true
102 | }
103 | }
104 | },
105 | responses : {
106 | 200 : { description: "Success" }
107 | },
108 | security : {
109 | basicAuth : []
110 | }
111 | } )
112 | ...
113 | }
114 |
115 | ```
116 |
117 | ### Configuration
118 |
119 | Example:
120 |
121 | ```ts
122 | app.use( swagger.express(
123 | {
124 | definition : {
125 | ...
126 | securityDefinitions : {
127 | basicAuth : {
128 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
129 | },
130 | apiKeyHeader : {
131 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
132 | in: SwaggerDefinitionConstant.Security.In.HEADER,
133 | name: "apiHeader"
134 | }
135 | }
136 | }
137 | }
138 | ) );
139 | ```
140 |
141 | ## deprecated: boolean
142 | Define deprecated
143 | - Optional
--------------------------------------------------------------------------------
/wiki/api-operation-get.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiOperationGet(args: IApiOperationGetArgs)
2 | Decorate method for getting a resource in your controller.
3 |
4 | Example:
5 |
6 | ```ts
7 | @ApiPath( {
8 | path : "/versions",
9 | name : "Version"
10 | } )
11 | @controller( "/versions" )
12 | @injectable()
13 | export class VersionController implements interfaces.Controller {
14 | public static TARGET_NAME: string = "VersionController";
15 | private data: [any] = [
16 | {
17 | id : "1",
18 | name : "Version 1",
19 | description : "Description Version 1",
20 | version : "1.0.0"
21 | },
22 | {
23 | id : "2",
24 | name : "Version 2",
25 | description : "Description Version 2",
26 | version : "2.0.0"
27 | }
28 | ];
29 |
30 | @ApiOperationGet( {
31 | description : "Get version object",
32 | summary : "Get version",
33 | responses : {
34 | 200 : { description : "Success", type : SwaggerDefinitionConstant.Response.Type.ARRAY , model : "Version" }
35 | }
36 | } )
37 | @httpGet( "/" )
38 | public getVersions( request: express.Request, response: express.Response, next: express.NextFunction ): void {
39 | response.json( this.data );
40 | }
41 | }
42 |
43 | ```
44 |
45 | # IApiOperationGetArgs
46 |
47 | ## path: string
48 | Define particular path of operation. Default is path parameter in [@ApiPath](./api-path.decorator.md).
49 | - Optional
50 |
51 | ## description: string
52 | Define description of operation.
53 | - Optional
54 |
55 | ## summary: string
56 | Define summary of operation.
57 | - Optional
58 |
59 | ## parameters: [IApiOperationArgsBaseParameters](./i-api-operation-args-base-parameters.md)
60 | Define parameters in path, body, query and formData.
61 | - Required
62 |
63 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
64 | Define all responses.
65 | - Required
66 |
67 | ## produces: string[]
68 | Define type list that resource produce.
69 | - Optional
70 | - Default is global type list defined in ISwaggerBuildDefinition when execute [.express(options: ISwaggerExpressOptions)](./configuration.md)
71 |
72 | ## security: {[key: string]: any[]}
73 | Define security
74 | - Optional
75 |
76 | Example:
77 |
78 | ```ts
79 | ...
80 | @ApiOperationGet( {
81 | ...
82 | security : {
83 | basicAuth : []
84 | }
85 | } )
86 | ...
87 | }
88 |
89 | ```
90 |
91 | ### Configuration
92 |
93 | Example:
94 |
95 | ```ts
96 | app.use( swagger.express(
97 | {
98 | definition : {
99 | ...
100 | securityDefinitions : {
101 | basicAuth : {
102 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
103 | },
104 | apiKeyHeader : {
105 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
106 | in: SwaggerDefinitionConstant.Security.In.HEADER,
107 | name: "apiHeader"
108 | }
109 | }
110 | }
111 | }
112 | ) );
113 | ```
114 |
115 | ## deprecated: boolean
116 | Define deprecated
117 | - Optional
--------------------------------------------------------------------------------
/wiki/api-operation-patch.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiOperationPatch(args: IApiOperationPatchArgs)
2 | Decorate method for updating a field of resource in your controller.
3 |
4 | Example:
5 |
6 | ```ts
7 | @ApiPath( {
8 | path : "/versions",
9 | name : "Version"
10 | } )
11 | @controller( "/versions" )
12 | @injectable()
13 | export class VersionController implements interfaces.Controller {
14 | public static TARGET_NAME: string = "VersionController";
15 | private data: [any] = [
16 | {
17 | id : "1",
18 | name : "Version 1",
19 | description : "Description Version 1",
20 | version : "1.0.0"
21 | },
22 | {
23 | id : "2",
24 | name : "Version 2",
25 | description : "Description Version 2",
26 | version : "2.0.0"
27 | }
28 | ];
29 |
30 | @ApiOperationPatch( {
31 | path : "/{id}/description",
32 | description : "Patch description in version object",
33 | summary : "Patch description in version",
34 | parameters : {
35 | path: {
36 | id: {
37 | description : "Id of version",
38 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
39 | required : true
40 | }
41 | },
42 | body : { description : "New version", required : true, model : "Version" }
43 | },
44 | responses : {
45 | 200 : { description : "Success" },
46 | 400 : { description : "Parameters fail" },
47 | 404 : { description : "Version not found" }
48 | }
49 | } )
50 | @httpPatch( "/:id/description" )
51 | public patchVersionDescription( @requestParam( "id" ) id: string, request: express.Request, response: express.Response, next: express.NextFunction ): void {
52 | if ( ! request.body ) {
53 | return response.status( 400 ).end();
54 | }
55 | this.data.forEach( ( version: any )=> {
56 | if ( version.id === id ) {
57 | version.description = request.body.description;
58 | return response.json( version );
59 | }
60 | } );
61 | response.status( 404 ).end();
62 | }
63 | }
64 |
65 | ```
66 |
67 | # IApiOperationPatchArgs
68 |
69 | ## path: string
70 | Define particular path of operation. Default is path parameter in [@ApiPath](./api-path.decorator.md).
71 | - Optional
72 |
73 | ## description: string
74 | Define description of operation.
75 | - Optional
76 |
77 | ## summary: string
78 | Define summary of operation.
79 | - Optional
80 |
81 | ## parameters: [IApiOperationArgsBaseParameters](./i-api-operation-args-base-parameters.md)
82 | Define parameters in path, body, query and formData.
83 | - Required
84 |
85 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
86 | Define all responses.
87 | - Required
88 |
89 | ## produces: string[]
90 | Define type list that resource produce.
91 | - Optional
92 | - Default is global type list defined in ISwaggerBuildDefinition when execute [.express(options: ISwaggerExpressOptions)](./configuration.md)
93 |
94 | ## security: {[key: string]: any[]}
95 | Define security
96 | - Optional
97 |
98 | Example:
99 |
100 | ```ts
101 | ...
102 | @ApiOperationPatch( {
103 | path : "/{id}/description",
104 | description : "Patch description in version object",
105 | summary : "Patch description in version",
106 | parameters : {
107 | path: {
108 | id: {
109 | description : "Id of version",
110 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
111 | required : true
112 | }
113 | },
114 | body : { description : "New version", required : true, model : "Version" }
115 | },
116 | responses : {
117 | 200 : { description : "Success" },
118 | 400 : { description : "Parameters fail" },
119 | 404 : { description : "Version not found" }
120 | },
121 | security : {
122 | basicAuth : []
123 | }
124 | } )
125 | ...
126 | }
127 |
128 | ```
129 |
130 | ### Configuration
131 |
132 | Example:
133 |
134 | ```ts
135 | app.use( swagger.express(
136 | {
137 | definition : {
138 | ...
139 | securityDefinitions : {
140 | basicAuth : {
141 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
142 | },
143 | apiKeyHeader : {
144 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
145 | in: SwaggerDefinitionConstant.Security.In.HEADER,
146 | name: "apiHeader"
147 | }
148 | }
149 | }
150 | }
151 | ) );
152 | ```
153 |
154 | ## deprecated: boolean
155 | Define deprecated
156 | - Optional
--------------------------------------------------------------------------------
/wiki/api-operation-post.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiOperationPost(args: IApiOperationPostArgs)
2 | Decorate method for create a resource in your controller.
3 |
4 | Example:
5 |
6 | ```ts
7 | @ApiPath( {
8 | path : "/versions",
9 | name : "Version"
10 | } )
11 | @controller( "/versions" )
12 | @injectable()
13 | export class VersionController implements interfaces.Controller {
14 | public static TARGET_NAME: string = "VersionController";
15 | private data: [any] = [
16 | {
17 | id : "1",
18 | name : "Version 1",
19 | description : "Description Version 1",
20 | version : "1.0.0"
21 | },
22 | {
23 | id : "2",
24 | name : "Version 2",
25 | description : "Description Version 2",
26 | version : "2.0.0"
27 | }
28 | ];
29 |
30 | @ApiOperationPost( {
31 | description : "Post version object",
32 | summary : "Post new version",
33 | parameters : {
34 | body : { description : "New version", required : true, model : "Version" }
35 | },
36 | responses : {
37 | 200 : { description : "Success" },
38 | 400 : { description : "Parameters fail" }
39 | }
40 | } )
41 | @httpPost( "/" )
42 | public postVersion( request: express.Request, response: express.Response, next: express.NextFunction ): void {
43 | if ( ! request.body ) {
44 | return response.status( 400 ).end();
45 | }
46 | this.data.push( request.body );
47 | response.json( request.body );
48 | }
49 | }
50 |
51 | ```
52 |
53 | # IApiOperationPostArgs
54 |
55 | ## path: string
56 | Define particular path of operation. Default is path parameter in [@ApiPath](./api-path.decorator.md).
57 | - Optional
58 |
59 | ## description: string
60 | Define description of operation.
61 | - Optional
62 |
63 | ## summary: string
64 | Define summary of operation.
65 | - Optional
66 |
67 | ## parameters: [IApiOperationArgsBaseParameters](./i-api-operation-args-base-parameters.md)
68 | Define parameters in path, body, query and formData.
69 | - Required
70 |
71 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
72 | Define all responses.
73 | - Required
74 |
75 | ## produces: string[]
76 | Define type list that resource produce.
77 | - Optional
78 | - Default is global type list defined in ISwaggerBuildDefinition when execute [.express(options: ISwaggerExpressOptions)](./configuration.md)
79 |
80 | ## security: {[key: string]: any[]}
81 | Define security
82 | - Optional
83 |
84 | Example:
85 |
86 | ```ts
87 | ...
88 | @ApiOperationPost( {
89 | description : "Post version object",
90 | summary : "Post new version",
91 | parameters : {
92 | body : { description : "New version", required : true, model : "Version" }
93 | },
94 | responses : {
95 | 200 : { description : "Success" },
96 | 400 : { description : "Parameters fail" }
97 | },
98 | security : {
99 | basicAuth : []
100 | }
101 | } )
102 | ...
103 | }
104 |
105 | ```
106 |
107 | ### Configuration
108 |
109 | Example:
110 |
111 | ```ts
112 | app.use( swagger.express(
113 | {
114 | definition : {
115 | ...
116 | securityDefinitions : {
117 | basicAuth : {
118 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
119 | },
120 | apiKeyHeader : {
121 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
122 | in: SwaggerDefinitionConstant.Security.In.HEADER,
123 | name: "apiHeader"
124 | }
125 | }
126 | }
127 | }
128 | ) );
129 | ```
130 |
131 | ## deprecated: boolean
132 | Define deprecated
133 | - Optional
--------------------------------------------------------------------------------
/wiki/api-operation-put.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiOperationPut(args: IApiOperationPutArgs)
2 | Decorate method for updating a resource in your controller.
3 |
4 | Example:
5 |
6 | ```ts
7 | @ApiPath( {
8 | path : "/versions",
9 | name : "Version"
10 | } )
11 | @controller( "/versions" )
12 | @injectable()
13 | export class VersionController implements interfaces.Controller {
14 | public static TARGET_NAME: string = "VersionController";
15 | private data: [any] = [
16 | {
17 | id : "1",
18 | name : "Version 1",
19 | description : "Description Version 1",
20 | version : "1.0.0"
21 | },
22 | {
23 | id : "2",
24 | name : "Version 2",
25 | description : "Description Version 2",
26 | version : "2.0.0"
27 | }
28 | ];
29 |
30 | @ApiOperationPut( {
31 | path : "/{id}",
32 | parameters : {
33 | path : {
34 | id : {
35 | description : "Id of version",
36 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
37 | required : true
38 | }
39 | },
40 | body : {
41 | description : "Updated version",
42 | model : "Version",
43 | required : true
44 | }
45 | },
46 | responses : {
47 | 200 : { model : "Version" }
48 | }
49 | } )
50 | @httpPut( "/:id" )
51 | public putVersion( @requestParam( "id" ) id: string, request: express.Request, response: express.Response, next: express.NextFunction ): void {
52 | if ( ! request.body ) {
53 | return response.status( 400 ).end();
54 | }
55 | this.data.forEach( ( version: any, index: number )=> {
56 | if ( version.id === id ) {
57 | let newVersion = request.body;
58 | version.id = newVersion.id;
59 | version.name = newVersion.name;
60 | version.description = newVersion.description;
61 | version.version = newVersion.version;
62 | this.data[ index ] = version;
63 | return response.json( version );
64 | }
65 | } );
66 | response.status( 404 ).end();
67 | }
68 | }
69 |
70 | ```
71 |
72 | # IApiOperationPutArgs
73 |
74 | ## path: string
75 | Define particular path of operation. Default is path parameter in [@ApiPath](./api-path.decorator.md).
76 | - Optional
77 |
78 | ## description: string
79 | Define description of operation.
80 | - Optional
81 |
82 | ## summary: string
83 | Define summary of operation.
84 | - Optional
85 |
86 | ## parameters: [IApiOperationArgsBaseParameters](./i-api-operation-args-base-parameters.md)
87 | Define parameters in path, body, query and formData.
88 | - Required
89 |
90 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
91 | Define all responses.
92 | - Required
93 |
94 | ## produces: string[]
95 | Define type list that resource produce.
96 | - Optional
97 | - Default is global type list defined in ISwaggerBuildDefinition when execute [.express(options: ISwaggerExpressOptions)](./configuration.md)
98 |
99 | ## security: {[key: string]: any[]}
100 | Define security
101 | - Optional
102 |
103 | Example:
104 |
105 | ```ts
106 | ...
107 | @ApiOperationPut( {
108 | path : "/{id}",
109 | parameters : {
110 | path : {
111 | id : {
112 | description : "Id of version",
113 | type : SwaggerDefinitionConstant.Parameter.Type.STRING,
114 | required : true
115 | }
116 | },
117 | body : {
118 | description : "Updated version",
119 | model : "Version",
120 | required : true
121 | }
122 | },
123 | responses : {
124 | 200 : { model : "Version" }
125 | },
126 | security : {
127 | basicAuth : []
128 | }
129 | } )
130 | ...
131 | }
132 |
133 | ```
134 |
135 | ### Configuration
136 |
137 | Example:
138 |
139 | ```ts
140 | app.use( swagger.express(
141 | {
142 | definition : {
143 | ...
144 | securityDefinitions : {
145 | basicAuth : {
146 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
147 | },
148 | apiKeyHeader : {
149 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
150 | in: SwaggerDefinitionConstant.Security.In.HEADER,
151 | name: "apiHeader"
152 | }
153 | }
154 | }
155 | }
156 | ) );
157 | ```
158 |
159 | ## deprecated: boolean
160 | Define deprecated
161 | - Optional
--------------------------------------------------------------------------------
/wiki/api-path.decorator.md:
--------------------------------------------------------------------------------
1 | # @ApiPath(args: IApiPathArgs)
2 |
3 | Decorate your controller to declare a resource.
4 |
5 | Example:
6 |
7 | ```ts
8 | import { injectable } from "inversify";
9 | import "reflect-metadata";
10 | import { ApiPath } from "swagger-express-ts";
11 | import { controller } from "inversify-express-utils";
12 |
13 | @ApiPath( {
14 | path : "/version",
15 | name : "Version"
16 | } )
17 | @controller( "/version" )
18 | @injectable()
19 | export class VersionController implements interfaces.Controller {
20 | public static TARGET_NAME: string = "VersionController";
21 | }
22 | ```
23 |
24 | # IApiPathArgs
25 |
26 | ## path: string
27 | Define path of resource.
28 | - Required
29 |
30 | ## name: string
31 | Define name of resource.
32 | - Required
33 |
34 | ## description: string
35 | Define description of resource.
36 | - Optional
37 |
38 | ## security: {[key: string]: any[]}
39 | Define security to apply all operations from current path.
40 | - Optional
41 |
42 | Example:
43 |
44 | ```ts
45 | ...
46 | @ApiPath( {
47 | path : "/version",
48 | name : "Version",
49 | security : {
50 | basicAuth : []
51 | }
52 | } )
53 | ...
54 | ```
55 |
56 | ### Configuration
57 |
58 | Example:
59 |
60 | ```ts
61 | app.use( swagger.express(
62 | {
63 | definition : {
64 | ...
65 | securityDefinitions : {
66 | basicAuth : {
67 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
68 | },
69 | apiKeyHeader : {
70 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
71 | in: SwaggerDefinitionConstant.Security.In.HEADER,
72 | name: "apiHeader"
73 | }
74 | }
75 | }
76 | }
77 | ) );
78 | ```
79 |
80 | ## deprecated: boolean
81 | Define deprecated
82 | - Optional
--------------------------------------------------------------------------------
/wiki/configuration.md:
--------------------------------------------------------------------------------
1 | # Configuration
2 |
3 | ## .express(options: ISwaggerExpressOptions)
4 | Example with default configuration:
5 |
6 | ```ts
7 | app.use( swagger.express({
8 | definition : {
9 | info : {
10 | title : "My api" ,
11 | version : "1.0"
12 | } ,
13 | models : {
14 | Version : {
15 | properties : {
16 | id : {
17 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING ,
18 | required : true
19 | } ,
20 | name : {
21 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING ,
22 | required : true
23 | } ,
24 | description : {
25 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING
26 | } ,
27 | version : {
28 | type : SwaggerDefinitionConstant.Model.Property.Type.STRING
29 | }
30 | }
31 | }
32 | } ,
33 | externalDocs : {
34 | url : "My url"
35 | }
36 | }
37 | }) );
38 | ```
39 |
40 | # ISwaggerExpressOptions
41 |
42 | ## path: string
43 | Define path to serve swagger.json
44 | - Optional.
45 | - Default is "/api-docs/swagger.json".
46 |
47 | ## definition: [ISwaggerBuildDefinition](./i-swagger-build-definition.md)
48 | Define swagger definition.
49 | - Required
50 |
51 | # Authentication
52 |
53 | ## Configuration
54 |
55 | Example:
56 |
57 | ```ts
58 | app.use( swagger.express(
59 | {
60 | definition : {
61 | ...
62 | securityDefinitions : {
63 | basicAuth : {
64 | type : SwaggerDefinitionConstant.Security.Type.BASIC_AUTHENTICATION
65 | },
66 | apiKeyHeader : {
67 | type: SwaggerDefinitionConstant.Security.Type.API_KEY,
68 | in: SwaggerDefinitionConstant.Security.In.HEADER,
69 | name: "apiHeader"
70 | }
71 | }
72 | }
73 | }
74 | ) );
75 | ```
76 |
77 | ## Secure controller
78 |
79 | Example:
80 |
81 | ```ts
82 | ...
83 | @ApiPath( {
84 | path : "/version",
85 | name : "Version",
86 | security : {
87 | basicAuth : []
88 | }
89 | } )
90 | ...
91 | @ApiOperationGet( {
92 | ...
93 | security : {
94 | basicAuth : []
95 | }
96 | } )
97 | ...
98 | ```
99 |
--------------------------------------------------------------------------------
/wiki/i-api-body-operation-args-base-parameter.md:
--------------------------------------------------------------------------------
1 | # IApiBodyOperationArgsBaseParameter
2 |
3 | ## name: string
4 |
5 | Define name of parameter.
6 |
7 | * Optional
8 |
9 | ## description: string
10 |
11 | Define description of parameter.
12 |
13 | * Optional
14 |
15 | ## type: string
16 |
17 | Define type of parameter.
18 |
19 | * Optional
20 |
21 | ## required: boolean
22 |
23 | Define required of parameter.
24 |
25 | * Optional
26 |
27 | ## format: string
28 |
29 | Define format of parameter.
30 |
31 | * Optional
32 |
33 | ## minimum: number
34 |
35 | Define minimum of parameter.
36 |
37 | * Optional
38 |
39 | ## maximum: number
40 |
41 | Define maximum of parameter.
42 |
43 | * Optional
44 |
45 | ## default: number
46 |
47 | Define default of parameter.
48 |
49 | * Optional
50 |
51 | ## deprecated: boolean
52 |
53 | Define deprecated of parameter.
54 |
55 | * Optional
56 |
57 | ## allowEmptyValue: boolean
58 |
59 | Define allowEmptyValue of parameter.
60 |
61 | * Optional
62 |
63 | ## properties: { [key: string]: [IApiPropertyBodyOperationArgsBaseParameter](./i-api-property-body-operation-args-base-parameter.md) }
64 |
65 | Define properties of parameter.
66 |
67 | * Optional
68 |
69 | ## model: string
70 |
71 | Define model reference
72 |
73 | * Optional
74 | * If you want specify Array of model, you must set type with [SwaggerDefinitionConstant](./swagger-definition-constant.md).Definition.Property.Type.ARRAY
75 |
--------------------------------------------------------------------------------
/wiki/i-api-operation-args-base-parameter.md:
--------------------------------------------------------------------------------
1 | # IApiOperationArgsBaseParameter
2 |
3 | ## name: string
4 |
5 | Define name of parameter.
6 |
7 | * Optional
8 |
9 | ## description: string
10 |
11 | Define description of parameter.
12 |
13 | * Optional
14 |
15 | ## type: string
16 |
17 | Define type of parameter.
18 |
19 | * Optional
20 |
21 | ## format: string
22 |
23 | Define format of parameter.
24 |
25 | * Optional
26 |
27 | ## deprecated: boolean
28 |
29 | Define if parameter is deprecated.
30 |
31 | * Optional
32 |
33 | ## allowEmptyValue: boolean
34 |
35 | Define if parameter is allow empty value.
36 |
37 | * Optional
38 |
--------------------------------------------------------------------------------
/wiki/i-api-operation-args-base-parameters.md:
--------------------------------------------------------------------------------
1 | # IApiOperationArgsBaseParameters
2 |
3 | ## path: {[key: string]: [IApiOperationArgsBaseParameter](./i-api-operation-args-base-parameter.md)}
4 | Define path parameters.
5 | - Optional
6 |
7 | ## query: {[key: string]: [IApiOperationArgsBaseParameter](./i-api-operation-args-base-parameter.md)}
8 | Define query parameters.
9 | - Optional
10 |
11 | ## body: [IApiBodyOperationArgsBaseParameter](./i-api-body-operation-args-base-parameter.md)
12 | Define body parameters.
13 | - Optional
14 |
15 | ## formData: {[key: string]: [IApiOperationArgsBaseParameter](./i-api-operation-args-base-parameter.md)}
16 | Define formData parameters.
17 | - Optional
18 |
--------------------------------------------------------------------------------
/wiki/i-api-operation-args-base-response.md:
--------------------------------------------------------------------------------
1 | # IApiOperationArgsBaseResponse
2 |
3 | ## description: string
4 |
5 | Define description of response.
6 |
7 | * Optional
8 |
9 | ## type: string
10 |
11 | Define type of response.
12 |
13 | * Optional
14 |
15 | ## model: string
16 |
17 | Define model reference
18 |
19 | * Optional
20 | * If you want specify Array of model, you must set type with [SwaggerDefinitionConstant](./swagger-definition-constant.md).Definition.Property.Type.ARRAY
21 |
--------------------------------------------------------------------------------
/wiki/i-api-property-body-operation-args-base-parameter.md:
--------------------------------------------------------------------------------
1 | # IApiPropertyBodyOperationArgsBaseParameter
2 |
3 | ## type: string
4 |
5 | Define type of parameter.
6 |
7 |
8 | ## required: string
9 |
10 | Define required of parameter.
11 |
12 | * Optional
--------------------------------------------------------------------------------
/wiki/i-swagger-build-definition-model-property.md:
--------------------------------------------------------------------------------
1 | # ISwaggerBuildDefinitionModelProperty
2 |
3 | ## type: string
4 |
5 | Define type of property.
6 |
7 | * Required
8 | * Example : [SwaggerDefinitionConstant](./swagger-definition-constant.md).Definition.Property.Type.STRING or "string"
9 |
10 | ## format: string
11 |
12 | Define format of property.
13 |
14 | * Optional
15 | * Example : [SwaggerDefinitionConstant](./swagger-definition-constant.md).Definition.Property.Format.INT_64
16 |
17 | ## required: boolean
18 |
19 | Define if property is required.
20 |
21 | * Optional
22 | * Default is false.
23 |
24 | ## model: string
25 |
26 | Define model reference
27 |
28 | * Optional
29 | * If you want specify Array of model, you must set type with [SwaggerDefinitionConstant](./swagger-definition-constant.md).Definition.Property.Type.ARRAY
30 |
31 | ## description: string
32 |
33 | Define description of property.
34 |
35 | * Optional
36 |
37 | ## enum: string[]
38 |
39 | Define enum of property.
40 |
41 | * Optional
42 |
43 | ## itemType: string
44 |
45 | Define item type.
46 |
47 | * Optional
48 |
49 | Example:
50 |
51 | ```ts
52 | ...
53 | app.use(
54 | swagger.express({
55 | definition: {
56 | ...
57 | models: {
58 | Author: {
59 | name: {
60 | description: "Name of author",
61 | type: SwaggerDefinitionConstant.Model.Property.Type.ARRAY,
62 | itemType:
63 | SwaggerDefinitionConstant.Model.Property.ItemType.STRING,
64 | required: true
65 | }
66 | }
67 | }
68 | }
69 | ...
70 | }
71 | })
72 | );
73 | ...
74 | ```
75 |
76 | ## example: any[]
77 |
78 | Define example.
79 |
80 | * Optional
81 |
--------------------------------------------------------------------------------
/wiki/i-swagger-build-definition-model.md:
--------------------------------------------------------------------------------
1 | # ISwaggerBuildDefinitionModel
2 |
3 | ## description: string;
4 |
5 | Define description
6 | - Optional
7 |
8 | ## properties: {[key: string]: [ISwaggerBuildDefinitionModelProperty](./i-swagger-build-definition-model-property.md)}
9 |
10 | Define properties of model.
11 | - Required
--------------------------------------------------------------------------------
/wiki/i-swagger-build-definition.md:
--------------------------------------------------------------------------------
1 | # ISwaggerBuildDefinition
2 |
3 | ## setBasePath: string
4 |
5 | Define base URL for all API.
6 |
7 | * Optional.
8 | * Default is "/"
9 |
10 | ## setOpenapi: string
11 |
12 | Define version of OpenAPI.
13 |
14 | * Optional.
15 |
16 | ## setInfo : [SwaggerInfo](./i-swagger-setInfo.md)
17 |
18 | Define setInfo.
19 |
20 | ## setConsumes: string[]
21 |
22 | Define the MIME types supported by the API for setConsumes. The root-level definition can be overridden in individual operations.
23 |
24 | * Optional
25 | * Default is [SwaggerDefinition](./swagger-definition-constant.md).Consume.JSON or "application/json".
26 |
27 | ## setProduces: string[]
28 |
29 | Define the MIME types supported by the API for setProduces. The root-level definition can be overridden in individual operations.
30 |
31 | * Optional
32 | * Default is [SwaggerDefinition](./swagger-definition-constant.md).Consume.JSON or "application/json".
33 |
34 | ## setSchemes: string[]
35 |
36 | Define Schemes.
37 |
38 | * Optional
39 | * Default is [SwaggerDefinition](./swagger-definition-constant.md).Scheme.HTTP = "http"
40 |
41 | ## setHost: string
42 |
43 | Define setHost.
44 |
45 | * Optional
46 |
47 | ## models: {[key: string]: [ISwaggerBuildDefinitionModel](./i-swagger-build-definition-model.md)}
48 |
49 | Define all model.
50 |
51 | * Required
52 |
53 | ## externalDocs: [ISwaggerExternalDocs](./i-swagger-external-docs.md)
54 |
55 | Define external docs
56 |
57 | * Optional
58 |
59 | ## securityDefinitions: {[key: string]: [ISwaggerSecurityDefinition](./i-swagger-security-definition.md)}
60 |
61 | Define security definitions
62 |
63 | * Optional
64 |
65 | ## responses: {[key: string]: [IApiOperationArgsBaseResponse](./i-api-operation-args-base-response.md)}
66 |
67 | Define global responses
68 |
69 | * Optional
70 |
--------------------------------------------------------------------------------
/wiki/i-swagger-contact.md:
--------------------------------------------------------------------------------
1 | # ISwaggerContact
2 |
3 | ## name: string
4 | Define name of contact.
5 | - Optional
6 |
7 | ## url: string
8 | Define url of contact.
9 | - Optional
10 |
11 | ## email: string
12 | Define email of contact.
13 | - Optional
--------------------------------------------------------------------------------
/wiki/i-swagger-external-docs.md:
--------------------------------------------------------------------------------
1 | # ISwaggerExternalDocs
2 |
3 | ## description: string
4 | Define description of external docs.
5 | - Optional
6 |
7 | ## url: string
8 | Define url of external docs/
9 | - Required
--------------------------------------------------------------------------------
/wiki/i-swagger-info.md:
--------------------------------------------------------------------------------
1 | # ISwaggerInfo
2 |
3 | ## title: string
4 | Define title of your API
5 | - Required
6 |
7 | ## description: string
8 | Define description of your API
9 | - Optional
10 |
11 | ## termsOfService: string
12 | - Optional
13 |
14 | ## contact: ISwaggerContact
15 | - Optional
16 |
17 | ## license: ISwaggerLicense
18 | - Optional
19 |
20 | ## version: string
21 | - Required
--------------------------------------------------------------------------------
/wiki/i-swagger-license.md:
--------------------------------------------------------------------------------
1 | # ISwaggerLicense
2 |
3 | ## name: string
4 | Define name of license.
5 | - Required
6 |
7 | ## url: string
8 | Define URL of license.
9 | - Optional
--------------------------------------------------------------------------------
/wiki/i-swagger-security-definition.md:
--------------------------------------------------------------------------------
1 | # ISwaggerSecurityDefinition
2 |
3 | ### type: string
4 | Define type of security
5 | - Required
6 |
7 | ### in: string
8 | Define where security set
9 | - Optional
10 |
11 | ### name: string
12 | Define name of security
13 | - Optional
--------------------------------------------------------------------------------
/wiki/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olivierlsc/swagger-express-ts/8707dcb28a8db30f5f3f16dd95c2c339146ce6a5/wiki/img/logo.png
--------------------------------------------------------------------------------
/wiki/img/swagger-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/olivierlsc/swagger-express-ts/8707dcb28a8db30f5f3f16dd95c2c339146ce6a5/wiki/img/swagger-ui.png
--------------------------------------------------------------------------------
/wiki/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | You can get the latest release and the type setDefinitions using npm:
4 |
5 | ```sh
6 | npm install swagger-express-ts reflect-metadata --save
7 | ```
8 |
9 | swagger-express-ts requires the experimentalDecorators, emitDecoratorMetadata and lib compilation options in your tsconfig.json file.
10 |
11 | ```json
12 | {
13 | "compilerOptions": {
14 | "target": "es5",
15 | "lib": ["es6"],
16 | "types": ["reflect-metadata", "swagger-express-ts"],
17 | "module": "commonjs",
18 | "moduleResolution": "node",
19 | "experimentalDecorators": true,
20 | "emitDecoratorMetadata": true
21 | }
22 | }
23 | ```
24 |
--------------------------------------------------------------------------------
/wiki/swagger-definition-constant.md:
--------------------------------------------------------------------------------
1 | # SwaggerDefinitionConstant
2 |
3 | ## Produce
4 |
5 | ### XML : string = "application/xml"
6 |
7 | ### JSON: string = "application/json"
8 |
9 | ## Scheme
10 |
11 | ### HTTP: string = "http"
12 |
13 | ### HTTPS: string = "https"
14 |
15 | ## Consume
16 |
17 | ### XML : string = "application/xml"
18 |
19 | ### JSON: string = "application/json"
20 |
21 | ## Model
22 |
23 | ### Type
24 |
25 | #### OBJECT: string = "object"
26 |
27 | ### Property
28 |
29 | #### Type
30 |
31 | ##### INTEGER: string = "integer"
32 |
33 | ##### STRING: string = "string"
34 |
35 | ##### ARRAY: string = "array"
36 |
37 | #### Format
38 |
39 | ##### INT_64: string = "int64"
40 |
41 | ## Parameter
42 |
43 | ### Type
44 |
45 | #### INTEGER: string = "integer"
46 |
47 | #### STRING: string = "string"
48 |
49 | #### ARRAY: string = "array"
50 |
51 | ### In
52 |
53 | #### PATH: string = "path"
54 |
55 | #### QUERY: string = "query"
56 |
57 | #### BODY: string = "body"
58 |
59 | #### FORM_DATA: string = "formData"
60 |
61 | ## Response
62 |
63 | ### Type
64 |
65 | #### INTEGER: string = "integer"
66 |
67 | #### STRING: string = "string"
68 |
69 | #### ARRAY: string = "array"
--------------------------------------------------------------------------------