swagger-typescript-api 13.9.3 → 13.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +14 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +14 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +25 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +25 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-BeBS6icj.cjs → src-C6CxNImi.cjs} +106 -11
- package/dist/src-C6CxNImi.cjs.map +1 -0
- package/dist/{src-D2qG03ZJ.mjs → src-CxQXlsuV.mjs} +106 -11
- package/dist/src-CxQXlsuV.mjs.map +1 -0
- package/package.json +5 -5
- package/templates/base/content-type-accessors.ejs +18 -0
- package/templates/base/data-contracts.ejs +10 -0
- package/templates/base/enum-data-contract.ejs +6 -1
- package/templates/base/http-clients/axios-http-client.ejs +16 -2
- package/templates/base/http-clients/fetch-http-client.ejs +21 -7
- package/templates/default/procedure-call.ejs +3 -8
- package/templates/modular/api.ejs +4 -0
- package/templates/modular/procedure-call.ejs +3 -8
- package/dist/src-BeBS6icj.cjs.map +0 -1
- package/dist/src-D2qG03ZJ.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swagger-typescript-api",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.11.0",
|
|
4
4
|
"description": "Generate the API client for Fetch or Axios from an OpenAPI Specification",
|
|
5
5
|
"homepage": "https://github.com/acacode/swagger-typescript-api",
|
|
6
6
|
"bugs": "https://github.com/acacode/swagger-typescript-api/issues",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@apidevtools/swagger-parser": "12.1.0",
|
|
48
48
|
"@biomejs/js-api": "4.0.0",
|
|
49
|
-
"@biomejs/wasm-nodejs": "2.4.
|
|
49
|
+
"@biomejs/wasm-nodejs": "2.4.16",
|
|
50
50
|
"@types/swagger-schema-official": "^2.0.25",
|
|
51
51
|
"c12": "^3.3.3",
|
|
52
52
|
"citty": "^0.2.1",
|
|
@@ -63,17 +63,17 @@
|
|
|
63
63
|
"yummies": "7.19.4"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@biomejs/biome": "2.4.
|
|
66
|
+
"@biomejs/biome": "2.4.16",
|
|
67
67
|
"@changesets/changelog-github": "0.7.0",
|
|
68
68
|
"@changesets/cli": "2.31.0",
|
|
69
69
|
"@tsconfig/node20": "20.1.9",
|
|
70
70
|
"@tsconfig/strictest": "2.0.8",
|
|
71
|
-
"@types/node": "25.9.
|
|
71
|
+
"@types/node": "25.9.1",
|
|
72
72
|
"@types/swagger2openapi": "7.0.4",
|
|
73
73
|
"axios": "1.16.1",
|
|
74
74
|
"tsdown": "0.21.10",
|
|
75
75
|
"typedoc": "0.28.19",
|
|
76
|
-
"vitest": "4.1.
|
|
76
|
+
"vitest": "4.1.7"
|
|
77
77
|
},
|
|
78
78
|
"engines": {
|
|
79
79
|
"node": ">=20"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { config } = it;
|
|
3
|
+
const isUnion = config.enumStyle === "union";
|
|
4
|
+
|
|
5
|
+
// camelCase keys (Json, FormData, …) are used by http-client templates as CT.Json, CT.FormData, …
|
|
6
|
+
// They mirror the ContentType property names so the access pattern is identical regardless of enumStyle.
|
|
7
|
+
const v = {
|
|
8
|
+
Json: isUnion ? '"application/json"' : "ContentType.Json",
|
|
9
|
+
JsonApi: isUnion ? '"application/vnd.api+json"' : "ContentType.JsonApi",
|
|
10
|
+
FormData: isUnion ? '"multipart/form-data"' : "ContentType.FormData",
|
|
11
|
+
UrlEncoded: isUnion ? '"application/x-www-form-urlencoded"' : "ContentType.UrlEncoded",
|
|
12
|
+
Text: isUnion ? '"text/plain"' : "ContentType.Text",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// UPPER_SNAKE aliases (JSON, FORM_DATA, …) are used by procedure-call templates as
|
|
16
|
+
// requestContentKind["JSON"], matching the CONTENT_KIND constants produced by schema-routes.ts.
|
|
17
|
+
return { ...v, JSON: v.Json, JSON_API: v.JsonApi, FORM_DATA: v.FormData, URL_ENCODED: v.UrlEncoded, TEXT: v.Text };
|
|
18
|
+
%>
|
|
@@ -25,6 +25,16 @@ const dataContractTemplates = {
|
|
|
25
25
|
type: (contract) => {
|
|
26
26
|
return `type ${contract.name}${buildGenerics(contract)} = ${contract.content}`;
|
|
27
27
|
},
|
|
28
|
+
const: (contract) => {
|
|
29
|
+
const entries = contract.$content
|
|
30
|
+
.map(({ key, value }) => ` ${key}: ${value}`)
|
|
31
|
+
.join(',\n');
|
|
32
|
+
const typeExport = contract.internal ? '' : 'export ';
|
|
33
|
+
return (
|
|
34
|
+
`const ${contract.name} = {\n${entries},\n} as const\n` +
|
|
35
|
+
`${typeExport}type ${contract.name} = (typeof ${contract.name})[keyof typeof ${contract.name}]`
|
|
36
|
+
);
|
|
37
|
+
},
|
|
28
38
|
}
|
|
29
39
|
%>
|
|
30
40
|
|
|
@@ -3,7 +3,12 @@ const { contract, utils, config } = it;
|
|
|
3
3
|
const { formatDescription, require, _ } = utils;
|
|
4
4
|
const { name, $content } = contract;
|
|
5
5
|
%>
|
|
6
|
-
<% if (config.
|
|
6
|
+
<% if (config.enumStyle === "const") { %>
|
|
7
|
+
export const <%~ name %> = {
|
|
8
|
+
<%~ _.map($content, ({ key, value }) => `${key}: ${value}`).join(",\n ") %>
|
|
9
|
+
} as const;
|
|
10
|
+
export type <%~ name %> = (typeof <%~ name %>)[keyof typeof <%~ name %>];
|
|
11
|
+
<% } else if (config.enumStyle === "union") { %>
|
|
7
12
|
export type <%~ name %> = <%~ _.map($content, ({ value }) => value).join(" | ") %>
|
|
8
13
|
<% } else { %>
|
|
9
14
|
export enum <%~ name %> {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<%
|
|
2
2
|
const { apiConfig, generateResponses, config } = it;
|
|
3
|
+
const CT = includeFile("@base/content-type-accessors", { config });
|
|
3
4
|
%>
|
|
4
5
|
|
|
5
6
|
import type { AxiosInstance, AxiosRequestConfig, HeadersDefaults, ResponseType, AxiosResponse } from "axios";
|
|
@@ -30,6 +31,18 @@ export interface ApiConfig<SecurityDataType = unknown> extends Omit<AxiosRequest
|
|
|
30
31
|
format?: ResponseType;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
<% if (config.enumStyle === "const") { %>
|
|
35
|
+
export const ContentType = {
|
|
36
|
+
Json: "application/json",
|
|
37
|
+
JsonApi: "application/vnd.api+json",
|
|
38
|
+
FormData: "multipart/form-data",
|
|
39
|
+
UrlEncoded: "application/x-www-form-urlencoded",
|
|
40
|
+
Text: "text/plain",
|
|
41
|
+
} as const;
|
|
42
|
+
export type ContentType = (typeof ContentType)[keyof typeof ContentType];
|
|
43
|
+
<% } else if (config.enumStyle === "union") { %>
|
|
44
|
+
export type ContentType = "application/json" | "application/vnd.api+json" | "multipart/form-data" | "application/x-www-form-urlencoded" | "text/plain";
|
|
45
|
+
<% } else { %>
|
|
33
46
|
export enum ContentType {
|
|
34
47
|
Json = "application/json",
|
|
35
48
|
JsonApi = "application/vnd.api+json",
|
|
@@ -37,6 +50,7 @@ export enum ContentType {
|
|
|
37
50
|
UrlEncoded = "application/x-www-form-urlencoded",
|
|
38
51
|
Text = "text/plain",
|
|
39
52
|
}
|
|
53
|
+
<% } %>
|
|
40
54
|
|
|
41
55
|
export class HttpClient<SecurityDataType = unknown> {
|
|
42
56
|
public instance: AxiosInstance;
|
|
@@ -116,11 +130,11 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
116
130
|
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
117
131
|
const responseFormat = (format || this.format) || undefined;
|
|
118
132
|
|
|
119
|
-
if (type ===
|
|
133
|
+
if (type === <%~ CT.FormData %> && body && body !== null && typeof body === "object") {
|
|
120
134
|
body = this.createFormData(body as Record<string, unknown>);
|
|
121
135
|
}
|
|
122
136
|
|
|
123
|
-
if (type ===
|
|
137
|
+
if (type === <%~ CT.Text %> && body && body !== null && typeof body !== "string") {
|
|
124
138
|
body = JSON.stringify(body);
|
|
125
139
|
}
|
|
126
140
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<%
|
|
2
2
|
const { apiConfig, generateResponses, config } = it;
|
|
3
|
+
const CT = includeFile("@base/content-type-accessors", { config });
|
|
3
4
|
%>
|
|
4
5
|
|
|
5
6
|
export type QueryParamsType = Record<string | number, any>;
|
|
@@ -41,6 +42,18 @@ export interface HttpResponse<D extends unknown, E extends unknown = unknown> ex
|
|
|
41
42
|
|
|
42
43
|
type CancelToken = Symbol | string | number;
|
|
43
44
|
|
|
45
|
+
<% if (config.enumStyle === "const") { %>
|
|
46
|
+
export const ContentType = {
|
|
47
|
+
Json: "application/json",
|
|
48
|
+
JsonApi: "application/vnd.api+json",
|
|
49
|
+
FormData: "multipart/form-data",
|
|
50
|
+
UrlEncoded: "application/x-www-form-urlencoded",
|
|
51
|
+
Text: "text/plain",
|
|
52
|
+
} as const;
|
|
53
|
+
export type ContentType = (typeof ContentType)[keyof typeof ContentType];
|
|
54
|
+
<% } else if (config.enumStyle === "union") { %>
|
|
55
|
+
export type ContentType = "application/json" | "application/vnd.api+json" | "multipart/form-data" | "application/x-www-form-urlencoded" | "text/plain";
|
|
56
|
+
<% } else { %>
|
|
44
57
|
export enum ContentType {
|
|
45
58
|
Json = "application/json",
|
|
46
59
|
JsonApi = "application/vnd.api+json",
|
|
@@ -48,6 +61,7 @@ export enum ContentType {
|
|
|
48
61
|
UrlEncoded = "application/x-www-form-urlencoded",
|
|
49
62
|
Text = "text/plain",
|
|
50
63
|
}
|
|
64
|
+
<% } %>
|
|
51
65
|
|
|
52
66
|
export class HttpClient<SecurityDataType = unknown> {
|
|
53
67
|
public baseUrl: string = "<%~ apiConfig.baseUrl %>";
|
|
@@ -103,10 +117,10 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
private contentFormatters: Record<ContentType, (input: any) => any> = {
|
|
106
|
-
[
|
|
107
|
-
[
|
|
108
|
-
[
|
|
109
|
-
[
|
|
120
|
+
[<%~ CT.Json %>]: (input:any) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
|
|
121
|
+
[<%~ CT.JsonApi %>]: (input:any) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
|
|
122
|
+
[<%~ CT.Text %>]: (input:any) => input !== null && typeof input !== "string" ? JSON.stringify(input) : input,
|
|
123
|
+
[<%~ CT.FormData %>]: (input: any) => {
|
|
110
124
|
if (input instanceof FormData) {
|
|
111
125
|
return input;
|
|
112
126
|
}
|
|
@@ -124,7 +138,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
124
138
|
return formData;
|
|
125
139
|
}, new FormData());
|
|
126
140
|
},
|
|
127
|
-
[
|
|
141
|
+
[<%~ CT.UrlEncoded %>]: (input: any) => this.toQueryString(input),
|
|
128
142
|
}
|
|
129
143
|
|
|
130
144
|
protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams {
|
|
@@ -181,7 +195,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
181
195
|
const secureParams = ((typeof secure === 'boolean' ? secure : this.baseApiParams.secure) && this.securityWorker && await this.securityWorker(this.securityData)) || {};
|
|
182
196
|
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
183
197
|
const queryString = query && this.toQueryString(query);
|
|
184
|
-
const payloadFormatter = this.contentFormatters[type ||
|
|
198
|
+
const payloadFormatter = this.contentFormatters[type || <%~ CT.Json %>];
|
|
185
199
|
const responseFormat = format || requestParams.format;
|
|
186
200
|
|
|
187
201
|
return this.customFetch(
|
|
@@ -190,7 +204,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
190
204
|
...requestParams,
|
|
191
205
|
headers: {
|
|
192
206
|
...(requestParams.headers || {}),
|
|
193
|
-
...(type && type !==
|
|
207
|
+
...(type && type !== <%~ CT.FormData %> ? { "Content-Type": type } : {}),
|
|
194
208
|
},
|
|
195
209
|
signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
|
|
196
210
|
body: typeof body === "undefined" || body === null ? null : payloadFormatter(body),
|
|
@@ -31,8 +31,9 @@ const rawWrapperArgs = config.extractRequestParams ?
|
|
|
31
31
|
_.compact([
|
|
32
32
|
requestParams && {
|
|
33
33
|
name: extractedRequestParamsName,
|
|
34
|
-
optional:
|
|
34
|
+
optional: route.request.requestParamsOptional,
|
|
35
35
|
type: getInlineParseContent(requestParams),
|
|
36
|
+
defaultValue: route.request.requestParamsOptional ? '{}' : undefined,
|
|
36
37
|
},
|
|
37
38
|
...(!requestParams ? pathParams : []),
|
|
38
39
|
payload,
|
|
@@ -52,13 +53,7 @@ const wrapperArgs = _
|
|
|
52
53
|
.join(', ')
|
|
53
54
|
|
|
54
55
|
// RequestParams["type"]
|
|
55
|
-
const requestContentKind = {
|
|
56
|
-
"JSON": "ContentType.Json",
|
|
57
|
-
"JSON_API": "ContentType.JsonApi",
|
|
58
|
-
"URL_ENCODED": "ContentType.UrlEncoded",
|
|
59
|
-
"FORM_DATA": "ContentType.FormData",
|
|
60
|
-
"TEXT": "ContentType.Text",
|
|
61
|
-
}
|
|
56
|
+
const requestContentKind = includeFile("@base/content-type-accessors", { config });
|
|
62
57
|
// RequestParams["format"]
|
|
63
58
|
const responseContentKind = {
|
|
64
59
|
"JSON": '"json"',
|
|
@@ -8,7 +8,11 @@ const dataContracts = _.map(modelTypes, "name");
|
|
|
8
8
|
|
|
9
9
|
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import type { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
|
|
10
10
|
|
|
11
|
+
<% if (config.enumStyle === "union") { %>
|
|
12
|
+
import { HttpClient, RequestParams, type ContentType, HttpResponse } from "./<%~ config.fileNames.httpClient %>";
|
|
13
|
+
<% } else { %>
|
|
11
14
|
import { HttpClient, RequestParams, ContentType, HttpResponse } from "./<%~ config.fileNames.httpClient %>";
|
|
15
|
+
<% } %>
|
|
12
16
|
<% if (dataContracts.length) { %>
|
|
13
17
|
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
|
|
14
18
|
<% } %>
|
|
@@ -31,8 +31,9 @@ const rawWrapperArgs = config.extractRequestParams ?
|
|
|
31
31
|
_.compact([
|
|
32
32
|
requestParams && {
|
|
33
33
|
name: extractedRequestParamsName,
|
|
34
|
-
optional:
|
|
34
|
+
optional: route.request.requestParamsOptional,
|
|
35
35
|
type: getInlineParseContent(requestParams),
|
|
36
|
+
defaultValue: route.request.requestParamsOptional ? '{}' : undefined,
|
|
36
37
|
},
|
|
37
38
|
...(!requestParams ? pathParams : []),
|
|
38
39
|
payload,
|
|
@@ -52,13 +53,7 @@ const wrapperArgs = _
|
|
|
52
53
|
.join(', ')
|
|
53
54
|
|
|
54
55
|
// RequestParams["type"]
|
|
55
|
-
const requestContentKind = {
|
|
56
|
-
"JSON": "ContentType.Json",
|
|
57
|
-
"JSON_API": "ContentType.JsonApi",
|
|
58
|
-
"URL_ENCODED": "ContentType.UrlEncoded",
|
|
59
|
-
"FORM_DATA": "ContentType.FormData",
|
|
60
|
-
"TEXT": "ContentType.Text",
|
|
61
|
-
}
|
|
56
|
+
const requestContentKind = includeFile("@base/content-type-accessors", { config });
|
|
62
57
|
// RequestParams["format"]
|
|
63
58
|
const responseContentKind = {
|
|
64
59
|
"JSON": '"json"',
|