Skip to content

Commit 0caea2c

Browse files
authored
Fix enum const parsing for substrings of primitive types (#1384)
Signed-off-by: Sora Morimoto <[email protected]>
1 parent cacdb10 commit 0caea2c

File tree

6 files changed

+600
-3
lines changed

6 files changed

+600
-3
lines changed

.changeset/chubby-ears-shine.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"swagger-typescript-api": patch
3+
---
4+
5+
Fix enum const parsing for substrings of primitive types.

src/schema-parser/base-schema-parsers/enum.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export class EnumSchemaParser extends MonoSchemaParser {
158158
}
159159

160160
formatEnumKey = ({ key, value }) => {
161-
let formatted;
161+
let formatted: string | undefined;
162162

163163
if (key) {
164164
formatted = this.typeNameFormatter.format(key, {

src/schema-parser/schema-utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ export class SchemaUtils {
266266
);
267267
}
268268

269-
let resultType;
269+
let resultType: string;
270270

271-
if (this.isConstantSchema(schema)) {
271+
if (this.isConstantSchema(schema) && !schema.enum) {
272272
resultType = this.formatJsValue(schema.const);
273273
} else {
274274
const primitiveType = this.getSchemaPrimitiveType(schema);

tests/__snapshots__/extended.test.ts.snap

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67475,6 +67475,295 @@ export class Api<
6747567475
"
6747667476
`;
6747767477

67478+
exports[`extended > 'issue-1057' 1`] = `
67479+
"/* eslint-disable */
67480+
/* tslint:disable */
67481+
// @ts-nocheck
67482+
/*
67483+
* ---------------------------------------------------------------
67484+
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
67485+
* ## ##
67486+
* ## AUTHOR: acacode ##
67487+
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
67488+
* ---------------------------------------------------------------
67489+
*/
67490+
67491+
export interface MySchema {
67492+
not_working?: MySchemaNotWorkingEnum;
67493+
working?: MySchemaWorkingEnum;
67494+
}
67495+
67496+
export enum MySchemaNotWorkingEnum {
67497+
PhoneNumber = "phone_number",
67498+
}
67499+
67500+
export enum MySchemaWorkingEnum {
67501+
EmailAddress = "email_address",
67502+
}
67503+
67504+
export type QueryParamsType = Record<string | number, any>;
67505+
export type ResponseFormat = keyof Omit<Body, "body" | "bodyUsed">;
67506+
67507+
export interface FullRequestParams extends Omit<RequestInit, "body"> {
67508+
/** set parameter to \`true\` for call \`securityWorker\` for this request */
67509+
secure?: boolean;
67510+
/** request path */
67511+
path: string;
67512+
/** content type of request body */
67513+
type?: ContentType;
67514+
/** query params */
67515+
query?: QueryParamsType;
67516+
/** format of response (i.e. response.json() -> format: "json") */
67517+
format?: ResponseFormat;
67518+
/** request body */
67519+
body?: unknown;
67520+
/** base url */
67521+
baseUrl?: string;
67522+
/** request cancellation token */
67523+
cancelToken?: CancelToken;
67524+
}
67525+
67526+
export type RequestParams = Omit<
67527+
FullRequestParams,
67528+
"body" | "method" | "query" | "path"
67529+
>;
67530+
67531+
export interface ApiConfig<SecurityDataType = unknown> {
67532+
baseUrl?: string;
67533+
baseApiParams?: Omit<RequestParams, "baseUrl" | "cancelToken" | "signal">;
67534+
securityWorker?: (
67535+
securityData: SecurityDataType | null,
67536+
) => Promise<RequestParams | void> | RequestParams | void;
67537+
customFetch?: typeof fetch;
67538+
}
67539+
67540+
export interface HttpResponse<D extends unknown, E extends unknown = unknown>
67541+
extends Response {
67542+
data: D;
67543+
error: E;
67544+
}
67545+
67546+
type CancelToken = Symbol | string | number;
67547+
67548+
export enum ContentType {
67549+
Json = "application/json",
67550+
JsonApi = "application/vnd.api+json",
67551+
FormData = "multipart/form-data",
67552+
UrlEncoded = "application/x-www-form-urlencoded",
67553+
Text = "text/plain",
67554+
}
67555+
67556+
export class HttpClient<SecurityDataType = unknown> {
67557+
public baseUrl: string = "";
67558+
private securityData: SecurityDataType | null = null;
67559+
private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"];
67560+
private abortControllers = new Map<CancelToken, AbortController>();
67561+
private customFetch = (...fetchParams: Parameters<typeof fetch>) =>
67562+
fetch(...fetchParams);
67563+
67564+
private baseApiParams: RequestParams = {
67565+
credentials: "same-origin",
67566+
headers: {},
67567+
redirect: "follow",
67568+
referrerPolicy: "no-referrer",
67569+
};
67570+
67571+
constructor(apiConfig: ApiConfig<SecurityDataType> = {}) {
67572+
Object.assign(this, apiConfig);
67573+
}
67574+
67575+
public setSecurityData = (data: SecurityDataType | null) => {
67576+
this.securityData = data;
67577+
};
67578+
67579+
protected encodeQueryParam(key: string, value: any) {
67580+
const encodedKey = encodeURIComponent(key);
67581+
return \`\${encodedKey}=\${encodeURIComponent(typeof value === "number" ? value : \`\${value}\`)}\`;
67582+
}
67583+
67584+
protected addQueryParam(query: QueryParamsType, key: string) {
67585+
return this.encodeQueryParam(key, query[key]);
67586+
}
67587+
67588+
protected addArrayQueryParam(query: QueryParamsType, key: string) {
67589+
const value = query[key];
67590+
return value.map((v: any) => this.encodeQueryParam(key, v)).join("&");
67591+
}
67592+
67593+
protected toQueryString(rawQuery?: QueryParamsType): string {
67594+
const query = rawQuery || {};
67595+
const keys = Object.keys(query).filter(
67596+
(key) => "undefined" !== typeof query[key],
67597+
);
67598+
return keys
67599+
.map((key) =>
67600+
Array.isArray(query[key])
67601+
? this.addArrayQueryParam(query, key)
67602+
: this.addQueryParam(query, key),
67603+
)
67604+
.join("&");
67605+
}
67606+
67607+
protected addQueryParams(rawQuery?: QueryParamsType): string {
67608+
const queryString = this.toQueryString(rawQuery);
67609+
return queryString ? \`?\${queryString}\` : "";
67610+
}
67611+
67612+
private contentFormatters: Record<ContentType, (input: any) => any> = {
67613+
[ContentType.Json]: (input: any) =>
67614+
input !== null && (typeof input === "object" || typeof input === "string")
67615+
? JSON.stringify(input)
67616+
: input,
67617+
[ContentType.JsonApi]: (input: any) =>
67618+
input !== null && (typeof input === "object" || typeof input === "string")
67619+
? JSON.stringify(input)
67620+
: input,
67621+
[ContentType.Text]: (input: any) =>
67622+
input !== null && typeof input !== "string"
67623+
? JSON.stringify(input)
67624+
: input,
67625+
[ContentType.FormData]: (input: any) => {
67626+
if (input instanceof FormData) {
67627+
return input;
67628+
}
67629+
67630+
return Object.keys(input || {}).reduce((formData, key) => {
67631+
const property = input[key];
67632+
formData.append(
67633+
key,
67634+
property instanceof Blob
67635+
? property
67636+
: typeof property === "object" && property !== null
67637+
? JSON.stringify(property)
67638+
: \`\${property}\`,
67639+
);
67640+
return formData;
67641+
}, new FormData());
67642+
},
67643+
[ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),
67644+
};
67645+
67646+
protected mergeRequestParams(
67647+
params1: RequestParams,
67648+
params2?: RequestParams,
67649+
): RequestParams {
67650+
return {
67651+
...this.baseApiParams,
67652+
...params1,
67653+
...(params2 || {}),
67654+
headers: {
67655+
...(this.baseApiParams.headers || {}),
67656+
...(params1.headers || {}),
67657+
...((params2 && params2.headers) || {}),
67658+
},
67659+
};
67660+
}
67661+
67662+
protected createAbortSignal = (
67663+
cancelToken: CancelToken,
67664+
): AbortSignal | undefined => {
67665+
if (this.abortControllers.has(cancelToken)) {
67666+
const abortController = this.abortControllers.get(cancelToken);
67667+
if (abortController) {
67668+
return abortController.signal;
67669+
}
67670+
return void 0;
67671+
}
67672+
67673+
const abortController = new AbortController();
67674+
this.abortControllers.set(cancelToken, abortController);
67675+
return abortController.signal;
67676+
};
67677+
67678+
public abortRequest = (cancelToken: CancelToken) => {
67679+
const abortController = this.abortControllers.get(cancelToken);
67680+
67681+
if (abortController) {
67682+
abortController.abort();
67683+
this.abortControllers.delete(cancelToken);
67684+
}
67685+
};
67686+
67687+
public request = async <T = any, E = any>({
67688+
body,
67689+
secure,
67690+
path,
67691+
type,
67692+
query,
67693+
format,
67694+
baseUrl,
67695+
cancelToken,
67696+
...params
67697+
}: FullRequestParams): Promise<HttpResponse<T, E>> => {
67698+
const secureParams =
67699+
((typeof secure === "boolean" ? secure : this.baseApiParams.secure) &&
67700+
this.securityWorker &&
67701+
(await this.securityWorker(this.securityData))) ||
67702+
{};
67703+
const requestParams = this.mergeRequestParams(params, secureParams);
67704+
const queryString = query && this.toQueryString(query);
67705+
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
67706+
const responseFormat = format || requestParams.format;
67707+
67708+
return this.customFetch(
67709+
\`\${baseUrl || this.baseUrl || ""}\${path}\${queryString ? \`?\${queryString}\` : ""}\`,
67710+
{
67711+
...requestParams,
67712+
headers: {
67713+
...(requestParams.headers || {}),
67714+
...(type && type !== ContentType.FormData
67715+
? { "Content-Type": type }
67716+
: {}),
67717+
},
67718+
signal:
67719+
(cancelToken
67720+
? this.createAbortSignal(cancelToken)
67721+
: requestParams.signal) || null,
67722+
body:
67723+
typeof body === "undefined" || body === null
67724+
? null
67725+
: payloadFormatter(body),
67726+
},
67727+
).then(async (response) => {
67728+
const r = response.clone() as HttpResponse<T, E>;
67729+
r.data = null as unknown as T;
67730+
r.error = null as unknown as E;
67731+
67732+
const data = !responseFormat
67733+
? r
67734+
: await response[responseFormat]()
67735+
.then((data) => {
67736+
if (r.ok) {
67737+
r.data = data;
67738+
} else {
67739+
r.error = data;
67740+
}
67741+
return r;
67742+
})
67743+
.catch((e) => {
67744+
r.error = e;
67745+
return r;
67746+
});
67747+
67748+
if (cancelToken) {
67749+
this.abortControllers.delete(cancelToken);
67750+
}
67751+
67752+
if (!response.ok) throw data;
67753+
return data;
67754+
});
67755+
};
67756+
}
67757+
67758+
/**
67759+
* @title No title
67760+
*/
67761+
export class Api<
67762+
SecurityDataType extends unknown,
67763+
> extends HttpClient<SecurityDataType> {}
67764+
"
67765+
`;
67766+
6747867767
exports[`extended > 'link-example' 1`] = `
6747967768
"/* eslint-disable */
6748067769
/* tslint:disable */

0 commit comments

Comments
 (0)