Skip to content

defineRouteMeta excludes falsy enum values ​​from OpenAPI definition #3892

@nogic1008

Description

@nogic1008

Environment

  • Node.js: 24.11.1
  • Nuxt: 4.2.2
  • nitropack: 2.12.9

Reproduction

  1. Enable OpenAPI feature (set experimental.openAPI to true)
  2. Write OpenAPI meta within defineRouteMeta that contains falsy value (ex. 0, "") in enum
    defineRouteMeta({
      openAPI: {
        parameters: [
          {
            in: 'query',
            name: 'val',
            schema: { type: 'integer', enum: [0, 1, 2, 3, 4] },
          },
        ],
      },
    });
  3. Launch server and access to /_openapi.json

https://stackblitz.com/edit/github-fxzr4xvy?file=server%2Froutes%2Findex.ts

Describe the bug

OpenAPI json does not contain falsy value in enum.

{
  "openapi": "3.1.0",
  "info": {
    "title": "Nitro Server Routes"
  },
  "servers": [
    {
      "url": "http://localhost:3000",
      "description": "Local Development Server",
      "variables": {}
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "App Routes"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "val",
            "schema": {
              "type": "integer",
              "enum": [
                // missing 0!!!
                1,
                2,
                3,
                4
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
    // snipped...
  }
}

Additional context

This bug is caused by using filter(Boolean) for filtering in the astToObject function.

function astToObject(node: Expression | Literal): any {
  switch (node.type) {
    case "ObjectExpression": {
      const obj: Record<string, any> = {};
      for (const prop of node.properties) {
        if (prop.type === "Property") {
          const key = (prop.key as any).name ?? (prop.key as any).value;
          obj[key] = astToObject(prop.value as any);
        }
      }
      return obj;
    }
    case "ArrayExpression": {
      // filter(Boolean) rejects all falsy value (0, "", NaN...)
      return node.elements.map((el) => astToObject(el as any)).filter(Boolean);
      // To exclude null and undefined only, use:
      return node.elements.map((el) => astToObject(el as any)).filter(o => o != null);
    }
    case "Literal": {
      return node.value;
    }
    // No default
  }
}

Logs

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions