Comments (8)
Can you provide a reasoning for why these types aren't in your OpenAPI spec?
from openapi-ts.
Thank you for your response!
There is a module A that provides general UI logic, components etc, including generated abstract entities types based on the OpenAPI schema of this module.
And also there are several modules B, C, etc., which pull up module A as a dependency, and these modules describe types that inherit from the abstract entities types of module A.
Moreover, module A will also be used by third party developers who will add their own logic on top, and I would like them to directly import the types of module A instead of describing copies, otherwise there will be duplication of types descriptions and potential data inconsistency.
I don't know if I could properly explain the need, but import mappings are used in some other generators, for example, in https://github.com/OpenAPITools/openapi-generator (for multiple languages, including TS), because this adds more flexibility to the generation configuration.
from openapi-ts.
@dymovalex are you able to share a sample OpenAPI spec with current and expected results?
Are you currently using the library linked in your comment? I assume you're not using this package since it doesn't support the feature you're asking for. Why are you looking to switch?
from openapi-ts.
We've been using openapi-typescript-codegen in the project for a couple of years, but now the need for import mappings support has come to light.
Therefore, I am looking now for a suitable solution. The simplest solution for me, of course, if mappings support appears in this maintainable fork of openapi-typescript-codegen. Or I'll have to look for a completely different generator.
In the package I linked to in the comments above, two generators were considered:
typescript-fetch - does not support mappings
typescript - supports mappings, but in a version that differs from one we are using to generate Java code on the backend. Due to the fact that the project is large with custom mustache templates, transferring the backend to a new version seems to be a difficult task, and pulling two different versions of generators into the project seems inconvenient and potentially unreliable. Plus, to be honest, I don't really like the resulting generated code, it's very verbose and confusing (classes instead of types, for example).
And as for the samples, is not a real case, but describes the main idea:
Module A
We have schema:
components:
schemas:
AbstractComponent:
description: Abstract component
properties:
id:
type: string
required:
- id
AbstractButton:
description: Abstract button
properties:
width:
type: number
and result type:
/**
* Abstract component
*/
export type AbstractComponent = {
id: string
};
/**
* Abstract button
*/
export type AbstractButton = {
width?: number
};
Module B:
Current:
We have schema below. And we are forced to describe copies of AbstractComponent and AbstractButton in this module if we want to refer to these types:
components:
schemas:
AbstractComponent:
description: Abstract component
properties:
id:
type: string
required:
- id
AbstractButton:
description: Abstract button
properties:
width:
type: number
Button:
description: Button
allOf:
- $ref: "#/components/schemas/AbstractComponent"
- $ref: "#/components/schemas/AbstractButton"
- type: object
properties:
some:
type: string
And result models.ts
will look like this:
/**
* Abstract component
*/
export type AbstractComponent = {
id: string
};
/**
* Abstract button
*/
export type AbstractButton = {
width?: number
};
/**
* Button
*/
export type Button = AbstractComponent & AbstractButton & {
some?: string
};
Expected:
We describe config openapi-ts.importMappings.mjs
in root directory:
export default {
AbstractComponent: 'moduleA/AbstractComponent',
AbstractButton: 'moduleA/AbstractButton',
}
We have schema:
components:
schemas:
Button:
description: Button
allOf:
- $ref: "#/components/schemas/AbstractComponent"
- $ref: "#/components/schemas/AbstractButton"
- type: object
properties:
some:
type: string
And result models.ts
will look like this:
import { AbstractComponent } from 'moduleA/AbstractComponent';
import { AbstractButton } from 'moduleB/AbstractButton';
/**
* Button
*/
export type Button = AbstractComponent & AbstractButton & {
some?: string
};
from openapi-ts.
@dymovalex would what I propose here solve your problem?
Specifically:
TypeA:
$ref: './some/path/type_a.yaml#/components/schemas/TypeA'
or
TypeA:
$ref: 'http://some-url.com/openapi.yamll#/components/schemas/TypeA'
See relevant openapi docs: here. When using a reference from an external file or url we do handle generating the models/etc. So rather than providing third partys with module A, could you:
- Provide module A's openapi spec for them to use and they can extend there openapi spec off it. This could be a url or file provided.
- Generate module A to provide to third partys, but internally reference module A in your module B/C?
from openapi-ts.
Sounds like it might help, I'll try it. Thank you!
UPD
So far I've faced a problem that all the entities that I refer to through the local ref are typed as any
.
Maybe the problem is that the schema in the project consists of many schemas, which merge into one during the build.
from openapi-ts.
@dymovalex are you able provide an example of what module A and B specs look like? I could try it out myself and see what is happening.
from openapi-ts.
I solved problem with any
, it was due to type was not specified like 'object'.
But there's another problem:
moduleA.yaml
There are types Action and DataType
components:
schemas:
Action:
type: object
properties:
actionId:
type: string
parameterType:
$ref: "#/components/schemas/DataType"
returnType:
$ref: "#/components/schemas/DataType"
additionalProperties: false
required:
- actionId
- parameterType
- returnType
DataType:
type: object
properties:
a:
type: string
b:
type: integer
properties:
type: object
additionalProperties:
$ref: "#/components/schemas/DataType"
additionalProperties: false
required:
- a
- b
moduleB.yaml
Here DataType is used both separately and as part of the Action type
components:
schemas:
SomeAction:
type: object
properties:
actionProps:
$ref: '../../../moduleA.yaml#/components/schemas/Action'
Component:
type: object
properties:
name:
type: string
type:
$ref: '../../../moduleA.yaml#/components/schemas/DataType'
additionalProperties: false
required:
- name
- type
As a result I get in module B:
- Not a reference to the type, but a copy of it (it seems that you can live with this, but it's not very convenient)
- I get a strange import of the Component_properties_type, which actually does not exist and which causes a build error
import type { Component_properties_type } from './Component_properties_type';
export type SomeAction = {
actionProps?: {
actionId: string;
parameterType: Component_properties_type;
returnType: Component_properties_type;
};
}
import type { Component_properties_type } from './Component_properties_type';
export type Component = {
name: string;
type: {
a: string;
b: number;
properties?: Record<string, Component_properties_type>;
};
};
I suppose that adding a relative reference to the DataType
in Action
in Module A
itself can help fix it (not sure) but:
- Using relative references to types definitions that are in the same module and in the same schema is confusing
- There can be a lot of nesting in types and this problem will lead to 'relative path hell'
- Itโs not entirely clear what to do with types that have recursion, as DataType. If we also take into account the problem with copying a type rather than referring to it, Iโm not sure that this is basically possible to do.
Based on the above, it seems that in my case itโs simply impossible to do what I'm looking for without import mappings.
from openapi-ts.
Related Issues (20)
- The generated Service layer code contains Chinese characters HOT 11
- Use exported enums in type fields HOT 3
- It does not pickup typescript in monorepo environment w/ pnpm HOT 3
- Content type headers not passed onto request HOT 4
- Rename conflicting TypeScript identifiers
- DeprecationWarning: fs.Stats constructor is deprecated HOT 3
- export eslint.rules for external usage HOT 3
- Got client HOT 15
- Non-global clients/configs HOT 5
- Export services as module instead of class to enable tree shaking. HOT 10
- Unused @ts-expect-error comment HOT 4
- Support for exactOptionalPropertyTypes in tsconfig.json HOT 1
- Validate response against openapi schema HOT 1
- Standalone package for your client HOT 1
- [question] How does this package compare to `openapi-typescript`? HOT 2
- can't generate a node16 moduleResolution compatible package HOT 8
- Improve support for `Accept` and `Content-Type` headers
- Newly exported `DefaultService` does not exist HOT 4
- Export `FetchClient` interface
- Parameters with `in: header` cause incompatible types
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openapi-ts.