From 878d4a6c68fd1480cb23be252d7ca98c3b0d0eff Mon Sep 17 00:00:00 2001 From: Mark Cowlishaw Date: Wed, 26 Jun 2024 19:21:41 -0700 Subject: [PATCH] Add ne config option to tuen off common-types update schema --- .../typespec-autorest/reference/emitter.md | 6 ++ packages/typespec-autorest/README.md | 6 ++ packages/typespec-autorest/src/emit.ts | 1 + packages/typespec-autorest/src/lib.ts | 14 +++ packages/typespec-autorest/src/openapi.ts | 11 ++- .../typespec-autorest/test/options.test.ts | 86 ++++++++++++++++++- 6 files changed, 122 insertions(+), 2 deletions(-) diff --git a/docs/emitters/typespec-autorest/reference/emitter.md b/docs/emitters/typespec-autorest/reference/emitter.md index 4bc24450c4..66026fa84d 100644 --- a/docs/emitters/typespec-autorest/reference/emitter.md +++ b/docs/emitters/typespec-autorest/reference/emitter.md @@ -125,3 +125,9 @@ Create read-only property schema for lro status **Type:** `"none" | "final-state-only" | "all"` Determine whether and how to emit x-ms-long-running-operation-options for lro resolution + +### `emit-common-types-schema` + +**Type:** `"reference-only" | "for-visibility-changes"` + +Determine whether and how to emit schemas for common-types rather than referencing them diff --git a/packages/typespec-autorest/README.md b/packages/typespec-autorest/README.md index d0e5b6e3d1..f3d2993d1a 100644 --- a/packages/typespec-autorest/README.md +++ b/packages/typespec-autorest/README.md @@ -130,6 +130,12 @@ Create read-only property schema for lro status Determine whether and how to emit x-ms-long-running-operation-options for lro resolution +#### `emit-common-types-schema` + +**Type:** `"reference-only" | "for-visibility-changes"` + +Determine whether and how to emit schemas for common-types rather than referencing them + ## Decorators ### Autorest diff --git a/packages/typespec-autorest/src/emit.ts b/packages/typespec-autorest/src/emit.ts index abeecf1f7a..1ac8f57030 100644 --- a/packages/typespec-autorest/src/emit.ts +++ b/packages/typespec-autorest/src/emit.ts @@ -91,6 +91,7 @@ export function resolveAutorestOptions( armTypesDir, useReadOnlyStatusSchema: resolvedOptions["use-read-only-status-schema"], emitLroOptions: resolvedOptions["emit-lro-options"], + emitCommonTypesSchema: resolvedOptions["emit-common-types-schema"], }; } diff --git a/packages/typespec-autorest/src/lib.ts b/packages/typespec-autorest/src/lib.ts index 11d002f7fd..041234ee55 100644 --- a/packages/typespec-autorest/src/lib.ts +++ b/packages/typespec-autorest/src/lib.ts @@ -90,6 +90,12 @@ export interface AutorestEmitterOptions { * @default "final-state-only" */ "emit-lro-options"?: "none" | "final-state-only" | "all"; + + /** + * Determines whether and how to emit schemas for common-types + * @default "for-visibility-changes" + */ + "emit-common-types-schema"?: "reference-only" | "for-visibility-changes"; } const EmitterOptionsSchema: JSONSchemaType = { @@ -193,6 +199,14 @@ const EmitterOptionsSchema: JSONSchemaType = { description: "Determine whether and how to emit x-ms-long-running-operation-options for lro resolution", }, + "emit-common-types-schema": { + type: "string", + enum: ["reference-only", "for-visibility-changes"], + nullable: true, + default: "for-visibility-changes", + description: + "Determine whether and how to emit schemas for common-types rather than referencing them", + }, }, required: [], }; diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index d92f86a17a..6d72a878a7 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -195,6 +195,12 @@ export interface AutorestDocumentEmitterOptions { * @default "final-state-only" */ readonly emitLroOptions?: "none" | "final-state-only" | "all"; + + /** + * Determines whether and how to emit schema for arm common-types + * @default "for-visibility-only" + */ + readonly emitCommonTypesSchema?: "reference-only" | "for-visibility-changes"; } /** @@ -884,7 +890,10 @@ export async function getOpenAPIForService( undefined; const ref = resolveExternalRef(type); if (ref) { - if (!metadataInfo.isTransformed(type, schemaContext.visibility)) { + if ( + options.emitCommonTypesSchema === "reference-only" || + !metadataInfo.isTransformed(type, schemaContext.visibility) + ) { return ref; } diff --git a/packages/typespec-autorest/test/options.test.ts b/packages/typespec-autorest/test/options.test.ts index 365aacb655..520897fc6b 100644 --- a/packages/typespec-autorest/test/options.test.ts +++ b/packages/typespec-autorest/test/options.test.ts @@ -293,7 +293,7 @@ op test(): void; }); }); - describe("'suppress-lro-options' option", () => { + describe("'emit-lro-options' option", () => { const lroCode = ` @armProviderNamespace @useDependency(Azure.Core.Versions.v1_0_Preview_2) @@ -385,4 +385,88 @@ op test(): void; deepStrictEqual(output.paths[itemPath].put["x-ms-long-running-operation-options"], undefined); }); }); + + describe("'emit-common-types-schema' option", () => { + const commonTypesPath = "../../common-types/resource-management/v3/types.json"; + const commonCode = ` + @armProviderNamespace + @useDependency(Azure.Core.Versions.v1_0_Preview_2) + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Test; + + interface Operations extends Azure.ResourceManager.Operations {} + + @doc("The state of the resource") + enum ResourceState { + Succeeded, + Canceled, + Failed + } + + @doc("The widget properties") + model WidgetProperties { + @doc("I am a simple Resource Identifier") + simpleArmId: Azure.Core.armResourceIdentifier; + + @doc("The provisioning State") + provisioningState: ResourceState; + } + + @doc("Foo resource") + model Widget is TrackedResource { + @doc("Widget name") + @key("widgetName") + @segment("widgets") + @path + name: string; + } + @armResourceOperations(Widget) + interface Widgets { + get is ArmResourceRead; + @Azure.Core.useFinalStateVia("azure-async-operation") + createOrUpdate is ArmResourceCreateOrReplaceAsync; + update is ArmResourcePatchSync; + delete is ArmResourceDeleteSync; + listByResourceGroup is ArmResourceListByParent; + listBySubscription is ArmListBySubscription; + } + `; + + it("emits only schema references with 'reference-only' setting", async () => { + const output = await openapiWithOptions(commonCode, { + "emit-common-types-schema": "reference-only", + }); + ok(output.definitions); + ok(output.definitions["WidgetUpdate"]); + deepStrictEqual(output.definitions["WidgetUpdate"].allOf, [ + { + $ref: `${commonTypesPath}#/definitions/TrackedResource`, + }, + ]); + }); + + it("emits an update schema for TrackedResource by default", async () => { + const output = await openapiWithOptions(commonCode, {}); + ok(output.definitions); + ok(output.definitions["WidgetUpdate"]); + deepStrictEqual(output.definitions["WidgetUpdate"].allOf, [ + { + $ref: `#/definitions/Azure.ResourceManager.CommonTypes.TrackedResourceUpdate`, + }, + ]); + }); + + it("emits update schema when set to `for-visibility-changes`", async () => { + const output = await openapiWithOptions(commonCode, { + "emit-common-types-schema": "for-visibility-changes", + }); + ok(output.definitions); + ok(output.definitions["WidgetUpdate"]); + deepStrictEqual(output.definitions["WidgetUpdate"].allOf, [ + { + $ref: `#/definitions/Azure.ResourceManager.CommonTypes.TrackedResourceUpdate`, + }, + ]); + }); + }); });