diff --git a/src/load.ts b/src/load.ts index 8db8f0a05..daeb58658 100644 --- a/src/load.ts +++ b/src/load.ts @@ -147,8 +147,17 @@ export default async function load(schemaURL: URL, options: LoadOptions): Promis return `external["${relativeURL}"]["${parts.join('"]["')}"]`; // export external ref } + // References to properties of schemas like `#/components/schemas/Pet/properties/name` + // requires the components to be wrapped in a `properties` object. But to keep + // backwards compatibility we should instead just remove the `properties` part. + // For us to recognize the `properties` part it simply has to be the second last. + if (parts[parts.length - 2] === "properties") { + parts.splice(parts.length - 2, 1); + } + // scenario 3: transform all $refs pointing back to root schema const [base, ...rest] = parts; + return `${base}["${rest.join('"]["')}"]`; // transform other $refs to the root schema (including external refs that point back to the root schema) }); diff --git a/tests/v2/expected/reference-to-properties.immutable.ts b/tests/v2/expected/reference-to-properties.immutable.ts new file mode 100644 index 000000000..18b237e44 --- /dev/null +++ b/tests/v2/expected/reference-to-properties.immutable.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + readonly "/pet": { + readonly post: operations["addPet"]; + }; +} + +export interface definitions { + readonly Pet: { + readonly id?: number; + readonly name: string; + }; +} + +export interface operations { + readonly addPet: { + readonly parameters: { + readonly body: { + readonly body: { + readonly name?: definitions["Pet"]["name"]; + }; + }; + }; + readonly responses: { + readonly 200: unknown; + }; + }; +} + +export interface external {} diff --git a/tests/v2/expected/reference-to-properties.ts b/tests/v2/expected/reference-to-properties.ts new file mode 100644 index 000000000..cabdc03e2 --- /dev/null +++ b/tests/v2/expected/reference-to-properties.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/pet": { + post: operations["addPet"]; + }; +} + +export interface definitions { + Pet: { + id?: number; + name: string; + }; +} + +export interface operations { + addPet: { + parameters: { + body: { + body: { + name?: definitions["Pet"]["name"]; + }; + }; + }; + responses: { + 200: unknown; + }; + }; +} + +export interface external {} diff --git a/tests/v2/specs/reference-to-properties.yaml b/tests/v2/specs/reference-to-properties.yaml new file mode 100644 index 000000000..9832ba479 --- /dev/null +++ b/tests/v2/specs/reference-to-properties.yaml @@ -0,0 +1,43 @@ +swagger: "2.0" +info: + description: "" + version: "1.0.0" + title: "Swagger Petstore" + termsOfService: "http://swagger.io/terms/" + contact: + email: "apiteam@swagger.io" + license: + name: "Apache 2.0" + url: "http://www.apache.org/licenses/LICENSE-2.0.html" +paths: + /pet: + post: + operationId: "addPet" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - in: "body" + name: "body" + description: "" + required: true + schema: + properties: + name: + $ref: "#/definitions/Pet/properties/name" + responses: + 200: + description: "" +definitions: + Pet: + type: "object" + required: + - "name" + properties: + id: + type: "integer" + format: "int64" + name: + type: "string" + example: "doggie" diff --git a/tests/v3/expected/reference-to-properties.additional.ts b/tests/v3/expected/reference-to-properties.additional.ts new file mode 100644 index 000000000..e4a063493 --- /dev/null +++ b/tests/v3/expected/reference-to-properties.additional.ts @@ -0,0 +1,35 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/pet": { + put: operations["updatePet"]; + }; +} + +export interface components { + schemas: { + Pet: { + name: string; + } & { [key: string]: any }; + }; +} + +export interface operations { + updatePet: { + responses: { + 200: unknown; + }; + requestBody: { + content: { + "application/json": { + name?: components["schemas"]["Pet"]["name"]; + } & { [key: string]: any }; + }; + }; + }; +} + +export interface external {} diff --git a/tests/v3/expected/reference-to-properties.immutable.ts b/tests/v3/expected/reference-to-properties.immutable.ts new file mode 100644 index 000000000..224f2fe04 --- /dev/null +++ b/tests/v3/expected/reference-to-properties.immutable.ts @@ -0,0 +1,35 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + readonly "/pet": { + readonly put: operations["updatePet"]; + }; +} + +export interface components { + readonly schemas: { + readonly Pet: { + readonly name: string; + }; + }; +} + +export interface operations { + readonly updatePet: { + readonly responses: { + readonly 200: unknown; + }; + readonly requestBody: { + readonly content: { + readonly "application/json": { + readonly name?: components["schemas"]["Pet"]["name"]; + }; + }; + }; + }; +} + +export interface external {} diff --git a/tests/v3/expected/reference-to-properties.ts b/tests/v3/expected/reference-to-properties.ts new file mode 100644 index 000000000..4990796f3 --- /dev/null +++ b/tests/v3/expected/reference-to-properties.ts @@ -0,0 +1,35 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/pet": { + put: operations["updatePet"]; + }; +} + +export interface components { + schemas: { + Pet: { + name: string; + }; + }; +} + +export interface operations { + updatePet: { + responses: { + 200: unknown; + }; + requestBody: { + content: { + "application/json": { + name?: components["schemas"]["Pet"]["name"]; + }; + }; + }; + }; +} + +export interface external {} diff --git a/tests/v3/specs/reference-to-properties.yaml b/tests/v3/specs/reference-to-properties.yaml new file mode 100644 index 000000000..1e264ede6 --- /dev/null +++ b/tests/v3/specs/reference-to-properties.yaml @@ -0,0 +1,38 @@ +openapi: 3.0.1 +info: + title: Spec with reference to proeprties + description: '' + termsOfService: http://swagger.io/terms/ + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +paths: + /pet: + put: + summary: '' + operationId: updatePet + requestBody: + description: '' + content: + application/json: + schema: + properties: + name: + $ref: '#/components/schemas/Pet/properties/name' + required: true + responses: + 200: + description: '' + content: {} +components: + schemas: + Pet: + required: + - name + type: object + properties: + name: + type: string