airtasker / spot

Spot is a concise, developer-friendly way to describe your API contract.
Other
553 stars 38 forks source link

Handle Multiple JSDoc Correctly #1080

Open Noeyfan opened 3 years ago

Noeyfan commented 3 years ago

Describe the bug SPOT generate fail when multiple JSDoc occurred before any type definition.

To Reproduce Below is the api.ts file

// api.ts
import { api, body, endpoint, request, response, String } from "@airtasker/spot";

@api({ name: "my-api" })
class Api {}

@endpoint({
  method: "POST",
  path: "/users"
})
class CreateUser {
  @request
  request(
    @body body: CreateUserRequest
  ) {}
}

/**
 * Some Generaal Documentation
 */

/**
 * Some Interface Documentation
 */
interface CreateUserRequest {
  firstName: String;
}

Running command:

> spot generate -c api.ts -g openapi2 -l yaml -o .
> spot generate -c api.ts -g openapi3 -l yaml -o .
> spot generate -c api.ts -g json-schema -l json -o .

Will result in error:

Error: expected at most 1 jsDoc node, got 2

Expected behavior The generation should success and produce the expected result.

Screenshots N/A

Desktop (please complete the following information): @airtasker/spot/1.2.0 darwin-x64 node-v12.13.0

Additional context

Noeyfan commented 3 years ago

Let me know if this is done intentionally. Otherwise the fix is very simple, we can use the last parsed JSDoc instead of throwing errors.

lfportal commented 3 years ago

@Noeyfan This is intentional, jsDoc nodes are associated with the next non-jsDoc node immediately following it. Spot treats jsDoc nodes as part of its syntax and expects at most one jsDoc node associated with any node. To leave general comments in files you can use regular inline comments or block comments. None of the below comments will be parsed by Spot:

// inline comment
/* block comment */
/*
multi
line
block
comment
*/
Noeyfan commented 3 years ago

I see, the problem I've encountered is when file have a copyright info:

/**
 * @license
 * Copyright (c) 2015 Example Corporation Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy ...
 */

/**
 * Document for my interface
 */
interface IFoo { }

I understand we can probably use block comment for copyright info, but seems it go against the convention, https://jsdoc.app/tags-license.html, and could result in issue for other toolings.

So using the immediate JSDoc before the definition instead of fail the generation still seems a correct thing to do.

lfportal commented 3 years ago

Ah I see.

So using the immediate JSDoc before the definition instead of fail the generation still seems a correct thing to do.

Your suggestion is appropriate 👍.