nestjs-openapi 0.1.1 → 0.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import 'tsx';
3
- import { g as generate, e as formatValidationResult } from './shared/nestjs-openapi.CCvQ3RSW.mjs';
3
+ import { g as generate, e as formatValidationResult } from './shared/nestjs-openapi.yWMsjl_8.mjs';
4
4
  import minimist from 'minimist';
5
5
  import { relative } from 'node:path';
6
6
  import { createRequire } from 'node:module';
@@ -9,7 +9,7 @@ import 'node:fs';
9
9
  import 'ts-morph';
10
10
  import 'glob';
11
11
  import 'js-yaml';
12
- import './shared/nestjs-openapi.CzNt1duF.mjs';
12
+ import './shared/nestjs-openapi.CBj9xHZ4.mjs';
13
13
  import 'ts-json-schema-generator';
14
14
  import 'node:crypto';
15
15
  import 'node:url';
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Effect, Context, Layer, Option } from 'effect';
2
- import { C as ConfigNotFoundError, O as OpenApiGeneratorConfig, a as ConfigError, R as ResolvedConfig, P as ProjectError, b as ProjectInitError, E as EntryNotFoundError, M as MethodInfo, c as OpenApiPaths$1 } from './shared/nestjs-openapi.BYUrTaMo.mjs';
3
- export { A as AnalysisError, i as ConfigLoadError, j as ConfigValidationError, G as GenerateOptions, k as GeneratorError, H as HttpMethod, I as InvalidMethodError, e as ParameterLocation, f as ResolvedParameter, h as ReturnTypeInfo, d as generateAsync, g as generateEffect } from './shared/nestjs-openapi.BYUrTaMo.mjs';
2
+ import { C as ConfigNotFoundError, O as OpenApiGeneratorConfig, a as ConfigError, R as ResolvedConfig, P as ProjectError, b as ProjectInitError, E as EntryNotFoundError, M as MethodInfo, c as OpenApiPaths$1 } from './shared/nestjs-openapi.OhsaHu32.mjs';
3
+ export { A as AnalysisError, i as ConfigLoadError, j as ConfigValidationError, G as GenerateOptions, k as GeneratorError, H as HttpMethod, I as InvalidMethodError, e as ParameterLocation, f as ResolvedParameter, h as ReturnTypeInfo, d as generateAsync, g as generateEffect } from './shared/nestjs-openapi.OhsaHu32.mjs';
4
4
  import { DynamicModule } from '@nestjs/common';
5
5
  import { Project, SourceFile, ClassDeclaration, MethodDeclaration, Decorator, Symbol, ObjectLiteralExpression, Expression } from 'ts-morph';
6
6
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Effect, Context, Layer, Option } from 'effect';
2
- import { C as ConfigNotFoundError, O as OpenApiGeneratorConfig, a as ConfigError, R as ResolvedConfig, P as ProjectError, b as ProjectInitError, E as EntryNotFoundError, M as MethodInfo, c as OpenApiPaths$1 } from './shared/nestjs-openapi.BYUrTaMo.js';
3
- export { A as AnalysisError, i as ConfigLoadError, j as ConfigValidationError, G as GenerateOptions, k as GeneratorError, H as HttpMethod, I as InvalidMethodError, e as ParameterLocation, f as ResolvedParameter, h as ReturnTypeInfo, d as generateAsync, g as generateEffect } from './shared/nestjs-openapi.BYUrTaMo.js';
2
+ import { C as ConfigNotFoundError, O as OpenApiGeneratorConfig, a as ConfigError, R as ResolvedConfig, P as ProjectError, b as ProjectInitError, E as EntryNotFoundError, M as MethodInfo, c as OpenApiPaths$1 } from './shared/nestjs-openapi.OhsaHu32.js';
3
+ export { A as AnalysisError, i as ConfigLoadError, j as ConfigValidationError, G as GenerateOptions, k as GeneratorError, H as HttpMethod, I as InvalidMethodError, e as ParameterLocation, f as ResolvedParameter, h as ReturnTypeInfo, d as generateAsync, g as generateEffect } from './shared/nestjs-openapi.OhsaHu32.js';
4
4
  import { DynamicModule } from '@nestjs/common';
5
5
  import { Project, SourceFile, ClassDeclaration, MethodDeclaration, Decorator, Symbol, ObjectLiteralExpression, Expression } from 'ts-morph';
6
6
 
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- export { c as categorizeBrokenRefs, d as defineConfig, f as findConfigFile, e as formatValidationResult, g as generate, b as loadAndResolveConfig, a as loadConfig, l as loadConfigFromFile, r as resolveConfig, v as validateSpec } from './shared/nestjs-openapi.CCvQ3RSW.mjs';
1
+ export { c as categorizeBrokenRefs, d as defineConfig, f as findConfigFile, e as formatValidationResult, g as generate, b as loadAndResolveConfig, a as loadConfig, l as loadConfigFromFile, r as resolveConfig, v as validateSpec } from './shared/nestjs-openapi.yWMsjl_8.mjs';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { Module } from '@nestjs/common';
5
5
  export { generateAsync, generate as generateEffect } from './internal.mjs';
6
- import { P as ProjectInitError, E as EntryNotFoundError } from './shared/nestjs-openapi.CzNt1duF.mjs';
7
- export { a as ConfigLoadError, C as ConfigNotFoundError, b as ConfigValidationError, I as InvalidMethodError, c as getAllControllers, q as getArrayInitializer, o as getControllerMethodInfos, e as getControllerName, d as getControllerPrefix, j as getControllerTags, h as getDecoratorName, k as getHttpDecorator, f as getHttpMethods, m as getMethodInfo, w as getModuleDecoratorArg, z as getModuleMetadata, g as getModules, s as getStringLiteralValue, u as getSymbolFromIdentifier, l as isHttpDecorator, i as isHttpMethod, v as isModuleClass, n as normalizePath, y as resolveArrayOfClasses, x as resolveClassFromExpression, r as resolveClassFromSymbol, t as transformMethod, p as transformMethods } from './shared/nestjs-openapi.CzNt1duF.mjs';
6
+ import { P as ProjectInitError, E as EntryNotFoundError } from './shared/nestjs-openapi.CBj9xHZ4.mjs';
7
+ export { a as ConfigLoadError, C as ConfigNotFoundError, b as ConfigValidationError, I as InvalidMethodError, c as getAllControllers, q as getArrayInitializer, o as getControllerMethodInfos, e as getControllerName, d as getControllerPrefix, j as getControllerTags, h as getDecoratorName, k as getHttpDecorator, f as getHttpMethods, m as getMethodInfo, w as getModuleDecoratorArg, z as getModuleMetadata, g as getModules, s as getStringLiteralValue, u as getSymbolFromIdentifier, l as isHttpDecorator, i as isHttpMethod, v as isModuleClass, n as normalizePath, y as resolveArrayOfClasses, x as resolveClassFromExpression, r as resolveClassFromSymbol, t as transformMethod, p as transformMethods } from './shared/nestjs-openapi.CBj9xHZ4.mjs';
8
8
  import { Context, Effect, Layer } from 'effect';
9
9
  import { Project } from 'ts-morph';
10
10
  import 'glob';
@@ -1,2 +1,2 @@
1
1
  import 'effect';
2
- export { G as GenerateOptions, g as generate, d as generateAsync } from './shared/nestjs-openapi.BYUrTaMo.mjs';
2
+ export { G as GenerateOptions, g as generate, d as generateAsync } from './shared/nestjs-openapi.OhsaHu32.mjs';
@@ -1,2 +1,2 @@
1
1
  import 'effect';
2
- export { G as GenerateOptions, g as generate, d as generateAsync } from './shared/nestjs-openapi.BYUrTaMo.js';
2
+ export { G as GenerateOptions, g as generate, d as generateAsync } from './shared/nestjs-openapi.OhsaHu32.js';
package/dist/internal.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Effect } from 'effect';
2
2
  import { Project } from 'ts-morph';
3
- import { E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos, p as transformMethods } from './shared/nestjs-openapi.CzNt1duF.mjs';
3
+ import { E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos, p as transformMethods } from './shared/nestjs-openapi.CBj9xHZ4.mjs';
4
4
 
5
5
  const generate = (options) => Effect.gen(function* () {
6
6
  yield* Effect.logInfo("Starting OpenAPI generation").pipe(
@@ -1306,10 +1306,16 @@ const tsTypeToOpenApiSchema = (tsType) => {
1306
1306
  }
1307
1307
  }
1308
1308
  if (trimmed.includes(" | ")) {
1309
- const types = trimmed.split(" | ").map((t) => t.trim());
1310
- return {
1311
- oneOf: types.map((type) => tsTypeToOpenApiSchema(type))
1312
- };
1309
+ const allMembers = trimmed.split(" | ").map((t) => t.trim());
1310
+ const hasNull = allMembers.includes("null");
1311
+ const types = allMembers.filter((t) => t !== "undefined" && t !== "null");
1312
+ if (types.length === 0) return { type: "object" };
1313
+ const schema = types.length === 1 ? tsTypeToOpenApiSchema(types[0]) : { oneOf: types.map((type) => tsTypeToOpenApiSchema(type)) };
1314
+ if (!hasNull) return schema;
1315
+ if (schema.$ref) {
1316
+ return { allOf: [{ $ref: schema.$ref }], nullable: true };
1317
+ }
1318
+ return { ...schema, nullable: true };
1313
1319
  }
1314
1320
  switch (trimmed.toLowerCase()) {
1315
1321
  case "string":
@@ -173,9 +173,12 @@ interface OpenApiSchema {
173
173
  readonly format?: string;
174
174
  readonly $ref?: string;
175
175
  readonly oneOf?: readonly OpenApiSchema[];
176
+ readonly allOf?: readonly OpenApiSchema[];
176
177
  readonly items?: OpenApiSchema;
177
178
  readonly properties?: Record<string, OpenApiSchema>;
178
179
  readonly required?: readonly string[];
180
+ /** OpenAPI 3.0 nullable flag */
181
+ readonly nullable?: boolean;
179
182
  }
180
183
  declare const OpenApiOperation: Schema.Struct<{
181
184
  operationId: typeof Schema.String;
@@ -173,9 +173,12 @@ interface OpenApiSchema {
173
173
  readonly format?: string;
174
174
  readonly $ref?: string;
175
175
  readonly oneOf?: readonly OpenApiSchema[];
176
+ readonly allOf?: readonly OpenApiSchema[];
176
177
  readonly items?: OpenApiSchema;
177
178
  readonly properties?: Record<string, OpenApiSchema>;
178
179
  readonly required?: readonly string[];
180
+ /** OpenAPI 3.0 nullable flag */
181
+ readonly nullable?: boolean;
179
182
  }
180
183
  declare const OpenApiOperation: Schema.Struct<{
181
184
  operationId: typeof Schema.String;
@@ -4,7 +4,7 @@ import { join, dirname, resolve } from 'node:path';
4
4
  import { Project } from 'ts-morph';
5
5
  import { globSync, glob } from 'glob';
6
6
  import yaml from 'js-yaml';
7
- import { C as ConfigNotFoundError, a as ConfigLoadError, b as ConfigValidationError, p as transformMethods, A as extractClassConstraints, B as getRequiredProperties, D as mergeValidationConstraints, E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos } from './nestjs-openapi.CzNt1duF.mjs';
7
+ import { C as ConfigNotFoundError, a as ConfigLoadError, b as ConfigValidationError, p as transformMethods, A as extractClassConstraints, B as getRequiredProperties, D as mergeValidationConstraints, E as EntryNotFoundError, g as getModules, o as getControllerMethodInfos } from './nestjs-openapi.CBj9xHZ4.mjs';
8
8
  import { createGenerator } from 'ts-json-schema-generator';
9
9
  import { randomUUID } from 'node:crypto';
10
10
  import { pathToFileURL } from 'node:url';
@@ -466,6 +466,12 @@ const extractReferencedSchemas = (paths) => {
466
466
  if (schema.oneOf) {
467
467
  schema.oneOf.forEach(extractFromSchema);
468
468
  }
469
+ if (schema.allOf) {
470
+ schema.allOf.forEach(extractFromSchema);
471
+ }
472
+ if (schema.anyOf) {
473
+ schema.anyOf.forEach(extractFromSchema);
474
+ }
469
475
  if (schema.properties) {
470
476
  Object.values(schema.properties).forEach(extractFromSchema);
471
477
  }
@@ -529,7 +535,14 @@ const extractNestedReferences = (schemas, knownSchemas) => {
529
535
  };
530
536
  const convertToOpenApiSchema = (schema) => {
531
537
  const result = {};
532
- if (schema.type) result["type"] = schema.type;
538
+ if (Array.isArray(schema.type)) {
539
+ const nonNull = schema.type.filter((t) => t !== "null");
540
+ const isNullable = nonNull.length < schema.type.length;
541
+ result["type"] = nonNull.length === 1 ? nonNull[0] : schema.type;
542
+ if (isNullable && nonNull.length === 1) result["nullable"] = true;
543
+ } else if (schema.type) {
544
+ result["type"] = schema.type;
545
+ }
533
546
  if (schema.format) result["format"] = schema.format;
534
547
  if (schema.$ref) {
535
548
  result["$ref"] = schema.$ref.replace(
@@ -700,14 +713,81 @@ const transformSchemasForVersion = (schemas, version) => {
700
713
  ])
701
714
  );
702
715
  };
716
+ const transformOperationToV31 = (operation) => {
717
+ const parameters = operation.parameters?.map((param) => ({
718
+ ...param,
719
+ schema: transformSchemaToV31(param.schema)
720
+ }));
721
+ const requestBody = operation.requestBody ? {
722
+ ...operation.requestBody,
723
+ content: Object.fromEntries(
724
+ Object.entries(operation.requestBody.content).map(
725
+ ([contentType, mediaType]) => [
726
+ contentType,
727
+ { ...mediaType, schema: transformSchemaToV31(mediaType.schema) }
728
+ ]
729
+ )
730
+ )
731
+ } : void 0;
732
+ const responses = Object.fromEntries(
733
+ Object.entries(operation.responses).map(([code, response]) => [
734
+ code,
735
+ response.content ? {
736
+ ...response,
737
+ content: Object.fromEntries(
738
+ Object.entries(response.content).map(
739
+ ([contentType, mediaType]) => [
740
+ contentType,
741
+ {
742
+ ...mediaType,
743
+ schema: transformSchemaToV31(mediaType.schema)
744
+ }
745
+ ]
746
+ )
747
+ )
748
+ } : response
749
+ ])
750
+ );
751
+ return {
752
+ ...operation,
753
+ ...parameters && { parameters },
754
+ ...requestBody && { requestBody },
755
+ responses
756
+ };
757
+ };
758
+ const HTTP_METHODS = /* @__PURE__ */ new Set([
759
+ "get",
760
+ "put",
761
+ "post",
762
+ "delete",
763
+ "options",
764
+ "head",
765
+ "patch",
766
+ "trace"
767
+ ]);
768
+ const transformPathsForVersion = (paths, version) => {
769
+ if (version === "3.0.3") return paths;
770
+ return Object.fromEntries(
771
+ Object.entries(paths).map(([path, pathItem]) => [
772
+ path,
773
+ Object.fromEntries(
774
+ Object.entries(pathItem).map(
775
+ ([key, value]) => HTTP_METHODS.has(key) ? [key, transformOperationToV31(value)] : [key, value]
776
+ )
777
+ )
778
+ ])
779
+ );
780
+ };
703
781
  const transformSpecForVersion = (spec, version) => {
704
782
  if (version === "3.0.3") {
705
783
  return { ...spec, openapi: version };
706
784
  }
707
785
  const transformedSchemas = spec.components?.schemas ? transformSchemasForVersion(spec.components.schemas, version) : void 0;
786
+ const transformedPaths = transformPathsForVersion(spec.paths, version);
708
787
  return {
709
788
  ...spec,
710
789
  openapi: version,
790
+ paths: transformedPaths,
711
791
  ...transformedSchemas && {
712
792
  components: {
713
793
  ...spec.components,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-openapi",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Static code analysis tool to generate OpenAPI specifications from NestJS applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",