Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Three-dimensional Array type breaks #195

Open
mrclean-oa opened this issue Oct 13, 2021 · 2 comments
Open

[BUG] Three-dimensional Array type breaks #195

mrclean-oa opened this issue Oct 13, 2021 · 2 comments
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed

Comments

@mrclean-oa
Copy link

mrclean-oa commented Oct 13, 2021

Describe the bug
I am working with GeoJSON data and the data is represented as the following:

{
   "type":"MultiLineString",
   "coordinates":[
      [
         [
            10,
            10,
            0
         ],
         [
            20,
            20,
            1
         ],
         [
            10,
            40,
            2
         ]
      ]
   ]
}

So I would like to type the endpoint accordingly using a @typedef, I'm especially excited about using express-oas-validator, so I'd really like to get this to work:

/**
 * Index 0: The valid numbers for Longitude are between -180 and 180
 * Index 1: The valid numbers for Latitude are between -90 and 90
 * Index 2: The valid numbers for Altitude is a number greater than or equal to 0
 * @typedef {[number, number, number]} CoordinateArray
 */
/**
 * @typedef {object} GeoJSON
 * @property {string} type - enum:MultiLineString - the GeoJSON type
 * @property {array<array<array<CoordinateArray>>>} coordinates - the coordinates to the location
 */

When the coordinates property is {array<array<CoordinateArray>>} it works great, but you'll notice I'm missing a dimension. I have two arrays for property, and the tuple for the three numbers, yet it drops one of the arrays, see the image:
Screen Shot 2021-10-13 at 3 56 07 PM

When I add one more dimension (required for GeoJSON), it breaks in a confusing way, see "broken" image:
Screen Shot 2021-10-13 at 3 56 47 PM

It thinks it's an array of strings.

I thought I might be defining the tuple incorrectly, because of the dropped array mentioned earlier, so I tried a work around:

/**
 * @typedef {array} CoordinateArray
 * @property {number} - 0: The valid numbers for Longitude are between -180 and 180
 * @property {number} - 1: The valid numbers for Latitude are between -90 and 90
 * @property {number} - 2: The valid numbers for Altitude is a number greater than or equal to 0
 * 
 */

But then it comes out as an object instead of an array... that's no good.

So I tried doing this:

/**
 * Index 0: The valid numbers for Longitude are between -180 and 180
 * Index 1: The valid numbers for Latitude are between -90 and 90
 * Index 2: The valid numbers for Altitude is a number greater than or equal to 0
 * @typedef {[number, number, number][]} CoordinateArray
 */
/**
 * @typedef {object} GeoJSON
 * @property {string} type - enum:MultiLineString - the GeoJSON type
 * @property {array<array<CoordinateArray>>} coordinates - the coordinates to the location
 */

Adding brackets to the typedef for CoordinateArray, but it yields the same result as the "broken" screenshot.

At this point, I believe this is a bug with express-jsdoc-swagger, or maybe I'm doing something wrong?

To Reproduce

/**
 * Index 0: The valid numbers for Longitude are between -180 and 180
 * Index 1: The valid numbers for Latitude are between -90 and 90
 * Index 2: The valid numbers for Altitude is a number greater than or equal to 0
 * @typedef {[number, number, number]} CoordinateArray
 */
/**
 * @typedef {object} GeoJSON
 * @property {string} type - enum:MultiLineString - the GeoJSON type
 * @property {array<array<array<CoordinateArray>>>} coordinates - the coordinates to the location
 */

Expected behavior
I would expect to see this in Swagger UI:

{
  "id": 0,
  "id_user": 0,
  "geom": {
    "type": "MultiLineString",
    "coordinates": [
      [
        [
           0,
           0,
           0,
         ]
      ]
    ]
  },
  "title": "string",
  "notes": "string",
  "created_at": "2021-10-13T21:56:36.600Z",
  "updated_at": "2021-10-13T21:56:36.600Z"
}

Which would be equivalent to [number, number, number][][]. I'd love to define min and max values on the tuple but I'll settle for anything that unblocks me and would enable me to use the validation package y'all wrote.

Screenshots
When the coordinates property is {array<array<CoordinateArray>>} it works great, see the image:
Screen Shot 2021-10-13 at 3 56 07 PM

When I add one more dimension (required for GeoJSON), it breaks in a confusing way:
Screen Shot 2021-10-13 at 3 56 47 PM

Desktop (please complete the following information):

  • OS: macOS
  • Version 11.6

Additional context
Nope, nothing that I can think of

@mrclean-oa
Copy link
Author

mrclean-oa commented Oct 14, 2021

This JSDoc issue resolves 2D arrays, yet it is still seems present, since CoordinateArray[][] does not even render the coordinates key when I use bracket notation.

@mrclean-oa
Copy link
Author

mrclean-oa commented Oct 14, 2021

If it helps for debugging I manually ran doctrine (using the one installed by express-jsdoc-swagger):

const doctrine = require('doctrine');

var ast = doctrine.parse(
  `/**
    * Index 0 is Longitude - The valid numbers for Longitude are between -180 and 180.
    * Index 1 is Latitude - The valid numbers for Latitude are between -90 and 90.
    * Index 2 is Altitude - The valid numbers for Altitude is a number greater than or equal to 0.
    * @typedef {[integer, integer, integer]} CoordinateArray
    */
  /**
   * GeoJSON is a format for encoding a variety of geographic data structures using JavaScript Object Notation (JSON).
   * @typedef {object} GeoJSON
   * @property {string} type - enum:MultiLineString,Point,Position,MultiPoint,LineString,Polygon,MultiPolygon,GeometryCollection - the GeoJSON type
   * @property {array<array<CoordinatesArray>>} coordinates - the coordinates to the location
   */`,
  { unwrap: true }
);

console.log(JSON.stringify(ast, null, 2));

And got this result:

{
  "description": "Index 0 is Longitude - The valid numbers for Longitude are between -180 and 180.\nIndex 1 is Latitude - The valid numbers for Latitude are between -90 and 90.\nIndex 2 is Altitude - The valid numbers for Altitude is a number greater than or equal to 0.",
  "tags": [
    {
      "title": "typedef",
      "description": null,
      "type": {
        "type": "ArrayType",
        "elements": [
          {
            "type": "NameExpression",
            "name": "integer"
          },
          {
            "type": "NameExpression",
            "name": "integer"
          },
          {
            "type": "NameExpression",
            "name": "integer"
          }
        ]
      },
      "name": "CoordinateArray"
    },
    {
      "title": "typedef",
      "description": null,
      "type": {
        "type": "NameExpression",
        "name": "object"
      },
      "name": "GeoJSON"
    },
    {
      "title": "property",
      "description": "enum:MultiLineString,Point,Position,MultiPoint,LineString,Polygon,MultiPolygon,GeometryCollection - the GeoJSON type",
      "type": {
        "type": "NameExpression",
        "name": "string"
      },
      "name": "type"
    },
    {
      "title": "property",
      "description": "the coordinates to the location",
      "type": {
        "type": "TypeApplication",
        "expression": {
          "type": "NameExpression",
          "name": "array"
        },
        "applications": [
          {
            "type": "TypeApplication",
            "expression": {
              "type": "NameExpression",
              "name": "array"
            },
            "applications": [
              {
                "type": "NameExpression",
                "name": "CoordinatesArray"
              }
            ]
          }
        ]
      },
      "name": "coordinates"
    }
  ]
}

I don't know how to judge the result, but would be happy to close this if it appears to be a doctrine problem.

@kevinccbsg kevinccbsg added enhancement New feature or request help wanted Extra attention is needed bug Something isn't working labels Oct 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants