nestjs-openapi 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +91 -23
- package/dist/index.d.ts +91 -23
- package/dist/index.mjs +146 -28
- package/dist/internal.d.mts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.mjs +1 -1
- package/dist/shared/{nestjs-openapi.NtbZNAvU.d.mts → nestjs-openapi.CAanamW0.d.mts} +219 -219
- package/dist/shared/{nestjs-openapi.NtbZNAvU.d.ts → nestjs-openapi.CAanamW0.d.ts} +219 -219
- package/dist/shared/{nestjs-openapi.DeikubMm.mjs → nestjs-openapi.Nd-wGr8A.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { S as SpecFileNotFoundError, a as
|
|
2
|
-
export { c as ConfigLoadError, C as ConfigNotFoundError, ae as ConfigService, e as ConfigValidationError, D as DtoGlobResolutionError, E as EntryNotFoundError, I as InvalidMethodError, B as MethodExtractionService, M as MissingGenericSchemaTempFileCleanupError, f as MissingGenericSchemaTempFileWriteError, n as ModuleTraversalService, ad as OutputService, P as ProjectInitError, i as ProjectService, j as ProjectServiceLive, h as PublicApiError, a0 as SchemaGenerationError, a1 as SchemaService, ac as ValidationService, a9 as applyConstraintsToSchema, av as categorizeBrokenRefs, d as defineConfig, a7 as extractClassConstraints, a5 as extractClassValidationInfo, a6 as extractClassValidationInfoEffect, a2 as extractPropertyConstraints, a4 as extractPropertyValidationInfo, V as filterInternalSchemas, W as filterInternalSchemasEffect, Q as filterSchemas, R as filterSchemasEffect, af as findConfigFile, aw as formatValidationResult, g as generate, _ as generateSchemas, $ as generateSchemasFromFiles, ak as generatorServicesLayer, l as getAllControllers, am as getArrayInitializer, z as getControllerMethodInfos, A as getControllerMethodInfosEffect, p as getControllerName, o as getControllerPrefix, t as getControllerTags, s as getDecoratorName, u as getHttpDecorator, r as getHttpMethods, x as getMethodInfo, y as getMethodInfoEffect, aq as getModuleDecoratorArg, at as getModuleMetadata, k as getModules, a8 as getRequiredProperties, an as getStringLiteralValue, ao as getSymbolFromIdentifier, v as isHttpDecorator, q as isHttpMethod, ap as isModuleClass, a3 as isPropertyOptional, aj as loadAndResolveConfig, ah as loadConfig, ag as loadConfigFromFile, m as makeProjectContext, N as mergeGeneratedSchemas, O as mergeGeneratedSchemasEffect, K as mergeSchemas, L as mergeSchemasEffect, aa as mergeValidationConstraints, ab as mergeValidationConstraintsEffect, w as normalizePath, T as normalizeSchemas, U as normalizeSchemasEffect, X as normalizeStructureRefs, Y as normalizeStructureRefsEffect, as as resolveArrayOfClasses, ar as resolveClassFromExpression, al as resolveClassFromSymbol, ai as resolveConfig, Z as toPascalCase, F as transformMethod, G as transformMethodEffect, H as transformMethods, J as transformMethodsEffect, au as validateSpec } from './shared/nestjs-openapi.
|
|
1
|
+
import { S as SpecFileNotFoundError, a as SpecFileParseError, b as SpecFileReadError } from './shared/nestjs-openapi.Nd-wGr8A.mjs';
|
|
2
|
+
export { c as ConfigLoadError, C as ConfigNotFoundError, ae as ConfigService, e as ConfigValidationError, D as DtoGlobResolutionError, E as EntryNotFoundError, I as InvalidMethodError, B as MethodExtractionService, M as MissingGenericSchemaTempFileCleanupError, f as MissingGenericSchemaTempFileWriteError, n as ModuleTraversalService, ad as OutputService, P as ProjectInitError, i as ProjectService, j as ProjectServiceLive, h as PublicApiError, a0 as SchemaGenerationError, a1 as SchemaService, ac as ValidationService, a9 as applyConstraintsToSchema, av as categorizeBrokenRefs, d as defineConfig, a7 as extractClassConstraints, a5 as extractClassValidationInfo, a6 as extractClassValidationInfoEffect, a2 as extractPropertyConstraints, a4 as extractPropertyValidationInfo, V as filterInternalSchemas, W as filterInternalSchemasEffect, Q as filterSchemas, R as filterSchemasEffect, af as findConfigFile, aw as formatValidationResult, g as generate, _ as generateSchemas, $ as generateSchemasFromFiles, ak as generatorServicesLayer, l as getAllControllers, am as getArrayInitializer, z as getControllerMethodInfos, A as getControllerMethodInfosEffect, p as getControllerName, o as getControllerPrefix, t as getControllerTags, s as getDecoratorName, u as getHttpDecorator, r as getHttpMethods, x as getMethodInfo, y as getMethodInfoEffect, aq as getModuleDecoratorArg, at as getModuleMetadata, k as getModules, a8 as getRequiredProperties, an as getStringLiteralValue, ao as getSymbolFromIdentifier, v as isHttpDecorator, q as isHttpMethod, ap as isModuleClass, a3 as isPropertyOptional, aj as loadAndResolveConfig, ah as loadConfig, ag as loadConfigFromFile, m as makeProjectContext, N as mergeGeneratedSchemas, O as mergeGeneratedSchemasEffect, K as mergeSchemas, L as mergeSchemasEffect, aa as mergeValidationConstraints, ab as mergeValidationConstraintsEffect, w as normalizePath, T as normalizeSchemas, U as normalizeSchemasEffect, X as normalizeStructureRefs, Y as normalizeStructureRefsEffect, as as resolveArrayOfClasses, ar as resolveClassFromExpression, al as resolveClassFromSymbol, ai as resolveConfig, Z as toPascalCase, F as transformMethod, G as transformMethodEffect, H as transformMethods, J as transformMethodsEffect, au as validateSpec } from './shared/nestjs-openapi.Nd-wGr8A.mjs';
|
|
3
3
|
import { readFileSync } from 'node:fs';
|
|
4
4
|
import { fail } from 'node:assert';
|
|
5
5
|
import { resolve } from 'node:path';
|
|
6
6
|
import { Module } from '@nestjs/common';
|
|
7
|
-
import { Effect, Exit, Cause, Option } from 'effect';
|
|
7
|
+
import { Effect, Either, Exit, Cause, Option } from 'effect';
|
|
8
8
|
export { generateAsync, generate as generateEffect, generateFromConfigAsync, generateFromConfigEffect, generatePathsAsync, generatePathsEffect } from './internal.mjs';
|
|
9
9
|
import 'node:crypto';
|
|
10
10
|
import 'ts-morph';
|
|
@@ -94,21 +94,40 @@ function generateSwaggerUiHtml(title, jsonPath) {
|
|
|
94
94
|
</body>
|
|
95
95
|
</html>`;
|
|
96
96
|
}
|
|
97
|
+
function isErrorWithCode(cause, code) {
|
|
98
|
+
return cause !== null && typeof cause === "object" && "code" in cause && cause.code === code;
|
|
99
|
+
}
|
|
100
|
+
function getSpecFileCandidates(filePath, options = {}) {
|
|
101
|
+
const candidates = [filePath];
|
|
102
|
+
candidates.push(...options.fallbackSpecFiles ?? []);
|
|
103
|
+
return [...new Set(candidates)];
|
|
104
|
+
}
|
|
105
|
+
const readSpecFileContentEffect = (filePath) => Effect.try({
|
|
106
|
+
try: () => readFileSync(resolve(process.cwd(), filePath), "utf-8"),
|
|
107
|
+
catch: (cause) => isErrorWithCode(cause, "ENOENT") ? SpecFileNotFoundError.create(filePath) : SpecFileReadError.create(filePath, cause)
|
|
108
|
+
});
|
|
97
109
|
const loadSpecFileEffect = Effect.fn("OpenApiModule.loadSpecFile")(
|
|
98
|
-
function* (filePath) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
function* (filePath, options = {}) {
|
|
111
|
+
for (const candidate of getSpecFileCandidates(filePath, options)) {
|
|
112
|
+
const contentResult = yield* readSpecFileContentEffect(candidate).pipe(
|
|
113
|
+
Effect.either
|
|
114
|
+
);
|
|
115
|
+
if (Either.isLeft(contentResult)) {
|
|
116
|
+
if (contentResult.left instanceof SpecFileNotFoundError) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
return yield* Effect.fail(contentResult.left);
|
|
120
|
+
}
|
|
121
|
+
return yield* Effect.try({
|
|
122
|
+
try: () => JSON.parse(contentResult.right),
|
|
123
|
+
catch: (cause) => SpecFileParseError.create(candidate, cause)
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return yield* Effect.fail(SpecFileNotFoundError.create(filePath));
|
|
108
127
|
}
|
|
109
128
|
);
|
|
110
|
-
function loadSpecFile(filePath) {
|
|
111
|
-
const exit = Effect.runSyncExit(loadSpecFileEffect(filePath));
|
|
129
|
+
function loadSpecFile(filePath, options = {}) {
|
|
130
|
+
const exit = Effect.runSyncExit(loadSpecFileEffect(filePath, options));
|
|
112
131
|
if (Exit.isSuccess(exit)) {
|
|
113
132
|
return exit.value;
|
|
114
133
|
}
|
|
@@ -131,6 +150,7 @@ function resolveOptions(options) {
|
|
|
131
150
|
}
|
|
132
151
|
return {
|
|
133
152
|
specFile: options.specFile,
|
|
153
|
+
fallbackSpecFiles: options.fallbackSpecFiles ?? [],
|
|
134
154
|
enabled: options.enabled ?? true,
|
|
135
155
|
jsonPath: options.jsonPath ?? "/openapi.json",
|
|
136
156
|
swagger: {
|
|
@@ -140,6 +160,26 @@ function resolveOptions(options) {
|
|
|
140
160
|
}
|
|
141
161
|
};
|
|
142
162
|
}
|
|
163
|
+
function resolveOptionsWithSpecTitle(options, spec) {
|
|
164
|
+
return {
|
|
165
|
+
...options,
|
|
166
|
+
swagger: {
|
|
167
|
+
...options.swagger,
|
|
168
|
+
title: options.swagger.title || spec.info.title
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function createOpenApiModuleState(options) {
|
|
173
|
+
const resolvedOptions = resolveOptions(options);
|
|
174
|
+
if (!resolvedOptions.enabled) {
|
|
175
|
+
return { options: resolvedOptions };
|
|
176
|
+
}
|
|
177
|
+
const spec = loadSpecFile(resolvedOptions.specFile, resolvedOptions);
|
|
178
|
+
return {
|
|
179
|
+
spec,
|
|
180
|
+
options: resolveOptionsWithSpecTitle(resolvedOptions, spec)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
143
183
|
_OpenApiModule_decorators = [Module({})];
|
|
144
184
|
let _OpenApiModule = class _OpenApiModule {
|
|
145
185
|
/**
|
|
@@ -149,8 +189,8 @@ let _OpenApiModule = class _OpenApiModule {
|
|
|
149
189
|
* @returns Dynamic module configuration
|
|
150
190
|
*/
|
|
151
191
|
static forRoot(options) {
|
|
152
|
-
const
|
|
153
|
-
if (!
|
|
192
|
+
const state = createOpenApiModuleState(options);
|
|
193
|
+
if (!state.options.enabled || !state.spec) {
|
|
154
194
|
return {
|
|
155
195
|
module: _OpenApiModule,
|
|
156
196
|
providers: [],
|
|
@@ -158,25 +198,17 @@ let _OpenApiModule = class _OpenApiModule {
|
|
|
158
198
|
exports: []
|
|
159
199
|
};
|
|
160
200
|
}
|
|
161
|
-
const spec = loadSpecFile(resolvedOptions.specFile);
|
|
162
|
-
const finalOptions = {
|
|
163
|
-
...resolvedOptions,
|
|
164
|
-
swagger: {
|
|
165
|
-
...resolvedOptions.swagger,
|
|
166
|
-
title: resolvedOptions.swagger.title || spec.info.title
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
201
|
const providers = [
|
|
170
202
|
{
|
|
171
203
|
provide: OPENAPI_MODULE_OPTIONS,
|
|
172
|
-
useValue:
|
|
204
|
+
useValue: state.options
|
|
173
205
|
},
|
|
174
206
|
{
|
|
175
207
|
provide: OPENAPI_SPEC,
|
|
176
|
-
useValue: spec
|
|
208
|
+
useValue: state.spec
|
|
177
209
|
}
|
|
178
210
|
];
|
|
179
|
-
const controllers = createOpenApiControllers(
|
|
211
|
+
const controllers = createOpenApiControllers(state.options, state.spec);
|
|
180
212
|
return {
|
|
181
213
|
module: _OpenApiModule,
|
|
182
214
|
providers,
|
|
@@ -184,11 +216,97 @@ let _OpenApiModule = class _OpenApiModule {
|
|
|
184
216
|
exports: [OPENAPI_MODULE_OPTIONS, OPENAPI_SPEC]
|
|
185
217
|
};
|
|
186
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Register OpenAPI JSON and Swagger UI routes on an already-created Nest app.
|
|
221
|
+
*
|
|
222
|
+
* Use this when the route config depends on services that are only available
|
|
223
|
+
* during bootstrap. For module-level static config, prefer `forRoot()`.
|
|
224
|
+
*/
|
|
225
|
+
static setup(path, app, documentSource, options = {}) {
|
|
226
|
+
if (options.enabled === false) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const spec = loadDocumentSource(documentSource);
|
|
230
|
+
const httpAdapter = app.getHttpAdapter();
|
|
231
|
+
const swaggerPath = resolveSetupPath(path, app, options);
|
|
232
|
+
const jsonPath = resolveJsonDocumentUrl(swaggerPath, app, options);
|
|
233
|
+
if (shouldServeJson(options.raw)) {
|
|
234
|
+
httpAdapter.get(jsonPath, (_request, response) => {
|
|
235
|
+
sendResponse(response, spec, "application/json");
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (options.ui !== false) {
|
|
239
|
+
httpAdapter.get(swaggerPath, (_request, response) => {
|
|
240
|
+
sendResponse(
|
|
241
|
+
response,
|
|
242
|
+
generateSwaggerUiHtml(
|
|
243
|
+
options.customSiteTitle ?? spec.info.title,
|
|
244
|
+
jsonPath
|
|
245
|
+
),
|
|
246
|
+
"text/html"
|
|
247
|
+
);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
187
251
|
};
|
|
188
252
|
_init = __decoratorStart();
|
|
189
253
|
_OpenApiModule = __decorateElement(_init, 0, "OpenApiModule", _OpenApiModule_decorators, _OpenApiModule);
|
|
190
254
|
__runInitializers(_init, 1, _OpenApiModule);
|
|
191
255
|
let OpenApiModule = _OpenApiModule;
|
|
256
|
+
function loadDocumentSource(source) {
|
|
257
|
+
if (typeof source === "function") {
|
|
258
|
+
return source();
|
|
259
|
+
}
|
|
260
|
+
if (isDocumentFileSource(source)) {
|
|
261
|
+
return loadSpecFile(source.specFile, source);
|
|
262
|
+
}
|
|
263
|
+
return source;
|
|
264
|
+
}
|
|
265
|
+
function isDocumentFileSource(source) {
|
|
266
|
+
return source !== null && typeof source === "object" && "specFile" in source && typeof source.specFile === "string";
|
|
267
|
+
}
|
|
268
|
+
function resolveSetupPath(path, app, options) {
|
|
269
|
+
return joinRoutePath(
|
|
270
|
+
options.useGlobalPrefix === true ? getGlobalPrefix(app) : void 0,
|
|
271
|
+
path
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
function resolveJsonDocumentUrl(finalSwaggerPath, app, options) {
|
|
275
|
+
if (!options.jsonDocumentUrl) {
|
|
276
|
+
return `${finalSwaggerPath}-json`;
|
|
277
|
+
}
|
|
278
|
+
return joinRoutePath(
|
|
279
|
+
options.useGlobalPrefix === true ? getGlobalPrefix(app) : void 0,
|
|
280
|
+
options.jsonDocumentUrl
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
function getGlobalPrefix(app) {
|
|
284
|
+
const appWithConfig = app;
|
|
285
|
+
return appWithConfig.config?.getGlobalPrefix?.() ?? "";
|
|
286
|
+
}
|
|
287
|
+
function shouldServeJson(raw) {
|
|
288
|
+
return raw === void 0 || raw === true || Array.isArray(raw) && raw.length > 0;
|
|
289
|
+
}
|
|
290
|
+
function joinRoutePath(...parts) {
|
|
291
|
+
return `/${parts.filter((part) => part !== void 0 && part !== "").map((part) => part.replace(/^\/+|\/+$/g, "")).filter((part) => part.length > 0).join("/")}`;
|
|
292
|
+
}
|
|
293
|
+
function sendResponse(response, body, contentType) {
|
|
294
|
+
const responseLike = response;
|
|
295
|
+
responseLike.setHeader?.("Content-Type", contentType);
|
|
296
|
+
if (contentType === "application/json" && responseLike.json) {
|
|
297
|
+
responseLike.json(body);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (responseLike.type && responseLike.send) {
|
|
301
|
+
responseLike.type(contentType).send(body);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (responseLike.send) {
|
|
305
|
+
responseLike.send(body);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
responseLike.end?.(typeof body === "string" ? body : JSON.stringify(body));
|
|
309
|
+
}
|
|
192
310
|
function createJsonController(controllerPath, spec) {
|
|
193
311
|
class JsonSpecController {
|
|
194
312
|
getSpec() {
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { E as GenerateOptions, x as generate, y as generateAsync, D as generateFromConfigAsync, B as generateFromConfigEffect, A as generatePathsAsync, z as generatePathsEffect } from './shared/nestjs-openapi.
|
|
1
|
+
export { E as GenerateOptions, x as generate, y as generateAsync, D as generateFromConfigAsync, B as generateFromConfigEffect, A as generatePathsAsync, z as generatePathsEffect } from './shared/nestjs-openapi.CAanamW0.mjs';
|
|
2
2
|
import 'effect';
|
|
3
3
|
import 'ts-morph';
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { E as GenerateOptions, x as generate, y as generateAsync, D as generateFromConfigAsync, B as generateFromConfigEffect, A as generatePathsAsync, z as generatePathsEffect } from './shared/nestjs-openapi.
|
|
1
|
+
export { E as GenerateOptions, x as generate, y as generateAsync, D as generateFromConfigAsync, B as generateFromConfigEffect, A as generatePathsAsync, z as generatePathsEffect } from './shared/nestjs-openapi.CAanamW0.js';
|
|
2
2
|
import 'effect';
|
|
3
3
|
import 'ts-morph';
|
package/dist/internal.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
|
-
import { i as ProjectService, n as ModuleTraversalService, B as MethodExtractionService, J as transformMethodsEffect, ax as generateEffect, ay as runProjectApiPromise, ak as generatorServicesLayer, az as runtimeLayerFor, aA as runGeneratorApiPromise } from './shared/nestjs-openapi.
|
|
2
|
+
import { i as ProjectService, n as ModuleTraversalService, B as MethodExtractionService, J as transformMethodsEffect, ax as generateEffect, ay as runProjectApiPromise, ak as generatorServicesLayer, az as runtimeLayerFor, aA as runGeneratorApiPromise } from './shared/nestjs-openapi.Nd-wGr8A.mjs';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:path';
|
|
5
5
|
import 'node:crypto';
|