From c135831e02ddf6d9102b891cd975ae6d9f85b552 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Wed, 11 May 2022 12:46:11 -0700 Subject: [PATCH] Fix: `x-ms-client-flatten` defined at the root of schema shouldn't apply (#4532) --- .../extensions/modelerfour/CHANGELOG.json | 12 +++ packages/extensions/modelerfour/CHANGELOG.md | 9 ++- packages/extensions/modelerfour/package.json | 2 +- .../modelerfour/src/modeler/modelerfour.ts | 5 +- .../test/modeler/modelerfour-utils.ts | 16 ++++ .../test/modeler/modelerfour.schemas.test.ts | 74 ++++++++++++++++++- 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/packages/extensions/modelerfour/CHANGELOG.json b/packages/extensions/modelerfour/CHANGELOG.json index d75c4e9b9..57568b99f 100644 --- a/packages/extensions/modelerfour/CHANGELOG.json +++ b/packages/extensions/modelerfour/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@autorest/modelerfour", "entries": [ + { + "version": "4.23.4", + "tag": "@autorest/modelerfour_v4.23.4", + "date": "Mon, 09 May 2022 15:29:40 GMT", + "comments": { + "patch": [ + { + "comment": "Fix `x-ms-client-flatten` defined at the root of the model would always flatten that model when referemced in properties" + } + ] + } + }, { "version": "4.23.3", "tag": "@autorest/modelerfour_v4.23.3", diff --git a/packages/extensions/modelerfour/CHANGELOG.md b/packages/extensions/modelerfour/CHANGELOG.md index f05e3f841..8a018eef3 100644 --- a/packages/extensions/modelerfour/CHANGELOG.md +++ b/packages/extensions/modelerfour/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log - @autorest/modelerfour -This log was last generated on Tue, 03 May 2022 20:20:34 GMT and should not be manually modified. +This log was last generated on Mon, 09 May 2022 15:29:40 GMT and should not be manually modified. + +## 4.23.4 +Mon, 09 May 2022 15:29:40 GMT + +### Patches + +- Fix `x-ms-client-flatten` defined at the root of the model would always flatten that model when referemced in properties ## 4.23.3 Tue, 03 May 2022 20:20:34 GMT diff --git a/packages/extensions/modelerfour/package.json b/packages/extensions/modelerfour/package.json index a5e6aedd5..5acd619d5 100644 --- a/packages/extensions/modelerfour/package.json +++ b/packages/extensions/modelerfour/package.json @@ -1,6 +1,6 @@ { "name": "@autorest/modelerfour", - "version": "4.23.3", + "version": "4.23.4", "description": "AutoRest Modeler Version Four (component)", "directories": { "doc": "docs" diff --git a/packages/extensions/modelerfour/src/modeler/modelerfour.ts b/packages/extensions/modelerfour/src/modeler/modelerfour.ts index 352d0a08c..fa7e8e1d7 100644 --- a/packages/extensions/modelerfour/src/modeler/modelerfour.ts +++ b/packages/extensions/modelerfour/src/modeler/modelerfour.ts @@ -867,6 +867,7 @@ export class ModelerFour { this.schemaCache.set(schema, objectSchema); for (const [propertyName, propertyDeclaration] of Object.entries(schema.properties ?? {})) { this.use(>propertyDeclaration, (pSchemaName, pSchema) => { + const property = this.resolve(propertyDeclaration); const pType = this.processSchema(pSchemaName || `type·for·${propertyName}`, pSchema); const prop = objectSchema.addProperty( new Property( @@ -880,8 +881,8 @@ export class ModelerFour { required: schema.required ? schema.required.indexOf(propertyName) > -1 : undefined, serializedName: propertyName, isDiscriminator: discriminatorProperty === propertyName ? true : undefined, - extensions: this.interpret.getExtensionProperties(pSchema, propertyDeclaration), - clientDefaultValue: this.interpret.getClientDefault(pSchema, propertyDeclaration), + extensions: this.interpret.getExtensionProperties(property, propertyDeclaration), + clientDefaultValue: this.interpret.getClientDefault(property, propertyDeclaration), }, ), ); diff --git a/packages/extensions/modelerfour/test/modeler/modelerfour-utils.ts b/packages/extensions/modelerfour/test/modeler/modelerfour-utils.ts index 5c7ec15d8..ae286121d 100644 --- a/packages/extensions/modelerfour/test/modeler/modelerfour-utils.ts +++ b/packages/extensions/modelerfour/test/modeler/modelerfour-utils.ts @@ -2,6 +2,7 @@ import assert from "assert"; import { CodeModel, Operation } from "@autorest/codemodel"; import oai3, { Model } from "@azure-tools/openapi"; import { ModelerFourOptions } from "modeler/modelerfour-options"; +import { Flattener } from "../../src/flattener/flattener"; import { ModelerFour } from "../../src/modeler/modelerfour"; import { addOperation, createTestSessionFromModel, createTestSpec } from "../utils"; @@ -39,6 +40,21 @@ export async function runModeler(spec: any, config: { modelerfour: ModelerFourOp return result; } +export async function runFlattener( + codemodel: CodeModel, + config: { modelerfour: ModelerFourOptions } = cfg, +): Promise { + const { session, errors } = await createTestSessionFromModel(config, codemodel); + session.model = codemodel; + const flattener = await new Flattener(session).init(); + + expect(errors).toHaveLength(0); + + const result = flattener.process(); + expect(errors).toHaveLength(0); + return result; +} + export async function runModelerWithOperation( method: string, path: string, diff --git a/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts b/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts index 4a625abad..dc5810556 100644 --- a/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts +++ b/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts @@ -1,8 +1,9 @@ import assert from "assert"; import { ChoiceSchema, ConstantSchema, SealedChoiceSchema } from "@autorest/codemodel"; -import { JsonType } from "@azure-tools/openapi"; +import { JsonType, OpenAPI3Document } from "@azure-tools/openapi"; +import { ModelerFourOptions } from "modeler/modelerfour-options"; import { addSchema, assertSchema, createTestSpec, findByName } from "../utils"; -import { runModeler } from "./modelerfour-utils"; +import { runFlattener, runModeler } from "./modelerfour-utils"; describe("Modelerfour.Schemas", () => { describe("additionalProperties", () => { @@ -404,4 +405,73 @@ describe("Modelerfour.Schemas", () => { expect(parent?.properties?.find((x) => x.serializedName === "child")?.schema).toEqual(child); }); }); + + describe("x-ms-client-flatten", () => { + async function runModelerWithFlattener(spec: OpenAPI3Document, config: { modelerfour: ModelerFourOptions }) { + const codeModel = await runModeler(spec, config); + return runFlattener(codeModel, config); + } + + it("doesn't flatten if x-ms-client-flatten is specified on the property", async () => { + const spec = createTestSpec(); + + addSchema(spec, "Foo", { + type: "object", + properties: { + nestedBar: { $ref: "#/components/schemas/Bar", "x-ms-client-flatten": true }, + }, + }); + + addSchema(spec, "Bar", { + type: "object", + properties: { + bar: { + type: "string", + }, + }, + }); + + const codeModel = await runModelerWithFlattener(spec, { modelerfour: { "flatten-models": true } }); + + const foo = findByName("Foo", codeModel.schemas.objects); + expect(foo).toBeDefined(); + + const nestedBarProp = findByName("nestedBar", foo?.properties); + expect(nestedBarProp).not.toBeDefined(); + const flattendBarProp = findByName("bar", foo?.properties); + expect(flattendBarProp).toBeDefined(); + }); + + it("doesn't flatten if x-ms-client-flatten is specified on the target model", async () => { + const spec = createTestSpec(); + + addSchema(spec, "Foo", { + type: "object", + properties: { + nestedBar: { $ref: "#/components/schemas/Bar" }, + }, + }); + + addSchema(spec, "Bar", { + "x-ms-client-flatten": true, + type: "object", + properties: { + bar: { + type: "string", + }, + }, + }); + + const codeModel = await runModelerWithFlattener(spec, { modelerfour: { "flatten-models": true } }); + + const foo = findByName("Foo", codeModel.schemas.objects); + expect(foo).toBeDefined(); + const bar = findByName("Bar", codeModel.schemas.objects); + expect(bar).toBeDefined(); + + const nestedBarProp = findByName("nestedBar", foo?.properties); + expect(nestedBarProp).toBeDefined(); + expect(nestedBarProp?.schema).toEqual(bar); + }); + }); });