openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.39k stars 447 forks source link

Generate subset of schema #1682

Open yethee opened 2 months ago

yethee commented 2 months ago

Description

I've OpenAPI schema with multiple the security schemes. Some paths are public and some are internal.

How to get types for public paths (methods) only?

Proposal

May be we can add an option to filter by path, tags or operation id?

--filter 'operation=foo' --filter 'operaton=bar' // include only matched by operation id
--filter 'operation!=foo'                        // exclude path by operation id
--filter 'tag!=tag name'                         // excude by tag
ghost commented 2 months ago

Have you tried using the Redocly config to do this? I don't know anything about Redocly, but here's what I have found which I have not tested yet... If I do test it and it works, I'll put the answer here as well as in discussion #1655

The filter-out decorator seems like it might do what I want based on the existence of an x- property, but I'm really not sure.

The path-excludes-patterns rule seems like a lint rule so I wonder if that might just cause errors.

ghost commented 2 months ago

Actually the filter-in decorator looks like the best way so far - https://redocly.com/docs/cli/decorators/filter-in/

With this, you can annotate your OpenAPI schemas with a property like x-area: "feature1" or x-area: "feature2" and then use the filterin decorator in your openapi-typescript redocly config to choose only paths with one of the x-area values.

According to the Redocly cli readme:

Transform an OpenAPI description

If your OpenAPI description isn't everything you hoped it would be, enhance it with the Redocly decorators feature. This allows you to:

  • Publish reference docs with a subset of endpoints for public use ...
ghost commented 2 months ago

Welp, this didn't work at all. It seems like decorators are not supported or something. When I used the following redocly.yaml file, it still produced a ./src/api.ts file with all the endpoints.

apis:
  main:
    root: http://localhost:43020/api/v1/docs/json
    x-openapi-ts:
      output: ./src/api.ts
    decorators:
      filter-in:
        property: operationId
        value: [connectRepo]
    rules:
      operation-operationId-unique: error
      operation-parameters-unique: error
      path-not-include-query: error
      spec: 3.0

I suppose my next step might be to just use redocly to produce a temporary openapi schema file to feed into openapi-typescript, but I'm going to stop here for now.

ghost commented 2 months ago

OK I didn't stop there. The workaround that I described above should have worked because redocly produces a new api.yaml schema file for me but then openapi-typescript froze when I fed that file into it.

Here's what I tried basically: install the redocly cli, create a config file for it and use that to create a whole new filtered openapi schema file for openapi-typescript to use.

Steps:

Finally, I have gotten openapi-typescript to produce a file that includes only a subset of my API paths. (See my next comment for actually making it work!)

redocly.yaml file for the redocly cli:

apis:
  main:
    root: http://localhost:43020/api/v1/docs/json
    decorators:
      filter-in:
        property: operationId
        value: [connectRepo]
    rules:
      operation-operationId-unique: error
      operation-parameters-unique: error
      path-not-include-query: error
      spec: error

openapi-typescript.yaml file for the openapi-typescript cli:

apis:
  main:
    root: api.yaml
    x-openapi-ts:
      output: ./src/api.ts

NOTE: This openapi-typescript.yaml file caused openapi-typescript to freeze. Don't use it, just use the cli.

ghost commented 2 months ago

I got my workaround working by skipping the use of the openapi-typescript.yaml file and just feeding the temporary api.yaml schema produced by redocly bundle directly into the openapi-typescript command line, like this:

openapi-typescript ./api.yaml -o ./src/api.ts

So my full package script command is now:

REDOCLY_TELEMETRY=off redocly bundle main --config=start.yaml -o api.yaml &&
openapi-typescript ./api.yaml -o ./src/api.ts &&
rm ./api.yaml

As you can see I added a third part of that command to rm ./api.yaml. I also renamed the redocly.yaml file to start.yaml to prevent openapi-typescript from automatically using it.

So, with that, I have successfully gotten openapi-typescript to produce a subset of my API.