From 09a2cc5458ebf5552f6f2dd90b2fdad2bd6f9305 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 23 Jan 2026 19:33:02 -0500 Subject: [PATCH 1/9] Soft deprecated and remove from feeds --- eng/feeds/__snapshots__/azure-arm/tspconfig.yaml | 1 - eng/feeds/__snapshots__/azure-arm_stand_alone/tspconfig.yaml | 3 +-- eng/feeds/__snapshots__/azure-core/tspconfig.yaml | 3 +-- eng/feeds/__snapshots__/azure-core_stand_alone/tspconfig.yaml | 3 +-- eng/feeds/arm-canonical/tspconfig.yaml | 4 +--- eng/feeds/arm/tspconfig.yaml | 1 - eng/feeds/arm/tspconfig_stand_alone.yaml | 3 +-- eng/feeds/data-plane/tspconfig.yaml | 3 +-- eng/feeds/data-plane/tspconfig_stand_alone.yaml | 3 +-- packages/typespec-autorest/src/lib.ts | 3 +++ 10 files changed, 10 insertions(+), 17 deletions(-) diff --git a/eng/feeds/__snapshots__/azure-arm/tspconfig.yaml b/eng/feeds/__snapshots__/azure-arm/tspconfig.yaml index 12d8df8171..81bd7acded 100644 --- a/eng/feeds/__snapshots__/azure-arm/tspconfig.yaml +++ b/eng/feeds/__snapshots__/azure-arm/tspconfig.yaml @@ -4,7 +4,6 @@ options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true emitter-output-dir: "{project-root}" - azure-resource-provider-folder: "resource-manager" output-file: "{emitter-output-dir}/{version-status}/{version}/widget.json" arm-types-dir: "{project-root}/../../../../common-types/resource-management" "@azure-tools/typespec-csharp": diff --git a/eng/feeds/__snapshots__/azure-arm_stand_alone/tspconfig.yaml b/eng/feeds/__snapshots__/azure-arm_stand_alone/tspconfig.yaml index 14e86c486e..24a4c4a5c9 100644 --- a/eng/feeds/__snapshots__/azure-arm_stand_alone/tspconfig.yaml +++ b/eng/feeds/__snapshots__/azure-arm_stand_alone/tspconfig.yaml @@ -3,8 +3,7 @@ emit: options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true - azure-resource-provider-folder: "resource-manager" - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "resource-manager/{service-name}/{version-status}/{version}/openapi.json" linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" diff --git a/eng/feeds/__snapshots__/azure-core/tspconfig.yaml b/eng/feeds/__snapshots__/azure-core/tspconfig.yaml index c7ea7ca658..32af772b8a 100644 --- a/eng/feeds/__snapshots__/azure-core/tspconfig.yaml +++ b/eng/feeds/__snapshots__/azure-core/tspconfig.yaml @@ -7,9 +7,8 @@ emit: - "@azure-tools/typespec-autorest" options: "@azure-tools/typespec-autorest": - azure-resource-provider-folder: "data-plane" emitter-output-dir: "{project-root}/.." - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "data-plane/{service-name}/{version-status}/{version}/openapi.json" "@azure-tools/typespec-python": emitter-output-dir: "{output-dir}/{service-dir}/azure-contoso" namespace: "azure.contoso" diff --git a/eng/feeds/__snapshots__/azure-core_stand_alone/tspconfig.yaml b/eng/feeds/__snapshots__/azure-core_stand_alone/tspconfig.yaml index 0a0355b47f..17ce84a8cc 100644 --- a/eng/feeds/__snapshots__/azure-core_stand_alone/tspconfig.yaml +++ b/eng/feeds/__snapshots__/azure-core_stand_alone/tspconfig.yaml @@ -7,8 +7,7 @@ emit: - "@azure-tools/typespec-autorest" options: "@azure-tools/typespec-autorest": - azure-resource-provider-folder: "data-plane" - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "data-plane/{service-name}/{version-status}/{version}/openapi.json" "@azure-tools/typespec-python": emitter-output-dir: "{output-dir}/{service-dir}/azure-contoso" namespace: azure.contoso diff --git a/eng/feeds/arm-canonical/tspconfig.yaml b/eng/feeds/arm-canonical/tspconfig.yaml index 03c1478c26..1e5c9120ac 100644 --- a/eng/feeds/arm-canonical/tspconfig.yaml +++ b/eng/feeds/arm-canonical/tspconfig.yaml @@ -5,13 +5,11 @@ options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true emitter-output-dir: "{project-root}" - azure-resource-provider-folder: "resource-manager" output-file: "{emitter-output-dir}/{version-status}/{version}/widget.json" arm-types-dir: "{project-root}/../../../../common-types/resource-management" "@azure-tools/typespec-autorest-canonical": emitter-output-dir: "{project-root}/.." - azure-resource-provider-folder: "resource-manager" - output-file: "{azure-resource-provider-folder}/{service-name}/canonical/openapi.json" + output-file: "{emitter-output-dir}/canonical/openapi.json" linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" diff --git a/eng/feeds/arm/tspconfig.yaml b/eng/feeds/arm/tspconfig.yaml index 47a780179c..d94354561d 100644 --- a/eng/feeds/arm/tspconfig.yaml +++ b/eng/feeds/arm/tspconfig.yaml @@ -4,7 +4,6 @@ options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true emitter-output-dir: "{project-root}" - azure-resource-provider-folder: "resource-manager" output-file: "{emitter-output-dir}/{version-status}/{version}/widget.json" arm-types-dir: "{project-root}/../../../../common-types/resource-management" "@azure-tools/typespec-csharp": diff --git a/eng/feeds/arm/tspconfig_stand_alone.yaml b/eng/feeds/arm/tspconfig_stand_alone.yaml index 14e86c486e..24a4c4a5c9 100644 --- a/eng/feeds/arm/tspconfig_stand_alone.yaml +++ b/eng/feeds/arm/tspconfig_stand_alone.yaml @@ -3,8 +3,7 @@ emit: options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true - azure-resource-provider-folder: "resource-manager" - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "resource-manager/{service-name}/{version-status}/{version}/openapi.json" linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" diff --git a/eng/feeds/data-plane/tspconfig.yaml b/eng/feeds/data-plane/tspconfig.yaml index 96b3ef1443..02bfd9eac2 100644 --- a/eng/feeds/data-plane/tspconfig.yaml +++ b/eng/feeds/data-plane/tspconfig.yaml @@ -7,9 +7,8 @@ emit: - "@azure-tools/typespec-autorest" options: "@azure-tools/typespec-autorest": - azure-resource-provider-folder: "data-plane" emitter-output-dir: "{project-root}/.." - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "data-plane/{service-name}/{version-status}/{version}/openapi.json" "@azure-tools/typespec-python": emitter-output-dir: "{output-dir}/{service-dir}/{{#normalizePackageName}}{{parameters.ServiceNamespace}}{{/normalizePackageName}}" namespace: "{{#toLowerCase}}{{parameters.ServiceNamespace}}{{/toLowerCase}}" diff --git a/eng/feeds/data-plane/tspconfig_stand_alone.yaml b/eng/feeds/data-plane/tspconfig_stand_alone.yaml index 647e063b26..09e2c6fa22 100644 --- a/eng/feeds/data-plane/tspconfig_stand_alone.yaml +++ b/eng/feeds/data-plane/tspconfig_stand_alone.yaml @@ -7,8 +7,7 @@ emit: - "@azure-tools/typespec-autorest" options: "@azure-tools/typespec-autorest": - azure-resource-provider-folder: "data-plane" - output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" + output-file: "data-plane/{service-name}/{version-status}/{version}/openapi.json" "@azure-tools/typespec-python": emitter-output-dir: "{output-dir}/{service-dir}/{{#normalizePackageName}}{{parameters.ServiceNamespace}}{{/normalizePackageName}}" namespace: {{#toLowerCase}}{{parameters.ServiceNamespace}}{{/toLowerCase}} diff --git a/packages/typespec-autorest/src/lib.ts b/packages/typespec-autorest/src/lib.ts index d1cfa04ca1..104f47920b 100644 --- a/packages/typespec-autorest/src/lib.ts +++ b/packages/typespec-autorest/src/lib.ts @@ -14,6 +14,8 @@ export interface AutorestEmitterOptions { * - azure-resource-provider-folder: Value of the azure-resource-provider-folder option * - version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise. * + * @deprecated Do not use this option. Specify the path directly in emitter-output-dir. + * * @default `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json` * * @@ -142,6 +144,7 @@ const EmitterOptionsSchema: JSONSchemaType = { " - azure-resource-provider-folder: Value of the azure-resource-provider-folder option", " - version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise.", "", + " Deprecated: Do not use this option. Specify the path directly in emitter-output-dir.", "Default: `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json`", "", "", From 6476c44b7270613049aa8eeed1c5522795be1475 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 23 Jan 2026 19:44:23 -0500 Subject: [PATCH 2/9] abc --- .../typespec-autorest-canonical/src/lib.ts | 3 +-- packages/typespec-autorest/README.md | 11 +++++---- packages/typespec-autorest/src/emit.ts | 4 ++-- packages/typespec-autorest/src/lib.ts | 24 +++++++++---------- .../typespec-autorest/reference/emitter.md | 11 +++++---- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/packages/typespec-autorest-canonical/src/lib.ts b/packages/typespec-autorest-canonical/src/lib.ts index d4e9d34d45..03c13bdf20 100644 --- a/packages/typespec-autorest-canonical/src/lib.ts +++ b/packages/typespec-autorest-canonical/src/lib.ts @@ -6,9 +6,8 @@ export interface AutorestCanonicalEmitterOptions { * Output file will interpolate the following values: * - service-name: Name of the service if multiple * - version: Version of the service if multiple - * - azure-resource-provider-folder: Value of the azure-resource-provider-folder option * - * @default `{azure-resource-provider-folder}/{service-name}/canonical/openapi.json` + * @default `{emitter-output-dir}/{service-name}/canonical/openapi.json` * * * @example Single service no versioning diff --git a/packages/typespec-autorest/README.md b/packages/typespec-autorest/README.md index 9e670efde8..683203c87d 100644 --- a/packages/typespec-autorest/README.md +++ b/packages/typespec-autorest/README.md @@ -57,10 +57,9 @@ Output file will interpolate the following values: - service-name: Name of the service if multiple - version: Version of the service if multiple -- azure-resource-provider-folder: Value of the azure-resource-provider-folder option -- version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise. +- version-status: `preview` if version contains preview, stable otherwise. -Default: `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json` +Default: `{emitter-output-dir}/{service-name}/{version-status}/{version}/openapi.json` Example: Single service no versioning @@ -83,9 +82,9 @@ Example: Multiple service with versioning - `openapi.Org1.Service2.v1.0.yaml` - `openapi.Org1.Service2.v1.1.yaml` -Example: azureResourceProviderFolder is provided +Example: Versioning with version-status -- `arm-folder/AzureService/preview/2020-01-01.yaml` +- `arm-folder/AzureService/stable/2020-01-01.yaml` - `arm-folder/AzureService/preview/2020-01-01.yaml` ### `examples-dir` @@ -108,6 +107,8 @@ DEPRECATED. Use examples-dir instead **Type:** `string` +Deprecated. Do not use this option. Specify the path directly in emitter-output-dir. + ### `arm-types-dir` **Type:** `string` diff --git a/packages/typespec-autorest/src/emit.ts b/packages/typespec-autorest/src/emit.ts index 6029f94de5..984b247978 100644 --- a/packages/typespec-autorest/src/emit.ts +++ b/packages/typespec-autorest/src/emit.ts @@ -52,8 +52,7 @@ interface ResolvedAutorestEmitterOptions extends AutorestDocumentEmitterOptions } const defaultOptions = { - "output-file": - "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json", + "output-file": "{emitter-output-dir}/{service-name}/{version-status}/{version}/openapi.json", "new-line": "lf", "include-x-typespec-name": "never", "xml-strategy": "xml-service", @@ -101,6 +100,7 @@ export function resolveAutorestOptions( return { outputFile: resolvedOptions["output-file"], outputDir: emitterOutputDir, + // eslint-disable-next-line @typescript-eslint/no-deprecated azureResourceProviderFolder: resolvedOptions["azure-resource-provider-folder"], // eslint-disable-next-line @typescript-eslint/no-deprecated examplesDirectory: resolvedOptions["examples-dir"] ?? resolvedOptions["examples-directory"], diff --git a/packages/typespec-autorest/src/lib.ts b/packages/typespec-autorest/src/lib.ts index 104f47920b..130b3a09fa 100644 --- a/packages/typespec-autorest/src/lib.ts +++ b/packages/typespec-autorest/src/lib.ts @@ -11,12 +11,8 @@ export interface AutorestEmitterOptions { * Output file will interpolate the following values: * - service-name: Name of the service if multiple * - version: Version of the service if multiple - * - azure-resource-provider-folder: Value of the azure-resource-provider-folder option - * - version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise. * - * @deprecated Do not use this option. Specify the path directly in emitter-output-dir. - * - * @default `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json` + * @default `{emitter-output-dir}/{service-name}/{version-status}/{version}/openapi.json` * * * @example Single service no versioning @@ -55,6 +51,7 @@ export interface AutorestEmitterOptions { version?: string; + /** @deprecated Do not use this option. Specify the path directly in emitter-output-dir. */ "azure-resource-provider-folder"?: string; /** @@ -141,11 +138,9 @@ const EmitterOptionsSchema: JSONSchemaType = { "Output file will interpolate the following values:", " - service-name: Name of the service if multiple", " - version: Version of the service if multiple", - " - azure-resource-provider-folder: Value of the azure-resource-provider-folder option", - " - version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise.", + " - version-status: `preview` if version contains preview, stable otherwise.", "", - " Deprecated: Do not use this option. Specify the path directly in emitter-output-dir.", - "Default: `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json`", + "Default: `{emitter-output-dir}/{service-name}/{version-status}/{version}/openapi.json`", "", "", "Example: Single service no versioning", @@ -165,8 +160,8 @@ const EmitterOptionsSchema: JSONSchemaType = { " - `openapi.Org1.Service2.v1.0.yaml`", " - `openapi.Org1.Service2.v1.1.yaml`", "", - "Example: azureResourceProviderFolder is provided", - " - `arm-folder/AzureService/preview/2020-01-01.yaml`", + "Example: Versioning with version-status ", + " - `arm-folder/AzureService/stable/2020-01-01.yaml`", " - `arm-folder/AzureService/preview/2020-01-01.yaml`", ].join("\n"), }, @@ -183,7 +178,12 @@ const EmitterOptionsSchema: JSONSchemaType = { description: "DEPRECATED. Use examples-dir instead", }, version: { type: "string", nullable: true }, - "azure-resource-provider-folder": { type: "string", nullable: true }, + "azure-resource-provider-folder": { + type: "string", + nullable: true, + description: + "Deprecated. Do not use this option. Specify the path directly in emitter-output-dir.", + }, "arm-types-dir": { type: "string", nullable: true, diff --git a/website/src/content/docs/docs/emitters/typespec-autorest/reference/emitter.md b/website/src/content/docs/docs/emitters/typespec-autorest/reference/emitter.md index 8c24050680..3122bcfbc5 100644 --- a/website/src/content/docs/docs/emitters/typespec-autorest/reference/emitter.md +++ b/website/src/content/docs/docs/emitters/typespec-autorest/reference/emitter.md @@ -51,10 +51,9 @@ Output file will interpolate the following values: - service-name: Name of the service if multiple - version: Version of the service if multiple -- azure-resource-provider-folder: Value of the azure-resource-provider-folder option -- version-status: Only enabled if azure-resource-provider-folder is set. `preview` if version contains preview, stable otherwise. +- version-status: `preview` if version contains preview, stable otherwise. -Default: `{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json` +Default: `{emitter-output-dir}/{service-name}/{version-status}/{version}/openapi.json` Example: Single service no versioning @@ -77,9 +76,9 @@ Example: Multiple service with versioning - `openapi.Org1.Service2.v1.0.yaml` - `openapi.Org1.Service2.v1.1.yaml` -Example: azureResourceProviderFolder is provided +Example: Versioning with version-status -- `arm-folder/AzureService/preview/2020-01-01.yaml` +- `arm-folder/AzureService/stable/2020-01-01.yaml` - `arm-folder/AzureService/preview/2020-01-01.yaml` ### `examples-dir` @@ -102,6 +101,8 @@ DEPRECATED. Use examples-dir instead **Type:** `string` +Deprecated. Do not use this option. Specify the path directly in emitter-output-dir. + ### `arm-types-dir` **Type:** `string` From 965d5ba534a69cd0a25f337dd2e5d8470c625837 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 23 Jan 2026 16:46:46 -0800 Subject: [PATCH 3/9] Create deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md --- ...m-resource-provider-folder-2026-0-24-0-38-20.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md diff --git a/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md b/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md new file mode 100644 index 0000000000..10424531d9 --- /dev/null +++ b/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md @@ -0,0 +1,14 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: deprecation +packages: + - "@azure-tools/typespec-autorest" +--- + +Deprecate `azure-resource-provider-folder` option. + +```diff lang=yaml +-azure-resource-provider-folder: "resource-manager" +-output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json" ++output-file: "resource-manager/{service-name}/{version-status}/{version}/openapi.json" +``` From 9102d05594e70286ffc17bf5410df452e731d6b8 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 23 Jan 2026 19:52:25 -0500 Subject: [PATCH 4/9] fix canonical --- .../deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md | 1 + packages/typespec-autorest-canonical/src/emitter.ts | 1 + packages/typespec-autorest-canonical/src/lib.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md b/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md index 10424531d9..1d65e508be 100644 --- a/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md +++ b/.chronus/changes/deprecate-arm-resource-provider-folder-2026-0-24-0-38-20.md @@ -3,6 +3,7 @@ changeKind: deprecation packages: - "@azure-tools/typespec-autorest" + - "@azure-tools/typespec-autorest-canonical" --- Deprecate `azure-resource-provider-folder` option. diff --git a/packages/typespec-autorest-canonical/src/emitter.ts b/packages/typespec-autorest-canonical/src/emitter.ts index df49323871..ad20173ddb 100644 --- a/packages/typespec-autorest-canonical/src/emitter.ts +++ b/packages/typespec-autorest-canonical/src/emitter.ts @@ -65,6 +65,7 @@ export async function $onEmit(context: EmitContext Date: Fri, 23 Jan 2026 19:53:38 -0500 Subject: [PATCH 5/9] remove condition on version-status --- packages/typespec-autorest/src/emit.ts | 6 +----- packages/typespec-autorest/src/lib.ts | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/typespec-autorest/src/emit.ts b/packages/typespec-autorest/src/emit.ts index 984b247978..f4b88404d7 100644 --- a/packages/typespec-autorest/src/emit.ts +++ b/packages/typespec-autorest/src/emit.ts @@ -361,11 +361,7 @@ export function resolveOutputFile( multipleServices || azureResourceProviderFolder ? getNamespaceFullName(service.type) : undefined, - "version-status": azureResourceProviderFolder - ? version?.includes("preview") - ? "preview" - : "stable" - : undefined, + "version-status": version?.includes("preview") ? "preview" : "stable", version, feature, }); diff --git a/packages/typespec-autorest/src/lib.ts b/packages/typespec-autorest/src/lib.ts index 130b3a09fa..de1af15318 100644 --- a/packages/typespec-autorest/src/lib.ts +++ b/packages/typespec-autorest/src/lib.ts @@ -160,7 +160,7 @@ const EmitterOptionsSchema: JSONSchemaType = { " - `openapi.Org1.Service2.v1.0.yaml`", " - `openapi.Org1.Service2.v1.1.yaml`", "", - "Example: Versioning with version-status ", + "Example: Versioning with version-status", " - `arm-folder/AzureService/stable/2020-01-01.yaml`", " - `arm-folder/AzureService/preview/2020-01-01.yaml`", ].join("\n"), From 10ce5627c0ab314415f852c4c4c252870f19f385 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 23 Jan 2026 21:06:43 -0500 Subject: [PATCH 6/9] configure output-file to keep old structure for the samples here --- core | 2 +- .../samples/specs/data-plane/tspconfig.yaml | 3 + .../specs/misc/overloads/tspconfig.yaml | 1 + .../misc/x-ms-examples/flat/tspconfig.yaml | 1 + .../misc/x-ms-examples/nested/tspconfig.yaml | 1 + .../specs/resource-manager/tspconfig.yaml | 1 + packages/samples/specs/tspconfig.yaml | 5 + .../appconfig/@typespec/openapi3/openapi.yaml | 845 ------------------ packages/samples/test/samples.test.ts | 5 + packages/typespec-autorest/src/emit.ts | 6 +- 10 files changed, 20 insertions(+), 850 deletions(-) create mode 100644 packages/samples/specs/tspconfig.yaml delete mode 100644 packages/samples/test/output/azure/core/misc/appconfig/@typespec/openapi3/openapi.yaml diff --git a/core b/core index 06c47505d6..f17024309f 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 06c47505d6ff2b4be7975a326882185e7ec88c7e +Subproject commit f17024309f0091f23a3997dac56fbabbc8a5a68d diff --git a/packages/samples/specs/data-plane/tspconfig.yaml b/packages/samples/specs/data-plane/tspconfig.yaml index f9641fd33d..a1746bff44 100644 --- a/packages/samples/specs/data-plane/tspconfig.yaml +++ b/packages/samples/specs/data-plane/tspconfig.yaml @@ -1,6 +1,9 @@ emit: - "@azure-tools/typespec-autorest" - "@typespec/openapi3" +options: + "@azure-tools/typespec-autorest": + output-file: "{emitter-output-dir}/{service-name}/{version}/openapi.json" linter: extends: - "@azure-tools/typespec-azure-rulesets/data-plane" diff --git a/packages/samples/specs/misc/overloads/tspconfig.yaml b/packages/samples/specs/misc/overloads/tspconfig.yaml index febf78b198..9852bf1ce2 100644 --- a/packages/samples/specs/misc/overloads/tspconfig.yaml +++ b/packages/samples/specs/misc/overloads/tspconfig.yaml @@ -1,3 +1,4 @@ +extends: ../../tspconfig.yaml emit: - "@azure-tools/typespec-autorest" diff --git a/packages/samples/specs/misc/x-ms-examples/flat/tspconfig.yaml b/packages/samples/specs/misc/x-ms-examples/flat/tspconfig.yaml index e078dbe156..45b8182dcc 100644 --- a/packages/samples/specs/misc/x-ms-examples/flat/tspconfig.yaml +++ b/packages/samples/specs/misc/x-ms-examples/flat/tspconfig.yaml @@ -1,2 +1,3 @@ +extends: ../../../tspconfig.yaml emit: - "@azure-tools/typespec-autorest" diff --git a/packages/samples/specs/misc/x-ms-examples/nested/tspconfig.yaml b/packages/samples/specs/misc/x-ms-examples/nested/tspconfig.yaml index e078dbe156..45b8182dcc 100644 --- a/packages/samples/specs/misc/x-ms-examples/nested/tspconfig.yaml +++ b/packages/samples/specs/misc/x-ms-examples/nested/tspconfig.yaml @@ -1,2 +1,3 @@ +extends: ../../../tspconfig.yaml emit: - "@azure-tools/typespec-autorest" diff --git a/packages/samples/specs/resource-manager/tspconfig.yaml b/packages/samples/specs/resource-manager/tspconfig.yaml index a71f4f4ea4..83a3ce733c 100644 --- a/packages/samples/specs/resource-manager/tspconfig.yaml +++ b/packages/samples/specs/resource-manager/tspconfig.yaml @@ -4,6 +4,7 @@ options: "@azure-tools/typespec-autorest": use-read-only-status-schema: true arm-types-dir: "{project-root}/common-types" + output-file: "{emitter-output-dir}/{service-name}/{version}/openapi.json" linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" diff --git a/packages/samples/specs/tspconfig.yaml b/packages/samples/specs/tspconfig.yaml new file mode 100644 index 0000000000..9b0f1573a0 --- /dev/null +++ b/packages/samples/specs/tspconfig.yaml @@ -0,0 +1,5 @@ +emit: + - "@azure-tools/typespec-autorest" +options: + "@azure-tools/typespec-autorest": + output-file: "{emitter-output-dir}/{service-name}/{version}/openapi.json" diff --git a/packages/samples/test/output/azure/core/misc/appconfig/@typespec/openapi3/openapi.yaml b/packages/samples/test/output/azure/core/misc/appconfig/@typespec/openapi3/openapi.yaml deleted file mode 100644 index e2c290f153..0000000000 --- a/packages/samples/test/output/azure/core/misc/appconfig/@typespec/openapi3/openapi.yaml +++ /dev/null @@ -1,845 +0,0 @@ -openapi: 3.0.0 -info: - title: App Config Service - version: 0.0.0 -tags: [] -paths: - /keys: - get: - operationId: GetKeys - description: Gets a list of keys. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: name - in: query - required: true - schema: - type: string - explode: false - - name: after - in: header - required: true - schema: - type: string - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/vnd.microsoft.appconfig.keyset+json: - schema: - $ref: '#/components/schemas/PagedKey' - application/json: - schema: - $ref: '#/components/schemas/PagedKey' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - head: - operationId: CheckKeys - description: Requests the headers and status of the given resource. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: name - in: query - required: true - schema: - type: string - explode: false - - name: after - in: header - required: true - schema: - type: string - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - /kv: - get: - operationId: GetKeyValues - description: Gets a list of key-values. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - $ref: '#/components/parameters/KeyFilters.key' - - $ref: '#/components/parameters/KeyFilters.label' - - name: After - in: query - required: true - description: Instructs the server to return elements that appear after the element referred to by the specified token. - schema: - type: string - format: date - explode: false - - name: $Select - in: query - required: false - description: Used to select what fields are present in the returned resource(s). - schema: - type: array - items: - $ref: '#/components/schemas/KeyField' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/vnd.microsoft.appconfig.keyset+json: - schema: - $ref: '#/components/schemas/PagedKeyValue' - application/json: - schema: - $ref: '#/components/schemas/PagedKeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - head: - operationId: CheckKeyValues - description: Gets a list of key-values. - parameters: - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - $ref: '#/components/parameters/KeyFilters.key' - - $ref: '#/components/parameters/KeyFilters.label' - - name: After - in: query - required: true - description: Instructs the server to return elements that appear after the element referred to by the specified token. - schema: - type: string - format: date - explode: false - - name: $Select - in: query - required: false - description: Used to select what fields are present in the returned resource(s). - schema: - type: array - items: - $ref: '#/components/schemas/KeyField' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - /kv/{key}: - get: - operationId: GetKeyValue - description: Gets a single key-value. - parameters: - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - $ref: '#/components/parameters/KeyWithFilters.key' - - $ref: '#/components/parameters/KeyWithFilters.label' - - name: $Select - in: query - required: false - description: Used to select what fields are present in the returned resource(s). - schema: - type: array - items: - $ref: '#/components/schemas/KeyField' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - last-modified: - required: true - schema: - type: string - format: date - e-tag: - required: true - schema: - type: string - content: - application/vnd.microsoft.appconfig.kv+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - head: - operationId: CheckKeyValue - description: Requests the headers and status of the given resource. - parameters: - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - $ref: '#/components/parameters/KeyWithFilters.key' - - $ref: '#/components/parameters/KeyWithFilters.label' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - last-modified: - required: true - schema: - type: string - format: date - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - put: - operationId: PutKeyValue - description: Creates a key-value. - parameters: - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - - $ref: '#/components/parameters/KeyWithFilters.key' - - $ref: '#/components/parameters/KeyWithFilters.label' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - last-modified: - required: true - schema: - type: string - format: date - e-tag: - required: true - schema: - type: string - content: - application/vnd.microsoft.appconfig.kv+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - requestBody: - required: true - content: - application/vnd.microsoft.appconfig.kv+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/vnd.microsoft.appconfig.kvset+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - text/json: - schema: - $ref: '#/components/schemas/KeyValue' - application/*+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json-patch+json: - schema: - $ref: '#/components/schemas/KeyValue' - post: - operationId: UpdateKeyValue - description: Updates a key-value pair - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - - $ref: '#/components/parameters/KeyWithFilters.key' - - $ref: '#/components/parameters/KeyWithFilters.label' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - last-modified: - required: true - schema: - type: string - format: date - e-tag: - required: true - schema: - type: string - content: - application/vnd.microsoft.appconfig.kv+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - requestBody: - required: true - content: - application/json-patch+json: - schema: - type: array - items: - type: string - delete: - operationId: DeleteKeyValue - description: Deletes a key-value. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/KeyWithFilters.key' - - $ref: '#/components/parameters/KeyWithFilters.label' - - name: if-match - in: header - required: true - schema: - type: string - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - e-tag: - required: true - schema: - type: string - content: - application/vnd.microsoft.appconfig.kv+json: - schema: - $ref: '#/components/schemas/KeyValue' - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - '204': - description: 'There is no content to send for this request, but the headers may be useful. ' - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - /labels: - get: - operationId: GetLabels - description: Gets a list of labels. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: name - in: query - required: false - schema: - type: string - explode: false - - name: after - in: query - required: false - schema: - type: string - explode: false - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/vnd.microsoft.appconfig.labelset+json: - schema: - $ref: '#/components/schemas/PagedLabel' - application/json: - schema: - $ref: '#/components/schemas/PagedLabel' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - head: - operationId: CheckLabels - description: Requests the headers and status of the given resource. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: name - in: query - required: false - schema: - type: string - explode: false - - name: after - in: query - required: false - schema: - type: string - explode: false - - name: $Select - in: query - required: false - schema: - type: array - items: - $ref: '#/components/schemas/LabelField' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - /locks/{key}: - get: - operationId: GetLock - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - name: key - in: path - required: true - schema: - type: string - - name: label - in: query - required: true - schema: - type: string - explode: false - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - delete: - operationId: DeleteLock - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - name: key - in: path - required: true - schema: - type: string - - name: label - in: query - required: true - schema: - type: string - explode: false - - $ref: '#/components/parameters/ETagHeaders.ifMatch' - - $ref: '#/components/parameters/ETagHeaders.ifNoneMatch' - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/json: - schema: - $ref: '#/components/schemas/KeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - /revisions: - get: - operationId: GetRevisions - description: Gets a list of revisions. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: $Select - in: query - required: false - description: Used to select what fields are present in the returned resource(s). - schema: - type: array - items: - $ref: '#/components/schemas/KeyField' - - name: label - in: query - required: true - description: A filter used to match labels - schema: - type: string - explode: false - - name: key - in: query - required: true - description: A filter used to match keys. - schema: - type: string - explode: false - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - content: - application/vnd.microsoft.appconfig.kvset+json: - schema: - $ref: '#/components/schemas/PagedKeyValue' - application/json: - schema: - $ref: '#/components/schemas/PagedKeyValue' - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' - head: - operationId: CheckRevisions - description: Requests the headers and status of the given resource. - parameters: - - $ref: '#/components/parameters/ApiVersion' - - $ref: '#/components/parameters/SyncTokenHeader' - - $ref: '#/components/parameters/AcceptDatetimeHeader' - - name: name - in: query - required: true - schema: - type: string - explode: false - - name: after - in: query - required: true - schema: - type: string - explode: false - responses: - '200': - description: The request has succeeded. - headers: - sync-token: - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - default: - description: An unexpected error response. - content: - application/problem+json: - schema: - $ref: '#/components/schemas/Error' -components: - parameters: - AcceptDatetimeHeader: - name: accept-datetime - in: header - required: true - schema: - type: string - format: date - ApiVersion: - name: apiVersion - in: query - required: true - schema: - type: string - explode: false - ETagHeaders.ifMatch: - name: if-match - in: header - required: true - schema: - type: string - ETagHeaders.ifNoneMatch: - name: if-none-match - in: header - required: true - schema: - type: string - KeyFilters.key: - name: key - in: query - required: false - description: A filter for the name of the returned keys. - schema: - type: string - explode: false - KeyFilters.label: - name: label - in: query - required: false - description: A filter used to match labels - schema: - type: string - explode: false - KeyWithFilters.key: - name: key - in: path - required: true - description: A filter for the name of the returned keys. - schema: - type: string - KeyWithFilters.label: - name: label - in: query - required: false - description: A filter used to match labels - schema: - type: string - explode: false - SyncTokenHeader: - name: sync-token - in: header - required: false - description: Used to guarantee real-time consistency between requests. - schema: - type: string - schemas: - ETagHeader: - type: object - Error: - type: object - required: - - type - - title - - name - - detail - - statusCode - properties: - type: - type: string - description: The type of the error - title: - type: string - description: A brief summary of the error. - name: - type: string - description: The name of the parameter that resulted in the error. - detail: - type: string - description: A detailed description of the error. - statusCode: - type: integer - format: int32 - description: The HTTP status code that the error maps to. - description: Azure App Configuration error object. - Key: - type: object - required: - - key - properties: - key: - type: string - KeyField: - anyOf: - - type: string - enum: - - key - - label - - content_type - - value - - last_modified - - tags - - type: string - KeyValue: - type: object - required: - - key - - tags - - locked - properties: - key: - type: string - label: - type: string - tags: - type: object - additionalProperties: - type: string - locked: - type: boolean - Label: - type: object - required: - - name - properties: - name: - type: string - LabelField: - anyOf: - - type: string - enum: - - name - - type: string - LastModifiedHeader: - type: object - PagedKey: - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/Key' - description: The Key items on this page - nextLink: - type: string - description: The link to the next page of items - description: Paged collection of Key items - PagedKeyValue: - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/KeyValue' - description: The KeyValue items on this page - nextLink: - type: string - description: The link to the next page of items - description: Paged collection of KeyValue items - PagedLabel: - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/Label' - description: The Label items on this page - nextLink: - type: string - description: The link to the next page of items - description: Paged collection of Label items - Value: - type: object - required: - - tags - - locked - properties: - label: - type: string - tags: - type: object - additionalProperties: - type: string - locked: - type: boolean diff --git a/packages/samples/test/samples.test.ts b/packages/samples/test/samples.test.ts index 327eb1af5b..291f126061 100644 --- a/packages/samples/test/samples.test.ts +++ b/packages/samples/test/samples.test.ts @@ -23,6 +23,11 @@ describe("TypeSpec Samples (With autorest emitter)", () => { outputDir: resolvePath(rootOutputDir, "core"), exclude: [...excludedSamples, "authentication", "multipart", "todoApp"], emit: [resolvePath(pkgRoot, "node_modules/@azure-tools/typespec-autorest").replace(/\\/g, "/")], + options: { + "@azure-tools/typespec-autorest": { + "output-file": "{emitter-output-dir}/{service-name}/{version}/openapi.json", + }, + }, }); }); diff --git a/packages/typespec-autorest/src/emit.ts b/packages/typespec-autorest/src/emit.ts index f4b88404d7..8930b396f0 100644 --- a/packages/typespec-autorest/src/emit.ts +++ b/packages/typespec-autorest/src/emit.ts @@ -351,10 +351,8 @@ export function resolveOutputFile( feature?: string, ): string { const azureResourceProviderFolder = options.azureResourceProviderFolder; - if (azureResourceProviderFolder) { - const info = resolveInfo(program, service.type); - version = version ?? info?.version ?? "0000-00-00"; - } + const info = resolveInfo(program, service.type); + version = version ?? info?.version; const interpolated = interpolatePath(options.outputFile, { "azure-resource-provider-folder": azureResourceProviderFolder, "service-name": From 94c917815b5414c581d17fd8b32143a80ef59f60 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Sat, 24 Jan 2026 14:35:02 -0500 Subject: [PATCH 7/9] fix --- packages/typespec-autorest/src/emit.ts | 2 +- .../typespec-autorest/test/options.test.ts | 44 ++----------------- .../typespec-autorest/test/services.test.ts | 6 +-- packages/typespec-autorest/test/test-host.ts | 20 +++++++-- 4 files changed, 23 insertions(+), 49 deletions(-) diff --git a/packages/typespec-autorest/src/emit.ts b/packages/typespec-autorest/src/emit.ts index 8930b396f0..9d5c39a71a 100644 --- a/packages/typespec-autorest/src/emit.ts +++ b/packages/typespec-autorest/src/emit.ts @@ -359,7 +359,7 @@ export function resolveOutputFile( multipleServices || azureResourceProviderFolder ? getNamespaceFullName(service.type) : undefined, - "version-status": version?.includes("preview") ? "preview" : "stable", + "version-status": version && (version.includes("preview") ? "preview" : "stable"), version, feature, }); diff --git a/packages/typespec-autorest/test/options.test.ts b/packages/typespec-autorest/test/options.test.ts index fb351d0e55..071dd67266 100644 --- a/packages/typespec-autorest/test/options.test.ts +++ b/packages/typespec-autorest/test/options.test.ts @@ -123,7 +123,7 @@ describe("typespec-autorest: options", () => { ok(runner.fs.fs.has(resolveVirtualPath("./my-output/openapi.json"))); }); - it("emit to {emitter-output-dir}/{version}/{output-file} if spec contains versioning", async () => { + it("emit to {emitter-output-dir}/{version-status}/{version}/{output-file} if spec contains versioning", async () => { const versionedRunner = await Tester.createInstance(); await versionedRunner.compile( ` @@ -132,7 +132,6 @@ describe("typespec-autorest: options", () => { namespace DemoService; enum Versions {v1, v2} -#suppress "@azure-tools/typespec-azure-core/use-standard-operations" "This is a test." op test(): void; `, { @@ -150,45 +149,8 @@ op test(): void; !versionedRunner.fs.fs.has(resolveVirtualPath("./my-output/openapi.json")), "Shouldn't have created the non versioned file name", ); - ok(versionedRunner.fs.fs.has(resolveVirtualPath("./my-output/v1/openapi.json"))); - ok(versionedRunner.fs.fs.has(resolveVirtualPath("./my-output/v2/openapi.json"))); - }); - - it("emit to {emitter-output-dir}/{arm-folder}/{serviceName}/{versionType}/{version}/{output-file} if spec contains azure-resource-provider-folder is passed", async () => { - const versionedRunner = await Tester.createInstance(); - await versionedRunner.compile( - ` -@TypeSpec.Versioning.versioned(Versions) -@service(#{title: "Widget Service"}) -namespace TestService; -enum Versions {v1, "v2-preview"} - -#suppress "@azure-tools/typespec-azure-core/use-standard-operations" "This is a test." -op test(): void; - `, - { - compilerOptions: { - outputDir: "./my-output", - options: { - "@azure-tools/typespec-autorest": { - "emitter-output-dir": emitterOutputDir, - "azure-resource-provider-folder": "./arm-folder", - }, - }, - }, - }, - ); - - ok( - versionedRunner.fs.fs.has( - resolveVirtualPath("./my-output/arm-folder/TestService/stable/v1/openapi.json"), - ), - ); - ok( - versionedRunner.fs.fs.has( - resolveVirtualPath("./my-output/arm-folder/TestService/preview/v2-preview/openapi.json"), - ), - ); + ok(versionedRunner.fs.fs.has(resolveVirtualPath("./my-output/stable/v1/openapi.json"))); + ok(versionedRunner.fs.fs.has(resolveVirtualPath("./my-output/stable/v2/openapi.json"))); }); }); diff --git a/packages/typespec-autorest/test/services.test.ts b/packages/typespec-autorest/test/services.test.ts index 07f45a188f..ac403d8ba3 100644 --- a/packages/typespec-autorest/test/services.test.ts +++ b/packages/typespec-autorest/test/services.test.ts @@ -1,9 +1,9 @@ import { deepStrictEqual } from "assert"; import { it } from "vitest"; -import { openApiFor } from "./test-host.js"; +import { compileMultipleOpenAPI } from "./test-host.js"; it("supports emitting multiple services", async () => { - const { Service, Client } = await openApiFor( + const { Service, Client } = await compileMultipleOpenAPI( ` @service(#{ title: "My service" }) namespace Service { @@ -15,7 +15,7 @@ it("supports emitting multiple services", async () => { @route("other") op other(): string; } `, - ["Service", "Client"], + { Service: "Service/openapi.json", Client: "Client/openapi.json" }, ); deepStrictEqual(Service.paths, { diff --git a/packages/typespec-autorest/test/test-host.ts b/packages/typespec-autorest/test/test-host.ts index 4ff9b851ff..0bb78744b3 100644 --- a/packages/typespec-autorest/test/test-host.ts +++ b/packages/typespec-autorest/test/test-host.ts @@ -95,9 +95,9 @@ export async function compileOpenAPI( return JSON.parse(outputs["openapi.json"]); } -export async function compileVersionedOpenAPI( +export async function compileMultipleOpenAPI( code: string, - versions: K[], + files: Record, options: CompileOpenAPIOptions = {}, ): Promise> { const [{ outputs }, diagnostics] = await Tester.compileAndDiagnose(code, { @@ -112,12 +112,24 @@ export async function compileVersionedOpenAPI( expectDiagnosticEmpty(ignoreDiagnostics(diagnostics, ["@typespec/http/no-service-found"])); const output: any = {}; - for (const version of versions) { - output[version] = JSON.parse(outputs[resolvePath(version, "openapi.json")]); + for (const [key, filename] of Object.entries(files)) { + output[key] = JSON.parse(outputs[filename as any]); } return output; } +export async function compileVersionedOpenAPI( + code: string, + versions: K[], + options: CompileOpenAPIOptions = {}, +): Promise> { + return compileMultipleOpenAPI( + code, + Object.fromEntries(versions.map((x) => [x, resolvePath("stable", x, "openapi.json")])), + options, + ); +} + export async function CompileOpenApiWithFeatures( code: string, features: F[], From 725e000e87899bc7d129ac4938c6d3a4e11c6dd0 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Wed, 4 Feb 2026 14:22:38 -0500 Subject: [PATCH 8/9] revert --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index f17024309f..3182c02609 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit f17024309f0091f23a3997dac56fbabbc8a5a68d +Subproject commit 3182c02609325d8a3227e9df94a62d36df765321 From 70f5f74229cae31ca0229d7dcde8d64b8d6a7c56 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Thu, 5 Feb 2026 09:34:22 -0500 Subject: [PATCH 9/9] Fix CR comments --- eng/feeds/data-plane/tspconfig.yaml | 4 ++-- packages/typespec-autorest/test/test-host.ts | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/eng/feeds/data-plane/tspconfig.yaml b/eng/feeds/data-plane/tspconfig.yaml index 02bfd9eac2..4bb38b8e88 100644 --- a/eng/feeds/data-plane/tspconfig.yaml +++ b/eng/feeds/data-plane/tspconfig.yaml @@ -7,8 +7,8 @@ emit: - "@azure-tools/typespec-autorest" options: "@azure-tools/typespec-autorest": - emitter-output-dir: "{project-root}/.." - output-file: "data-plane/{service-name}/{version-status}/{version}/openapi.json" + emitter-output-dir: "{project-root}" + output-file: "{emitter-output-dir}/{version-status}/{version}/openapi.json" "@azure-tools/typespec-python": emitter-output-dir: "{output-dir}/{service-dir}/{{#normalizePackageName}}{{parameters.ServiceNamespace}}{{/normalizePackageName}}" namespace: "{{#toLowerCase}}{{parameters.ServiceNamespace}}{{/toLowerCase}}" diff --git a/packages/typespec-autorest/test/test-host.ts b/packages/typespec-autorest/test/test-host.ts index 0bb78744b3..c4350196e3 100644 --- a/packages/typespec-autorest/test/test-host.ts +++ b/packages/typespec-autorest/test/test-host.ts @@ -125,7 +125,12 @@ export async function compileVersionedOpenAPI( ): Promise> { return compileMultipleOpenAPI( code, - Object.fromEntries(versions.map((x) => [x, resolvePath("stable", x, "openapi.json")])), + Object.fromEntries( + versions.map((x) => [ + x, + resolvePath(x.includes("preview") ? "preview" : "stable", x, "openapi.json"), + ]), + ), options, ); }