diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 854139a3..8ad6bafe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1,21 @@ # Contributing + +## Build + +```bash +pnpm run build +``` + +## Test + +Snapshot Update + +```bash +pnpm run update:snapshot +``` + +## Shortcut + +```bash +pnpm run build && pnpm run test:code:gen && pnpm run update:snapshot +``` diff --git a/src/code-templates/_shared/ApiClientArgument.ts b/src/code-templates/_shared/ApiClientArgument.ts index 34233939..e58401ce 100644 --- a/src/code-templates/_shared/ApiClientArgument.ts +++ b/src/code-templates/_shared/ApiClientArgument.ts @@ -57,6 +57,7 @@ const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: C if (convertedParams.has2OrMoreRequestContentTypes) { members.push( factory.PropertySignature.create({ + readOnly: false, name: `"Content-Type"`, optional: false, type: factory.TypeReferenceNode.create({ name: "T" }), @@ -67,6 +68,7 @@ const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: C if (convertedParams.has2OrMoreSuccessResponseContentTypes) { members.push( factory.PropertySignature.create({ + readOnly: false, name: `Accept`, optional: false, type: factory.TypeReferenceNode.create({ name: "U" }), @@ -117,6 +119,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator. const headerDeclaration = createHeaders(factory, params); if (headerDeclaration) { const extraHeader = factory.PropertySignature.create({ + readOnly: false, name: "headers", optional: false, type: headerDeclaration, @@ -126,6 +129,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator. if (convertedParams.hasParameter) { const parameter = factory.PropertySignature.create({ + readOnly: false, name: "parameter", optional: false, type: factory.TypeReferenceNode.create({ @@ -137,6 +141,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator. if (convertedParams.hasRequestBody) { const requestBody = factory.PropertySignature.create({ + readOnly: false, name: "requestBody", optional: false, type: factory.IndexedAccessTypeNode.create({ diff --git a/src/code-templates/_shared/ApiClientInterface.ts b/src/code-templates/_shared/ApiClientInterface.ts index 01d054d7..29632106 100644 --- a/src/code-templates/_shared/ApiClientInterface.ts +++ b/src/code-templates/_shared/ApiClientInterface.ts @@ -63,16 +63,19 @@ const createQueryParamsDeclarations = (factory: TsGenerator.Factory.Type) => { name: "QueryParameter", members: [ factory.PropertySignature.create({ + readOnly: false, name: "value", optional: false, type: factory.TypeNode.create({ type: "any" }), }), factory.PropertySignature.create({ + readOnly: false, name: "style", optional: true, type: factory.TypeNode.create({ type: "string", enum: ["form", "spaceDelimited", "pipeDelimited", "deepObject"] }), }), factory.PropertySignature.create({ + readOnly: false, name: "explode", optional: false, type: factory.TypeNode.create({ type: "boolean" }), @@ -113,6 +116,7 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => { members: [ factory.PropertySignature.create({ name: "contentType", + readOnly: true, optional: true, type: factory.TypeReferenceNode.create({ name: "string", @@ -120,6 +124,7 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => { }), factory.PropertySignature.create({ name: "headers", + readOnly: false, optional: true, type: factory.TypeReferenceNode.create({ name: "Record", @@ -127,11 +132,13 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => { }), factory.PropertySignature.create({ name: "style", + readOnly: true, optional: true, type: factory.TypeNode.create({ type: "string", enum: ["form", "spaceDelimited", "pipeDelimited", "deepObject"] }), }), factory.PropertySignature.create({ name: "explode", + readOnly: true, optional: true, type: factory.TypeReferenceNode.create({ name: "boolean", @@ -139,6 +146,7 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => { }), factory.PropertySignature.create({ name: "allowReserved", + readOnly: true, optional: true, type: factory.TypeReferenceNode.create({ name: "boolean", @@ -219,6 +227,7 @@ export const create = ( }); const requestFunction = factory.PropertySignature.create({ + readOnly: false, name: "request", optional: false, type: functionType, @@ -230,32 +239,38 @@ export const create = ( members: [ factory.PropertySignature.create({ name: `httpMethod`, + readOnly: true, optional: false, type: factory.TypeReferenceNode.create({ name: "HttpMethod" }), }), factory.PropertySignature.create({ name: methodType === "currying-function" ? "uri" : "url", + readOnly: true, optional: false, type: factory.TypeReferenceNode.create({ name: "string" }), }), factory.PropertySignature.create({ name: `headers`, + readOnly: false, optional: false, type: objectLikeOrAnyType, }), factory.PropertySignature.create({ name: `requestBody`, + readOnly: false, optional: true, type: objectLikeOrAnyType, }), factory.PropertySignature.create({ name: `requestBodyEncoding`, + readOnly: false, optional: true, type: factory.TypeReferenceNode.create({ name: "Record" }), }), factory.PropertySignature.create({ name: `queryParameters`, optional: true, + readOnly: false, type: factory.UnionTypeNode.create({ typeNodes: [ factory.TypeReferenceNode.create({ diff --git a/src/internal/OpenApiTools/components/Header.ts b/src/internal/OpenApiTools/components/Header.ts index 0c988f3b..96f13f1b 100644 --- a/src/internal/OpenApiTools/components/Header.ts +++ b/src/internal/OpenApiTools/components/Header.ts @@ -37,6 +37,7 @@ export const generatePropertySignature = ( if (reference.type === "local") { context.setReferenceHandler(currentPoint, reference); return factory.PropertySignature.create({ + readOnly: false, name: converterContext.escapePropertySignatureName(name), optional: false, type: factory.TypeReferenceNode.create({ @@ -45,6 +46,7 @@ export const generatePropertySignature = ( }); } return factory.PropertySignature.create({ + readOnly: false, name: converterContext.escapePropertySignatureName(name), optional: false, type: factory.TypeReferenceNode.create({ @@ -53,6 +55,7 @@ export const generatePropertySignature = ( }); } return factory.PropertySignature.create({ + readOnly: false, name: converterContext.escapePropertySignatureName(name), optional: false, type: ToTypeNode.convert(entryPoint, currentPoint, factory, header.schema || { type: "null" }, context, converterContext), diff --git a/src/internal/OpenApiTools/components/MediaType.ts b/src/internal/OpenApiTools/components/MediaType.ts index dc3bf4e5..9ea80582 100644 --- a/src/internal/OpenApiTools/components/MediaType.ts +++ b/src/internal/OpenApiTools/components/MediaType.ts @@ -15,6 +15,7 @@ export const generatePropertySignature = ( converterContext: ConverterContext.Types, ): ts.PropertySignature => { return factory.PropertySignature.create({ + readOnly: false, name: converterContext.escapePropertySignatureName(protocol), optional: false, type: ToTypeNode.convert(entryPoint, currentPoint, factory, schema, context, converterContext), diff --git a/src/internal/OpenApiTools/components/Parameter.ts b/src/internal/OpenApiTools/components/Parameter.ts index 80577d54..500db334 100644 --- a/src/internal/OpenApiTools/components/Parameter.ts +++ b/src/internal/OpenApiTools/components/Parameter.ts @@ -53,6 +53,7 @@ export const generatePropertySignatureObject = ( const isPathProperty = localRef.in === "path"; const name = converterContext.escapePropertySignatureName(localRef.name); const typeElement = factory.PropertySignature.create({ + readOnly: false, name: name, optional: isPathProperty ? false : !localRef.required, comment: localRef.description, @@ -68,6 +69,7 @@ export const generatePropertySignatureObject = ( const isPathProperty = reference.data.in === "path"; const name = converterContext.escapePropertySignatureName(reference.data.name); const typeElement = factory.PropertySignature.create({ + readOnly: false, name: name, optional: isPathProperty ? false : !reference.data.required, comment: reference.data.description, @@ -88,6 +90,7 @@ export const generatePropertySignatureObject = ( const isPathProperty = parameter.in === "path"; const name = converterContext.escapePropertySignatureName(parameter.name); const typeElement = factory.PropertySignature.create({ + readOnly: false, name: name, optional: isPathProperty ? false : !parameter.required, type: ToTypeNode.convert(entryPoint, currentPoint, factory, parameter.schema || { type: "null" }, context, converterContext), diff --git a/src/internal/OpenApiTools/components/Schema.ts b/src/internal/OpenApiTools/components/Schema.ts index 689fa528..da6803c6 100644 --- a/src/internal/OpenApiTools/components/Schema.ts +++ b/src/internal/OpenApiTools/components/Schema.ts @@ -39,6 +39,7 @@ export const generatePropertySignatures = ( return Object.entries(schema.properties).map(([propertyName, property]) => { if (!property) { return factory.PropertySignature.create({ + readOnly: false, name: convertContext.escapePropertySignatureName(propertyName), optional: !required.includes(propertyName), comment: [schema.title, schema.description].filter(v => !!v).join("\n\n"), @@ -48,6 +49,7 @@ export const generatePropertySignatures = ( }); } return factory.PropertySignature.create({ + readOnly: typeof property !== "boolean" ? !!property.readOnly : false, name: convertContext.escapePropertySignatureName(propertyName), optional: !required.includes(propertyName), type: ToTypeNode.convert(entryPoint, currentPoint, factory, property, context, convertContext, { parent: schema }), diff --git a/src/internal/OpenApiTools/components/SecuritySchema.ts b/src/internal/OpenApiTools/components/SecuritySchema.ts index 9885b072..4dcf8569 100644 --- a/src/internal/OpenApiTools/components/SecuritySchema.ts +++ b/src/internal/OpenApiTools/components/SecuritySchema.ts @@ -11,21 +11,25 @@ export const generatePropertySignatures = ( ): ts.PropertySignature[] => { const signatures: ts.PropertySignature[] = [ factory.PropertySignature.create({ + readOnly: false, name: "type", optional: false, type: factory.LiteralTypeNode.create({ value: securitySchema.type }), }), factory.PropertySignature.create({ + readOnly: false, name: "name", optional: false, type: factory.LiteralTypeNode.create({ value: securitySchema.name }), }), factory.PropertySignature.create({ + readOnly: false, name: "in", optional: false, type: factory.LiteralTypeNode.create({ value: securitySchema.in }), }), factory.PropertySignature.create({ + readOnly: false, name: "openIdConnectUrl", optional: false, type: factory.LiteralTypeNode.create({ value: securitySchema.openIdConnectUrl }), diff --git a/src/internal/OpenApiTools/toTypeNode.ts b/src/internal/OpenApiTools/toTypeNode.ts index 08843f47..04b650cd 100644 --- a/src/internal/OpenApiTools/toTypeNode.ts +++ b/src/internal/OpenApiTools/toTypeNode.ts @@ -272,6 +272,7 @@ export const convert: Convert = ( const value: ts.PropertySignature[] = Object.entries(schema.properties || {}).map(([name, jsonSchema]) => { return factory.PropertySignature.create({ + readOnly: typeof jsonSchema !== "boolean" ? !!jsonSchema.readOnly : false, name: converterContext.escapePropertySignatureName(name), type: convert(entryPoint, currentPoint, factory, jsonSchema, context, converterContext, { parent: schema.properties }), optional: !required.includes(name), diff --git a/src/internal/TsGenerator/factory/PropertySignature.ts b/src/internal/TsGenerator/factory/PropertySignature.ts index e5bb912e..bd177109 100644 --- a/src/internal/TsGenerator/factory/PropertySignature.ts +++ b/src/internal/TsGenerator/factory/PropertySignature.ts @@ -4,6 +4,7 @@ import { generateComment } from "./utils"; export interface Params { name: string; + readOnly: boolean; optional: boolean; type: ts.TypeNode; comment?: string; @@ -16,8 +17,9 @@ export interface Factory { export const create = ({ factory }: Pick): Factory["create"] => (params: Params): ts.PropertySignature => { + const node = factory.createPropertySignature( - undefined, + params.readOnly ? [factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined, params.name, params.optional ? factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, params.type, diff --git a/src/meta.ts b/src/meta.ts index 930fdaa2..b1abc493 100644 --- a/src/meta.ts +++ b/src/meta.ts @@ -1,2 +1,2 @@ export const Name = "@himenon/openapi-typescript-code-generator"; -export const Version = "0.25.0"; +export const Version = "0.26.1"; \ No newline at end of file diff --git a/test/__tests__/class/__snapshots__/argo-rollout-test.ts.snap b/test/__tests__/class/__snapshots__/argo-rollout-test.ts.snap index 4e5c61a1..1c1e9ec8 100644 --- a/test/__tests__/class/__snapshots__/argo-rollout-test.ts.snap +++ b/test/__tests__/class/__snapshots__/argo-rollout-test.ts.snap @@ -3827,15 +3827,15 @@ export namespace ErrorResponse { export type RolloutService_Version = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/format.domain.ts.snap b/test/__tests__/class/__snapshots__/format.domain.ts.snap index 98bdfa5c..833e5487 100644 --- a/test/__tests__/class/__snapshots__/format.domain.ts.snap +++ b/test/__tests__/class/__snapshots__/format.domain.ts.snap @@ -44,15 +44,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/kubernetes-test.ts.snap b/test/__tests__/class/__snapshots__/kubernetes-test.ts.snap index bf815e85..852902a0 100644 --- a/test/__tests__/class/__snapshots__/kubernetes-test.ts.snap +++ b/test/__tests__/class/__snapshots__/kubernetes-test.ts.snap @@ -41026,15 +41026,15 @@ export namespace ErrorResponse { export type getCodeVersion = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/multi-type.test.domain.ts.snap b/test/__tests__/class/__snapshots__/multi-type.test.domain.ts.snap index b65beff1..1280b2ec 100644 --- a/test/__tests__/class/__snapshots__/multi-type.test.domain.ts.snap +++ b/test/__tests__/class/__snapshots__/multi-type.test.domain.ts.snap @@ -43,15 +43,15 @@ export namespace ErrorResponse { export type patchOneOf = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/spit-code-test.ts.snap b/test/__tests__/class/__snapshots__/spit-code-test.ts.snap index 370fa1dd..14afe8b6 100644 --- a/test/__tests__/class/__snapshots__/spit-code-test.ts.snap +++ b/test/__tests__/class/__snapshots__/spit-code-test.ts.snap @@ -124,15 +124,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/template-only-test.ts.snap b/test/__tests__/class/__snapshots__/template-only-test.ts.snap index 5e1573d5..d310d5bc 100644 --- a/test/__tests__/class/__snapshots__/template-only-test.ts.snap +++ b/test/__tests__/class/__snapshots__/template-only-test.ts.snap @@ -61,15 +61,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -251,15 +251,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -405,15 +405,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap b/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap index eace8729..b4d53b67 100644 --- a/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap +++ b/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap @@ -410,15 +410,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -552,6 +552,9 @@ exports[`Typedef with template api.v2.domain 1`] = ` export namespace Schemas { export type Message = "hello" | "world"; export type QueryParams = "a" | "b" | "c"; + export interface ReadOnlyParams { + readonly readonlyPropertyKey?: string; + } } export interface Parameter$getHelloWorld { /** query word */ @@ -562,10 +565,22 @@ export interface Response$getHelloWorld$Status$200 { message?: Schemas.Message; }; } +export interface RequestBody$postHelloWorldReadonly { +} +export interface Response$postHelloWorldReadonly$Status$200 { + "application/json": { + message?: Schemas.Message; + }; +} export type ResponseContentType$getHelloWorld = keyof Response$getHelloWorld$Status$200; export interface Params$getHelloWorld { parameter: Parameter$getHelloWorld; } +export type RequestContentType$postHelloWorldReadonly = keyof RequestBody$postHelloWorldReadonly; +export type ResponseContentType$postHelloWorldReadonly = keyof Response$postHelloWorldReadonly$Status$200; +export interface Params$postHelloWorldReadonly { + requestBody: RequestBody$postHelloWorldReadonly["application/json"]; +} export type HttpMethod = "GET" | "PUT" | "POST" | "DELETE" | "OPTIONS" | "HEAD" | "PATCH" | "TRACE"; export interface ObjectLike { [key: string]: any; @@ -578,20 +593,21 @@ export interface QueryParameter { export interface QueryParameters { [key: string]: QueryParameter; } -export type SuccessResponses = Response$getHelloWorld$Status$200; +export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200; export namespace ErrorResponse { export type getHelloWorld = void; + export type postHelloWorldReadonly = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -618,6 +634,19 @@ export class Client { queryParameters: queryParameters }, option); } + public async postHelloWorldReadonly(params: Params$postHelloWorldReadonly, option?: RequestOption): Promise { + const url = this.baseUrl + \`/hello/world/readonly\`; + const headers = { + "Content-Type": "application/json", + Accept: "application/json" + }; + return this.apiClient.request({ + httpMethod: "POST", + url, + headers, + requestBody: params.requestBody + }, option); + } } " `; @@ -1032,15 +1061,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1209,15 +1238,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1371,15 +1400,15 @@ export namespace ErrorResponse { export type createPublisherV2 = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1597,15 +1626,15 @@ export namespace ErrorResponse { export type getPublisher = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/class/__snapshots__/unknown-schema-domain-test.ts.snap b/test/__tests__/class/__snapshots__/unknown-schema-domain-test.ts.snap index 62928183..1563144d 100644 --- a/test/__tests__/class/__snapshots__/unknown-schema-domain-test.ts.snap +++ b/test/__tests__/class/__snapshots__/unknown-schema-domain-test.ts.snap @@ -42,15 +42,15 @@ export namespace ErrorResponse { export type getUnknown = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/argo-rollout-test.ts.snap b/test/__tests__/functional/__snapshots__/argo-rollout-test.ts.snap index 125c8245..e409a020 100644 --- a/test/__tests__/functional/__snapshots__/argo-rollout-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/argo-rollout-test.ts.snap @@ -3827,15 +3827,15 @@ export namespace ErrorResponse { export type RolloutService_Version = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/format.domain.ts.snap b/test/__tests__/functional/__snapshots__/format.domain.ts.snap index 70b71ed8..a90dd4cc 100644 --- a/test/__tests__/functional/__snapshots__/format.domain.ts.snap +++ b/test/__tests__/functional/__snapshots__/format.domain.ts.snap @@ -44,15 +44,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/kubernetes-test.ts.snap b/test/__tests__/functional/__snapshots__/kubernetes-test.ts.snap index b0ea1a8a..2ec7f7bd 100644 --- a/test/__tests__/functional/__snapshots__/kubernetes-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/kubernetes-test.ts.snap @@ -41026,15 +41026,15 @@ export namespace ErrorResponse { export type getCodeVersion = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/multi-type.test.domain.ts.snap b/test/__tests__/functional/__snapshots__/multi-type.test.domain.ts.snap index b007d37a..d22eaa04 100644 --- a/test/__tests__/functional/__snapshots__/multi-type.test.domain.ts.snap +++ b/test/__tests__/functional/__snapshots__/multi-type.test.domain.ts.snap @@ -43,15 +43,15 @@ export namespace ErrorResponse { export type patchOneOf = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/spit-code-test.ts.snap b/test/__tests__/functional/__snapshots__/spit-code-test.ts.snap index 48eb2761..4a9dcd39 100644 --- a/test/__tests__/functional/__snapshots__/spit-code-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/spit-code-test.ts.snap @@ -124,15 +124,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/template-only-test.ts.snap b/test/__tests__/functional/__snapshots__/template-only-test.ts.snap index c6f3ba23..8bc9d1ce 100644 --- a/test/__tests__/functional/__snapshots__/template-only-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/template-only-test.ts.snap @@ -61,15 +61,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -254,15 +254,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -411,15 +411,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap b/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap index e2874356..bd95e7ed 100644 --- a/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap @@ -410,15 +410,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -555,6 +555,9 @@ exports[`Typedef with template api.v2.domain 1`] = ` export namespace Schemas { export type Message = "hello" | "world"; export type QueryParams = "a" | "b" | "c"; + export interface ReadOnlyParams { + readonly readonlyPropertyKey?: string; + } } export interface Parameter$getHelloWorld { /** query word */ @@ -565,10 +568,22 @@ export interface Response$getHelloWorld$Status$200 { message?: Schemas.Message; }; } +export interface RequestBody$postHelloWorldReadonly { +} +export interface Response$postHelloWorldReadonly$Status$200 { + "application/json": { + message?: Schemas.Message; + }; +} export type ResponseContentType$getHelloWorld = keyof Response$getHelloWorld$Status$200; export interface Params$getHelloWorld { parameter: Parameter$getHelloWorld; } +export type RequestContentType$postHelloWorldReadonly = keyof RequestBody$postHelloWorldReadonly; +export type ResponseContentType$postHelloWorldReadonly = keyof Response$postHelloWorldReadonly$Status$200; +export interface Params$postHelloWorldReadonly { + requestBody: RequestBody$postHelloWorldReadonly["application/json"]; +} export type HttpMethod = "GET" | "PUT" | "POST" | "DELETE" | "OPTIONS" | "HEAD" | "PATCH" | "TRACE"; export interface ObjectLike { [key: string]: any; @@ -581,20 +596,21 @@ export interface QueryParameter { export interface QueryParameters { [key: string]: QueryParameter; } -export type SuccessResponses = Response$getHelloWorld$Status$200; +export type SuccessResponses = Response$getHelloWorld$Status$200 | Response$postHelloWorldReadonly$Status$200; export namespace ErrorResponse { export type getHelloWorld = void; + export type postHelloWorldReadonly = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -620,6 +636,19 @@ export const createClient = (apiClient: ApiClient, headers, queryParameters: queryParameters }, option); + }, + postHelloWorldReadonly: (params: Params$postHelloWorldReadonly, option?: RequestOption): Promise => { + const url = _baseUrl + \`/hello/world/readonly\`; + const headers = { + "Content-Type": "application/json", + Accept: "application/json" + }; + return apiClient.request({ + httpMethod: "POST", + url, + headers, + requestBody: params.requestBody + }, option); } }; }; @@ -1038,15 +1067,15 @@ export namespace ErrorResponse { export type deleteBook = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1218,15 +1247,15 @@ export interface QueryParameters { export type SuccessResponses = void; export namespace ErrorResponse { } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1382,15 +1411,15 @@ export namespace ErrorResponse { export type createPublisherV2 = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; @@ -1611,15 +1640,15 @@ export namespace ErrorResponse { export type getPublisher = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/__tests__/functional/__snapshots__/unknown-schema-domain-test.ts.snap b/test/__tests__/functional/__snapshots__/unknown-schema-domain-test.ts.snap index dfac984e..90738869 100644 --- a/test/__tests__/functional/__snapshots__/unknown-schema-domain-test.ts.snap +++ b/test/__tests__/functional/__snapshots__/unknown-schema-domain-test.ts.snap @@ -42,15 +42,15 @@ export namespace ErrorResponse { export type getUnknown = void; } export interface Encoding { - contentType?: string; + readonly contentType?: string; headers?: Record; - style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; - explode?: boolean; - allowReserved?: boolean; + readonly style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject"; + readonly explode?: boolean; + readonly allowReserved?: boolean; } export interface RequestArgs { - httpMethod: HttpMethod; - url: string; + readonly httpMethod: HttpMethod; + readonly url: string; headers: ObjectLike | any; requestBody?: ObjectLike | any; requestBodyEncoding?: Record; diff --git a/test/api.v2.domain/index.yml b/test/api.v2.domain/index.yml index 86ed80b9..69a60210 100644 --- a/test/api.v2.domain/index.yml +++ b/test/api.v2.domain/index.yml @@ -21,6 +21,12 @@ components: $ref: "./components/schemas/Message.yml" QueryParams: $ref: "./components/schemas/QueryParams.yml" + ReadOnlyParams: + type: object + properties: + readonlyPropertyKey: + type: string + readOnly: true paths: /hello/world: get: @@ -42,3 +48,21 @@ paths: properties: message: $ref: "#/components/schemas/Message" + /hello/world/readonly: + post: + operationId: postHelloWorldReadonly + requestBody: + description: ReadOnly Request Body + content: + application/json: + $ref: "#/components/schemas/ReadOnlyParams" + responses: + 200: + description: 成功 + content: + application/json: + schema: + type: object + properties: + message: + $ref: "#/components/schemas/Message"