@application-kit/bootstrap 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +20 -2
- package/dist/cjs/swagger/index.d.ts +3 -0
- package/dist/cjs/swagger/index.js +19 -0
- package/dist/cjs/swagger/setup-swagger.d.ts +3 -0
- package/dist/cjs/swagger/setup-swagger.js +25 -0
- package/dist/cjs/swagger/swagger-options.interface.d.ts +6 -0
- package/dist/cjs/swagger/swagger-options.interface.js +2 -0
- package/dist/cjs/swagger/swagger.environment.d.ts +3 -0
- package/dist/cjs/swagger/swagger.environment.js +25 -0
- package/dist/esm/swagger/index.d.ts +3 -0
- package/dist/esm/swagger/index.js +3 -0
- package/dist/esm/swagger/setup-swagger.d.ts +3 -0
- package/dist/esm/swagger/setup-swagger.js +18 -0
- package/dist/esm/swagger/swagger-options.interface.d.ts +6 -0
- package/dist/esm/swagger/swagger-options.interface.js +1 -0
- package/dist/esm/swagger/swagger.environment.d.ts +3 -0
- package/dist/esm/swagger/swagger.environment.js +21 -0
- package/package.json +19 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @application-kit/bootstrap
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9ee9bfa: Вход `@application-kit/bootstrap/swagger`: `setupSwagger(app, { include, path?, version? })` публикует документ OpenAPI,
|
|
8
|
+
только если `SWAGGER_ENABLED` включён явно. `@nestjs/swagger` — optional peer, его тянет только этот вход.
|
|
9
|
+
|
|
3
10
|
## 0.3.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @application-kit/bootstrap
|
|
2
2
|
|
|
3
3
|
Бутстрап процессов NestJS: web на Fastify с периметром, consumer с сервером метрик и CLI на nestjs-console. Состав
|
|
4
|
-
модулей, Swagger и хуки метрик знает приложение: пакет собирает процесс из его корневого модуля и опций. Порт, число
|
|
4
|
+
модулей, контроллеры документа Swagger и хуки метрик знает приложение: пакет собирает процесс из его корневого модуля и опций. Порт, число
|
|
5
5
|
прокси и порт метрик — переменные окружения контракта чарта; невалидное значение роняет старт.
|
|
6
6
|
|
|
7
7
|
## Установка
|
|
@@ -21,6 +21,7 @@ Peer-зависимости — `@nestjs/common`, `@nestjs/core`, `nestjs-pino`;
|
|
|
21
21
|
| `@application-kit/bootstrap/web` | `webBootstrap`, `createFastifyApplication` — web-процесс на Fastify | `@nestjs/platform-fastify`, `@fastify/cookie`, `class-validator`, `class-transformer`, `@opentelemetry/api`, `@libs-for-dev/nestjs-config-module` |
|
|
22
22
|
| `@application-kit/bootstrap/consumer` | `consumerBootstrap` — процесс-консьюмер без HTTP-слоя | `class-validator`, `class-transformer`, `@libs-for-dev/nestjs-config-module` |
|
|
23
23
|
| `@application-kit/bootstrap/cli` | `cliBootstrap` — CLI-процесс | `nestjs-console` |
|
|
24
|
+
| `@application-kit/bootstrap/swagger` | `setupSwagger` — документ OpenAPI web-процесса по выключателю | `@nestjs/swagger`, `class-validator`, `class-transformer`, `@libs-for-dev/nestjs-config-module` |
|
|
24
25
|
|
|
25
26
|
Корневого входа нет: web-процессу `nestjs-console` не нужен, CLI — Fastify.
|
|
26
27
|
|
|
@@ -31,8 +32,9 @@ Peer-зависимости — `@nestjs/common`, `@nestjs/core`, `nestjs-pino`;
|
|
|
31
32
|
| `PORT` | web | `3000` | порт `listen` на `0.0.0.0` |
|
|
32
33
|
| `TRUST_PROXY_HOPS` | web | `0` | сколько прокси перед приложением доверенные; `0` — только сокет |
|
|
33
34
|
| `METRICS_PORT` | consumer | `3001` | порт отдельного сервера `/metrics` |
|
|
35
|
+
| `SWAGGER_ENABLED` | web | `false` | публиковать ли документ `setupSwagger`; выключают `false`, `0` и пустая строка |
|
|
34
36
|
|
|
35
|
-
Значение — целое не меньше 0 (порт — не больше 65535). Иное (`abc`, `1.5`, `-1`) — `ClassValidationError` с именем
|
|
37
|
+
Значение числовых переменных — целое не меньше 0 (порт — не больше 65535). Иное (`abc`, `1.5`, `-1`) — `ClassValidationError` с именем
|
|
36
38
|
переменной до создания приложения: `Number('abc')` дал бы `NaN`, и доверенных прокси молча стало бы ноль.
|
|
37
39
|
|
|
38
40
|
## Web
|
|
@@ -82,6 +84,22 @@ await app.listen(port, '0.0.0.0')
|
|
|
82
84
|
| `cookie` | `{}` | опции `@fastify/cookie`; `false` — плагин не регистрируется |
|
|
83
85
|
| `configure` | — | `(app) => void`, зовётся после хука request-id, до интерцептора и пайпа |
|
|
84
86
|
|
|
87
|
+
## Swagger
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { setupSwagger } from '@application-kit/bootstrap/swagger'
|
|
91
|
+
|
|
92
|
+
const options = {
|
|
93
|
+
configure: (app) => {
|
|
94
|
+
setupSwagger(app, { include: [HealthHttpModule, MetricsHttpModule] })
|
|
95
|
+
},
|
|
96
|
+
} satisfies FastifyApplicationOptionsInterface
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Документ описывает всю серверную поверхность и аутентификации не требует, поэтому без `SWAGGER_ENABLED` он не
|
|
100
|
+
публикуется. В документ попадают контроллеры модулей из `include`, `operationId` — имя метода. UI отдаётся по `path`
|
|
101
|
+
(по умолчанию `swagger`), JSON — по `<path>-json`, версия в `info` — `version` (по умолчанию `1.0`).
|
|
102
|
+
|
|
85
103
|
## Consumer
|
|
86
104
|
|
|
87
105
|
```ts
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./setup-swagger.js"), exports);
|
|
18
|
+
__exportStar(require("./swagger-options.interface.js"), exports);
|
|
19
|
+
__exportStar(require("./swagger.environment.js"), exports);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setupSwagger = void 0;
|
|
7
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
8
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
9
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
10
|
+
const swagger_environment_js_1 = require("./swagger.environment.js");
|
|
11
|
+
const DEFAULT_PATH = 'swagger';
|
|
12
|
+
const DEFAULT_VERSION = '1.0';
|
|
13
|
+
const setupSwagger = (app, options) => {
|
|
14
|
+
const environment = (0, nestjs_config_module_1.exposeObjectWithValidation)(node_process_1.default.env, swagger_environment_js_1.SwaggerEnvironment);
|
|
15
|
+
if (!environment.SWAGGER_ENABLED) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const document = swagger_1.SwaggerModule.createDocument(app, new swagger_1.DocumentBuilder().setVersion(options.version ?? DEFAULT_VERSION)
|
|
19
|
+
.build(), {
|
|
20
|
+
include: options.include,
|
|
21
|
+
operationIdFactory: (_controllerKey, methodKey) => methodKey,
|
|
22
|
+
});
|
|
23
|
+
swagger_1.SwaggerModule.setup(options.path ?? DEFAULT_PATH, app, document);
|
|
24
|
+
};
|
|
25
|
+
exports.setupSwagger = setupSwagger;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SwaggerEnvironment = void 0;
|
|
13
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const class_validator_1 = require("class-validator");
|
|
16
|
+
class SwaggerEnvironment {
|
|
17
|
+
SWAGGER_ENABLED = false;
|
|
18
|
+
}
|
|
19
|
+
exports.SwaggerEnvironment = SwaggerEnvironment;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsBoolean)(),
|
|
23
|
+
(0, nestjs_config_module_1.ParseBoolean)(),
|
|
24
|
+
__metadata("design:type", Object)
|
|
25
|
+
], SwaggerEnvironment.prototype, "SWAGGER_ENABLED", void 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { exposeObjectWithValidation } from '@libs-for-dev/nestjs-config-module';
|
|
2
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { SwaggerEnvironment } from './swagger.environment.js';
|
|
5
|
+
const DEFAULT_PATH = 'swagger';
|
|
6
|
+
const DEFAULT_VERSION = '1.0';
|
|
7
|
+
export const setupSwagger = (app, options) => {
|
|
8
|
+
const environment = exposeObjectWithValidation(process.env, SwaggerEnvironment);
|
|
9
|
+
if (!environment.SWAGGER_ENABLED) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const document = SwaggerModule.createDocument(app, new DocumentBuilder().setVersion(options.version ?? DEFAULT_VERSION)
|
|
13
|
+
.build(), {
|
|
14
|
+
include: options.include,
|
|
15
|
+
operationIdFactory: (_controllerKey, methodKey) => methodKey,
|
|
16
|
+
});
|
|
17
|
+
SwaggerModule.setup(options.path ?? DEFAULT_PATH, app, document);
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { ParseBoolean } from '@libs-for-dev/nestjs-config-module';
|
|
11
|
+
import { Expose } from 'class-transformer';
|
|
12
|
+
import { IsBoolean } from 'class-validator';
|
|
13
|
+
export class SwaggerEnvironment {
|
|
14
|
+
SWAGGER_ENABLED = false;
|
|
15
|
+
}
|
|
16
|
+
__decorate([
|
|
17
|
+
Expose(),
|
|
18
|
+
IsBoolean(),
|
|
19
|
+
ParseBoolean(),
|
|
20
|
+
__metadata("design:type", Object)
|
|
21
|
+
], SwaggerEnvironment.prototype, "SWAGGER_ENABLED", void 0);
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@application-kit/bootstrap",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Бутстрап процессов NestJS: web на Fastify с периметром (доверенные прокси по хопам, request-id в каждом ответе, cookie, ValidationPipe с плоским списком ошибок, graceful shutdown), consumer с сервером метрик, CLI на nestjs-console с логгером pino; порты и прокси — из валидированного окружения",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bootstrap",
|
|
7
7
|
"fastify",
|
|
8
8
|
"nestjs",
|
|
9
|
-
"nestjs-console"
|
|
9
|
+
"nestjs-console",
|
|
10
|
+
"swagger"
|
|
10
11
|
],
|
|
11
12
|
"homepage": "https://gitlab.com/application-kit/application-kit/-/tree/main/packages/bootstrap",
|
|
12
13
|
"bugs": "https://gitlab.com/application-kit/application-kit/-/issues",
|
|
@@ -43,6 +44,16 @@
|
|
|
43
44
|
}
|
|
44
45
|
},
|
|
45
46
|
"./package.json": "./package.json",
|
|
47
|
+
"./swagger": {
|
|
48
|
+
"import": {
|
|
49
|
+
"types": "./dist/esm/swagger/index.d.ts",
|
|
50
|
+
"default": "./dist/esm/swagger/index.js"
|
|
51
|
+
},
|
|
52
|
+
"require": {
|
|
53
|
+
"types": "./dist/cjs/swagger/index.d.ts",
|
|
54
|
+
"default": "./dist/cjs/swagger/index.js"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
46
57
|
"./web": {
|
|
47
58
|
"import": {
|
|
48
59
|
"types": "./dist/esm/web/index.d.ts",
|
|
@@ -61,7 +72,7 @@
|
|
|
61
72
|
"dist"
|
|
62
73
|
],
|
|
63
74
|
"scripts": {
|
|
64
|
-
"build": "rm -rf ./dist && node ../../scripts/barrels.mjs create ./src/cli && node ../../scripts/barrels.mjs create ./src/consumer && node ../../scripts/barrels.mjs create ./src/web && tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json && node ../../scripts/barrels.mjs clean ./src && node ../../scripts/mark-cjs.mjs ./dist/cjs",
|
|
75
|
+
"build": "rm -rf ./dist && node ../../scripts/barrels.mjs create ./src/cli && node ../../scripts/barrels.mjs create ./src/consumer && node ../../scripts/barrels.mjs create ./src/swagger && node ../../scripts/barrels.mjs create ./src/web && tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json && node ../../scripts/barrels.mjs clean ./src && node ../../scripts/mark-cjs.mjs ./dist/cjs",
|
|
65
76
|
"lint:tsc": "tsc --noEmit --pretty --project .",
|
|
66
77
|
"test:mutation": "stryker run",
|
|
67
78
|
"test:unit": "vitest run"
|
|
@@ -75,6 +86,7 @@
|
|
|
75
86
|
"@nestjs/common": "^11.2.7",
|
|
76
87
|
"@nestjs/core": "^11.2.7",
|
|
77
88
|
"@nestjs/platform-fastify": "^11.2.7",
|
|
89
|
+
"@nestjs/swagger": "^11.4.8",
|
|
78
90
|
"@opentelemetry/api": "^1.9.1",
|
|
79
91
|
"@stryker-mutator/core": "^10.0.0",
|
|
80
92
|
"@stryker-mutator/vitest-runner": "^10.0.0",
|
|
@@ -96,6 +108,7 @@
|
|
|
96
108
|
"@nestjs/common": "^11.0.0",
|
|
97
109
|
"@nestjs/core": "^11.0.0",
|
|
98
110
|
"@nestjs/platform-fastify": "^11.0.0",
|
|
111
|
+
"@nestjs/swagger": "^11.0.0 || ^12.0.0",
|
|
99
112
|
"@opentelemetry/api": "^1.9.0",
|
|
100
113
|
"class-transformer": "^0.5.1",
|
|
101
114
|
"class-validator": "^0.15.1",
|
|
@@ -112,6 +125,9 @@
|
|
|
112
125
|
"@nestjs/platform-fastify": {
|
|
113
126
|
"optional": true
|
|
114
127
|
},
|
|
128
|
+
"@nestjs/swagger": {
|
|
129
|
+
"optional": true
|
|
130
|
+
},
|
|
115
131
|
"@opentelemetry/api": {
|
|
116
132
|
"optional": true
|
|
117
133
|
},
|