Skip to content

Commit

Permalink
fix: convert anyOf to union type
Browse files Browse the repository at this point in the history
  • Loading branch information
solufa committed Aug 5, 2023
1 parent 6842939 commit b4fbc03
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 16 deletions.
5 changes: 5 additions & 0 deletions aspida.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ module.exports = [
outputEachDir: true,
openapi: { inputFile: 'samples/headers.yml' },
},
{
input: 'samples/allOf-required',
outputEachDir: true,
openapi: { inputFile: 'samples/allOf-required.yml' },
},
// {
// input: 'samples/path-at-mark',
// outputEachDir: true,
Expand Down
33 changes: 33 additions & 0 deletions samples/allOf-required.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
openapi: 3.0.3
info:
title: allOf-required
version: 0.1.0
servers:
- url: https://example.com/v1
paths:
/path:
get:
summary:
responses:
'200':
description: 取得成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseSchema'
components:
schemas:
ResponseSchema:
allOf:
- required:
- req_property
- $ref: '#/components/schemas/BaseSchema'
BaseSchema:
type: object
properties:
req_property:
type: string
description: required property in response
unreq_property:
type: string
description: unrequired property in response
27 changes: 27 additions & 0 deletions samples/allOf-required/$api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { AspidaClient, BasicHeaders } from 'aspida';
import type { Methods as Methods0 } from './path';

const api = <T>({ baseURL, fetch }: AspidaClient<T>) => {
const prefix = (baseURL === undefined ? 'https://example.com/v1' : baseURL).replace(/\/$/, '');
const PATH0 = '/path';
const GET = 'GET';

return {
path: {
/**
* @returns 取得成功
*/
get: (option?: { config?: T | undefined } | undefined) =>
fetch<Methods0['get']['resBody'], BasicHeaders, Methods0['get']['status']>(prefix, PATH0, GET, option).json(),
/**
* @returns 取得成功
*/
$get: (option?: { config?: T | undefined } | undefined) =>
fetch<Methods0['get']['resBody'], BasicHeaders, Methods0['get']['status']>(prefix, PATH0, GET, option).json().then(r => r.body),
$path: () => `${prefix}${PATH0}`,
},
};
};

export type ApiInstance = ReturnType<typeof api>;
export default api;
9 changes: 9 additions & 0 deletions samples/allOf-required/@types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint-disable */
export type ResponseSchema = BaseSchema

export type BaseSchema = {
/** required property in response */
req_property?: string | undefined
/** unrequired property in response */
unreq_property?: string | undefined
}
25 changes: 25 additions & 0 deletions samples/allOf-required/path/$api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { AspidaClient, BasicHeaders } from 'aspida';
import type { Methods as Methods0 } from '.';

const api = <T>({ baseURL, fetch }: AspidaClient<T>) => {
const prefix = (baseURL === undefined ? 'https://example.com/v1' : baseURL).replace(/\/$/, '');
const PATH0 = '/path';
const GET = 'GET';

return {
/**
* @returns 取得成功
*/
get: (option?: { config?: T | undefined } | undefined) =>
fetch<Methods0['get']['resBody'], BasicHeaders, Methods0['get']['status']>(prefix, PATH0, GET, option).json(),
/**
* @returns 取得成功
*/
$get: (option?: { config?: T | undefined } | undefined) =>
fetch<Methods0['get']['resBody'], BasicHeaders, Methods0['get']['status']>(prefix, PATH0, GET, option).json().then(r => r.body),
$path: () => `${prefix}${PATH0}`,
};
};

export type ApiInstance = ReturnType<typeof api>;
export default api;
10 changes: 10 additions & 0 deletions samples/allOf-required/path/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */
import type * as Types from '../@types'

export type Methods = {
get: {
status: 200
/** 取得成功 */
resBody: Types.ResponseSchema
}
}
2 changes: 1 addition & 1 deletion samples/array-one-of/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type Methods = {

/** sample */
resBody: {
user?: Partial<Types.User> | null | undefined
user?: Types.User | null | undefined
}
}
}
6 changes: 3 additions & 3 deletions samples/freee/@types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2019,7 +2019,7 @@ export type ForbiddenError = {
export type BadRequestError = {
status_code?: number | undefined
errors?: {
messages: Partial<string[] & string>
messages: string[] | string

type: 'status' | 'validation' | 'error'
}[] | undefined
Expand All @@ -2028,7 +2028,7 @@ export type BadRequestError = {
export type BadRequestNotFoundError = {
status_code?: number | undefined
errors?: {
messages: Partial<string[] & string>
messages: string[] | string

type: 'status' | 'validation' | 'error'
}[] | undefined
Expand All @@ -2052,7 +2052,7 @@ export type TooManyRequestsError = {
export type InternalServerError = {
status_code?: number | undefined
errors?: {
messages: Partial<string[] & string>
messages: string[] | string

type: 'status' | 'validation' | 'error'
}[] | undefined
Expand Down
2 changes: 1 addition & 1 deletion samples/nullable-object/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type Methods = {

/** sample */
resBody: {
user?: Partial<Types.User> | null | undefined
user?: Types.User | null | undefined
}
}
}
2 changes: 1 addition & 1 deletion src/buildTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default async ({ input, isYaml }: Config) => {
? openapi
: await require('swagger2openapi').convertObj(openapi, { direct: true, resolveInternal: true });

return buildV3(await resolveExternalRefs(docs, typeof input === 'string' ? input : ''));
return resolveExternalRefs(docs, typeof input === 'string' ? input : '').then(buildV3);
};
18 changes: 10 additions & 8 deletions src/builderUtils/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const getPropertyName = (name: string) =>
const of2Values = (obj: OpenAPIV3.SchemaObject): PropValue[] | null => {
const values = (obj.oneOf || obj.allOf || obj.anyOf || [])
.map(p => schema2value(p))
.filter(v => v) as PropValue[];
.filter(Boolean) as PropValue[];
return values.length ? values : null;
};

Expand Down Expand Up @@ -128,13 +128,15 @@ export const schema2value = (
} else if (schema.format === 'binary') {
value = isResponse ? 'Blob' : BINARY_TYPE;
} else if (schema.type !== 'object') {
value = {
integer: 'number',
number: 'number',
null: 'null',
string: 'string',
boolean: 'boolean',
}[schema.type ?? 'string'];
value = schema.type
? {
integer: 'number',
number: 'number',
null: 'null',
string: 'string',
boolean: 'boolean',
}[schema.type]
: null;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/builderUtils/props2String.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export const value2String = (v: PropValue, indent: string): string =>
}${v.nullable ? ' | null' : ''}`;

const values2String = (values: PropValue[], hasOf: PropValue['hasOf'], indent: string) =>
`${hasOf === 'anyOf' ? 'Partial<' : ''}${values
values
.map(a => value2String(a, indent))
.join(hasOf === 'oneOf' ? ' | ' : ' & ')}${hasOf === 'anyOf' ? '>' : ''}`;
.join(hasOf === 'oneOf' || hasOf === 'anyOf' ? ' | ' : ' & ');

const isMultiLine = (values: PropValue[]) => values.find(v => !v.isEnum && Array.isArray(v.value));

Expand Down

0 comments on commit b4fbc03

Please sign in to comment.