From 8e8eac8bfc3ad017fb84034b0f38c73d3a567b34 Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Thu, 12 Dec 2024 14:14:13 -0800 Subject: [PATCH 01/11] introduce identifiers decorator and recognize key as identifiers --- packages/typespec-autorest/src/openapi.ts | 7 +- .../test/openapi-output.test.ts | 155 ++++++++++++++++++ .../typespec-azure-resource-manager/README.md | 17 ++ .../generated-defs/Azure.ResourceManager.ts | 22 ++- .../lib/decorators.tsp | 2 + .../src/lib.ts | 4 + .../src/resource.ts | 90 ++++++++++ .../src/rules/missing-x-ms-identifiers.ts | 23 ++- .../src/state.ts | 1 + .../src/tsp-index.ts | 2 + .../test/resource.test.ts | 73 +++++++++ .../rules/missing-x-ms-identifiers.test.ts | 41 ++++- .../reference/decorators.md | 16 ++ .../reference/index.mdx | 1 + 14 files changed, 442 insertions(+), 12 deletions(-) diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index 3ef3f624bf..f231a26376 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -12,6 +12,7 @@ import { } from "@azure-tools/typespec-azure-core"; import { getArmCommonTypeOpenAPIRef, + getArmIdentifiers, isArmCommonType, isAzureResource, isConditionallyFlattened, @@ -2373,9 +2374,9 @@ export async function getOpenAPIForService( visibility: context.visibility | Visibility.Item, }), }; - if (!ifArrayItemContainsIdentifier(program, typespecType as any)) { - array["x-ms-identifiers"] = []; - } + + array["x-ms-identifiers"] = getArmIdentifiers(program, typespecType) ?? []; + return applyIntrinsicDecorators(typespecType, array); } return undefined; diff --git a/packages/typespec-autorest/test/openapi-output.test.ts b/packages/typespec-autorest/test/openapi-output.test.ts index 727f95f758..aeba3e2ed0 100644 --- a/packages/typespec-autorest/test/openapi-output.test.ts +++ b/packages/typespec-autorest/test/openapi-output.test.ts @@ -823,6 +823,161 @@ describe("typespec-autorest: extension decorator", () => { }); }); +describe("typespec-azure: identifiers decorator", () => { + it("uses identifiers decorator for properties", async () => { + const oapi = await openApiFor( + ` + model Pet { + name: string; + age: int32; + } + model PetList { + @identifiers(["name"]) + value: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], ["name"]); + }); + it("identifies keys correctly as x-ms-identifiers", async () => { + const oapi = await openApiFor( + ` + model Pet { + name: string; + @key + age: int32; + } + model PetList { + value: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], ["age"]); + }); + it("prioritizes identifiers decorator over keys", async () => { + const oapi = await openApiFor( + ` + model Pet { + name: string; + @key + age: int32; + } + model PetList { + @identifiers([]) + value: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], []); + }); + it("supports multiple identifiers", async () => { + const oapi = await openApiFor( + ` + model Pet { + name: string; + age: int32; + } + model PetList { + @identifiers(["name", "age"]) + value: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], ["name", "age"]); + }); + it("supports inner properties in identifiers decorator", async () => { + const oapi = await openApiFor( + ` + model Pet { + dogs: Dog; + } + + model Dog { + bread: string; + } + + model PetList { + @identifiers(["dogs/bread"]) + pets: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], ["dogs/bread"]); + }); + it("supports inner properties for keys", async () => { + const oapi = await openApiFor( + ` + model Pet { + dogs: Dog; + cats: Cat; + } + + model Dog { + @key + bread: string; + } + + model Cat + { + features: Features; + } + + model Features { + @key + color:string; + size:int32; + } + + model PetList { + pets: Pet[] + } + + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], [ + "dogs/bread", + "cats/features/color", + ]); + }); + it("supports multiple keys", async () => { + const oapi = await openApiFor( + ` + model Pet { + @key + name: string; + @key + age: int32; + } + model PetList { + pets: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], ["name", "age"]); + }); +}); + describe("typespec-autorest: multipart formData", () => { it("expands model into formData parameters", async () => { const oapi = await openApiFor(` diff --git a/packages/typespec-azure-resource-manager/README.md b/packages/typespec-azure-resource-manager/README.md index 83f2165fc5..c20620db91 100644 --- a/packages/typespec-azure-resource-manager/README.md +++ b/packages/typespec-azure-resource-manager/README.md @@ -79,6 +79,7 @@ Available ruleSets: - [`@armResourceUpdate`](#@armresourceupdate) - [`@armVirtualResource`](#@armvirtualresource) - [`@extensionResource`](#@extensionresource) +- [`@identifiers`](#@identifiers) - [`@locationResource`](#@locationresource) - [`@resourceBaseType`](#@resourcebasetype) - [`@resourceGroupResource`](#@resourcegroupresource) @@ -353,6 +354,22 @@ See more details on [different Azure Resource Manager resource type here.](https None +#### `@identifiers` + +```typespec +@Azure.ResourceManager.identifiers(properties: string[]) +``` + +##### Target + +`ModelProperty` + +##### Parameters + +| Name | Type | Description | +| ---------- | ---------- | ----------- | +| properties | `string[]` | | + #### `@locationResource` `@locationResource` marks an Azure Resource Manager resource model as a location based resource. diff --git a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts index e956b75325..3fda61fd7f 100644 --- a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts +++ b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts @@ -1,9 +1,10 @@ -import type { +import { DecoratorContext, EnumMember, EnumValue, Interface, Model, + ModelProperty, Namespace, Operation, Type, @@ -266,6 +267,24 @@ export type ResourceBaseTypeDecorator = ( baseType: Type, ) => void; +/** + * This decorator is used to indicate the identifying properties of objects in the array, e.g. name + * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. + * + * @example + * ```typespec + * model Pet { + * @identifiers(["name"]) + * dog: Dog; + * } + * ``` + */ +export type IdentifiersDecorator = ( + context: DecoratorContext, + target: ModelProperty, + properties: string[], +) => void; + export type AzureResourceManagerDecorators = { armResourceCollectionAction: ArmResourceCollectionActionDecorator; armProviderNameValue: ArmProviderNameValueDecorator; @@ -288,6 +307,7 @@ export type AzureResourceManagerDecorators = { armCommonTypesVersion: ArmCommonTypesVersionDecorator; armVirtualResource: ArmVirtualResourceDecorator; resourceBaseType: ResourceBaseTypeDecorator; + identifiers: IdentifiersDecorator; }; export type AzureResourceManagerLegacyDecorators = { diff --git a/packages/typespec-azure-resource-manager/lib/decorators.tsp b/packages/typespec-azure-resource-manager/lib/decorators.tsp index 2b99ea3b1f..7f36e603c7 100644 --- a/packages/typespec-azure-resource-manager/lib/decorators.tsp +++ b/packages/typespec-azure-resource-manager/lib/decorators.tsp @@ -191,3 +191,5 @@ extern dec resourceBaseType( target: Model, baseType: "Tenant" | "Subscription" | "ResourceGroup" | "Location" | "Extension" ); + +extern dec identifiers(entity: ModelProperty, properties: string[]); diff --git a/packages/typespec-azure-resource-manager/src/lib.ts b/packages/typespec-azure-resource-manager/src/lib.ts index 11dd6eca9c..d745b90a2a 100644 --- a/packages/typespec-azure-resource-manager/src/lib.ts +++ b/packages/typespec-azure-resource-manager/src/lib.ts @@ -14,6 +14,10 @@ export const $lib = createTypeSpecLibrary({ messages: { armUpdateProviderNamespace: "The parameter to @armUpdateProviderNamespace must be an operation with a 'provider' parameter.", + armIdentifiersIncorrectEntity: + "The @identifiers decorator must be applied to a property that is an array of objects", + armIdentifiersProperties: + "The @identifiers decorator expects a parameter that is an array of strings or an empty array as a parameter.", }, }, "arm-resource-circular-ancestry": { diff --git a/packages/typespec-azure-resource-manager/src/resource.ts b/packages/typespec-azure-resource-manager/src/resource.ts index ecfc16d292..4d08d38f50 100644 --- a/packages/typespec-azure-resource-manager/src/resource.ts +++ b/packages/typespec-azure-resource-manager/src/resource.ts @@ -1,10 +1,12 @@ import { getAllProperties } from "@azure-tools/typespec-azure-core"; import { $tag, + ArrayModelType, DecoratorContext, getKeyName, getTags, Interface, + isArrayModelType, isGlobalNamespace, isNeverType, isTemplateDeclaration, @@ -22,6 +24,7 @@ import { ArmVirtualResourceDecorator, CustomAzureResourceDecorator, ExtensionResourceDecorator, + IdentifiersDecorator, LocationResourceDecorator, ResourceBaseTypeDecorator, ResourceGroupResourceDecorator, @@ -373,6 +376,93 @@ export const $armProviderNameValue: ArmProviderNameValueDecorator = ( } }; +export const $identifiers: IdentifiersDecorator = ( + context: DecoratorContext, + entity: ModelProperty, + properties: string[], +) => { + const { program } = context; + const { type } = entity; + + if ( + type.kind !== "Model" || + !isArrayModelType(program, type) || + type.indexer.value.kind !== "Model" + ) { + reportDiagnostic(program, { + code: "decorator-param-wrong-type", + messageId: "armIdentifiersIncorrectEntity", + target: entity, + }); + return; + } + + const propertiesValues = properties.values; + if (!Array.isArray(propertiesValues)) { + reportDiagnostic(program, { + code: "decorator-param-wrong-type", + messageId: "armIdentifiersProperties", + target: entity, + }); + return; + } + + context.program.stateMap(ArmStateKeys.armIdentifiers).set( + type.indexer.value, + propertiesValues.map((property) => property.value), + ); +}; + +export function getArmIdentifiers(program: Program, entity: ArrayModelType): string[] | undefined { + const value = entity.indexer.value; + + const getIdentifiers = program.stateMap(ArmStateKeys.armIdentifiers).get(value); + if (getIdentifiers !== undefined) { + return getIdentifiers; + } + + const result: string[] = []; + if (value.kind === "Model") { + for (const property of value.properties.values()) { + const pathToKey = getPathToKey(program, property); + if (pathToKey !== undefined) { + result.push(property.name + pathToKey); + } else if (getKeyName(program, property)) { + result.push(property.name); + } + } + } + + return result.length > 0 ? result : undefined; +} + +function getPathToKey( + program: Program, + entity: ModelProperty, + visited = new Set(), +): string | undefined { + if (entity.type.kind !== "Model") { + return undefined; + } + if (visited.has(entity)) { + return undefined; + } + visited.add(entity); + + for (const property of entity.type.properties.values()) { + if (property.type.kind !== "Model" && getKeyName(program, property)) { + return "/" + property.name; + } + if (property.type.kind === "Model") { + const path = getPathToKey(program, property, visited); + if (path !== undefined) { + return "/" + property.name + path; + } + } + } + return undefined; +} + function getServiceNamespace(program: Program, type: Type | undefined): string | undefined { if (type === undefined) return undefined; switch (type.kind) { diff --git a/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts b/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts index 586047cb9d..2967bbbd65 100644 --- a/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts +++ b/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts @@ -9,6 +9,7 @@ import { } from "@typespec/compiler"; import { getExtensions } from "@typespec/openapi"; import { isArmCommonType } from "../common-types.js"; +import { getArmIdentifiers } from "../resource.js"; export const missingXmsIdentifiersRule = createRule({ name: "missing-x-ms-identifiers", @@ -53,16 +54,27 @@ export const missingXmsIdentifiersRule = createRule({ } const xmsIdentifiers = getExtensions(program, property ?? array).get("x-ms-identifiers"); - if (xmsIdentifiers === undefined) { + const armIdentifiers = getArmIdentifiers(program, array); + if (xmsIdentifiers === undefined && armIdentifiers === undefined) { return true; } - if (Array.isArray(xmsIdentifiers)) { - for (const propIdentifier of xmsIdentifiers) { + const identifiers = armIdentifiers ?? xmsIdentifiers; + + if (Array.isArray(identifiers)) { + for (const propIdentifier of identifiers) { if (typeof propIdentifier === "string") { const props = propIdentifier.replace(/^\//, "").split("/"); let element = elementType; for (const prop of props) { + if (element === undefined || element.kind !== "Model") { + context.reportDiagnostic({ + messageId: "missingProperty", + format: { propertyName: prop, targetModelName: element?.name }, + target: property, + }); + return false; + } const propertyValue = getProperty(element, prop); if (propertyValue === undefined) { context.reportDiagnostic({ @@ -72,10 +84,7 @@ export const missingXmsIdentifiersRule = createRule({ }); } - const propertyType = propertyValue?.type as ArrayModelType; - if (propertyType !== undefined && propertyType.kind === "Model") { - element = propertyType; - } + element = propertyValue?.type as ArrayModelType; } } else { context.reportDiagnostic({ diff --git a/packages/typespec-azure-resource-manager/src/state.ts b/packages/typespec-azure-resource-manager/src/state.ts index 7323a184d3..88f3167687 100644 --- a/packages/typespec-azure-resource-manager/src/state.ts +++ b/packages/typespec-azure-resource-manager/src/state.ts @@ -14,6 +14,7 @@ export const ArmStateKeys = { armLibraryNamespaces: azureResourceManagerCreateStateSymbol("armLibraryNamespaces"), usesArmLibraryNamespaces: azureResourceManagerCreateStateSymbol("usesArmLibraryNamespaces"), armCommonTypesVersion: azureResourceManagerCreateStateSymbol("armCommonTypesVersion"), + armIdentifiers: azureResourceManagerCreateStateSymbol("armIdentifiers"), // resource.ts armResourcesCached: azureResourceManagerCreateStateSymbol("armResourcesCached"), diff --git a/packages/typespec-azure-resource-manager/src/tsp-index.ts b/packages/typespec-azure-resource-manager/src/tsp-index.ts index 2d0a27ea1b..1acc6a211f 100644 --- a/packages/typespec-azure-resource-manager/src/tsp-index.ts +++ b/packages/typespec-azure-resource-manager/src/tsp-index.ts @@ -20,6 +20,7 @@ import { $armVirtualResource, $customAzureResource, $extensionResource, + $identifiers, $locationResource, $resourceBaseType, $resourceGroupResource, @@ -54,6 +55,7 @@ export const $decorators = { armCommonTypesVersion: $armCommonTypesVersion, armVirtualResource: $armVirtualResource, resourceBaseType: $resourceBaseType, + identifiers: $identifiers, } satisfies AzureResourceManagerDecorators, "Azure.ResourceManager.Legacy": { customAzureResource: $customAzureResource, diff --git a/packages/typespec-azure-resource-manager/test/resource.test.ts b/packages/typespec-azure-resource-manager/test/resource.test.ts index 2577afb9d8..101889576a 100644 --- a/packages/typespec-azure-resource-manager/test/resource.test.ts +++ b/packages/typespec-azure-resource-manager/test/resource.test.ts @@ -883,3 +883,76 @@ it("recognizes resource with customResource identifier", async () => { `); expectDiagnosticEmpty(diagnostics); }); + +describe("typespec-azure-resource-manager: identifiers decorator", () => { + it("allows multiple model properties in identifiers decorator", async () => { + const { diagnostics } = await checkFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + model Dog { + name: string; + age: int32; + } + + model Pets + { + @identifiers(["name", "age"]) + dogs: Dog[]; + } +`); + + expectDiagnosticEmpty(diagnostics); + }); + + it("allows inner model properties in identifiers decorator", async () => { + const { diagnostics } = await checkFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + model Dog { + breed: Breed; + } + + model Breed { + type: string; + } + + model Pets + { + @identifiers(["breed/type"]) + dogs: Dog[]; + } +`); + + expectDiagnosticEmpty(diagnostics); + }); + + it("emits diagnostic when identifiers is not of a model property object array", async () => { + const { diagnostics } = await checkFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + model Dog { + name: string; + } + + model Pets + { + @identifiers(["age"]) + dogs: Dog; + } +`); + + expectDiagnostics(diagnostics, [ + { + code: "@azure-tools/typespec-azure-resource-manager/decorator-param-wrong-type", + message: + "The @identifiers decorator must be applied to a property that is an array of objects", + }, + ]); + }); +}); diff --git a/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts b/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts index 4c529814b0..6377bd9c40 100644 --- a/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts @@ -177,6 +177,44 @@ describe("typespec-azure-core: no-enum rule", () => { .toBeValid(); }); + it("allow x-ms-identifiers from keys", async () => { + await tester + .expect( + ` + model Pet { + pet: Dog[]; + } + + model Dog { + food: Food; + } + + model Food { + @key + brand: string; + } + `, + ) + .toBeValid(); + }); + + it("allow x-ms-identifiers from identifiers decorator", async () => { + await tester + .expect( + ` + model Pet { + @identifiers(["name"]) + pet: Dog[]; + } + + model Dog { + name: string; + } + `, + ) + .toBeValid(); + }); + it("emit diagnostic if a section is not found", async () => { await tester .expect( @@ -188,12 +226,13 @@ describe("typespec-azure-core: no-enum rule", () => { model Dog { food: string; + brand: string; } `, ) .toEmitDiagnostics({ code: "@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers", - message: `Property "brand" is not found in "Dog". Make sure value of x-ms-identifiers extension are valid property name of the array element.`, + message: `Property "brand" is not found in "string". Make sure value of x-ms-identifiers extension are valid property name of the array element.`, }); }); }); diff --git a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md index 9b2cc18146..e0bcfa3673 100644 --- a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md +++ b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md @@ -272,6 +272,22 @@ See more details on [different Azure Resource Manager resource type here.](https None +### `@identifiers` {#@Azure.ResourceManager.identifiers} + +```typespec +@Azure.ResourceManager.identifiers(properties: string[]) +``` + +#### Target + +`ModelProperty` + +#### Parameters + +| Name | Type | Description | +| ---------- | ---------- | ----------- | +| properties | `string[]` | | + ### `@locationResource` {#@Azure.ResourceManager.locationResource} `@locationResource` marks an Azure Resource Manager resource model as a location based resource. diff --git a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/index.mdx b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/index.mdx index 88fbc6bd48..6a10dbf9ac 100644 --- a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/index.mdx +++ b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/index.mdx @@ -48,6 +48,7 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager - [`@armResourceUpdate`](./decorators.md#@Azure.ResourceManager.armResourceUpdate) - [`@armVirtualResource`](./decorators.md#@Azure.ResourceManager.armVirtualResource) - [`@extensionResource`](./decorators.md#@Azure.ResourceManager.extensionResource) +- [`@identifiers`](./decorators.md#@Azure.ResourceManager.identifiers) - [`@locationResource`](./decorators.md#@Azure.ResourceManager.locationResource) - [`@resourceBaseType`](./decorators.md#@Azure.ResourceManager.resourceBaseType) - [`@resourceGroupResource`](./decorators.md#@Azure.ResourceManager.resourceGroupResource) From 5a3b5d6e4aabf1ffbe1b15b7b18850ef4dce58df Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Thu, 12 Dec 2024 14:17:40 -0800 Subject: [PATCH 02/11] summary of changes --- .../x-ms-identifiers-alternatives-2024-11-12-14-15-30.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .chronus/changes/x-ms-identifiers-alternatives-2024-11-12-14-15-30.md diff --git a/.chronus/changes/x-ms-identifiers-alternatives-2024-11-12-14-15-30.md b/.chronus/changes/x-ms-identifiers-alternatives-2024-11-12-14-15-30.md new file mode 100644 index 0000000000..c2beccae88 --- /dev/null +++ b/.chronus/changes/x-ms-identifiers-alternatives-2024-11-12-14-15-30.md @@ -0,0 +1,8 @@ +--- +changeKind: feature +packages: + - "@azure-tools/typespec-autorest" + - "@azure-tools/typespec-azure-resource-manager" +--- + +Use the @identifiers decorator to identify and utilize identifiers for x-ms-identifiers. Additionally, use the @key decorator to identify identifiers. From 9be6ae0f62bde7adce8fba49094ec35e7381a9f3 Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Mon, 16 Dec 2024 14:29:36 -0800 Subject: [PATCH 03/11] avoid adding x-ms-identifiers unexpected --- packages/typespec-autorest/src/openapi.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index f231a26376..dabcec7c8b 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -2375,7 +2375,12 @@ export async function getOpenAPIForService( }), }; - array["x-ms-identifiers"] = getArmIdentifiers(program, typespecType) ?? []; + const armIdentifiers = getArmIdentifiers(program, typespecType); + if (armIdentifiers !== undefined && armIdentifiers.length > 0) { + array["x-ms-identifiers"] = armIdentifiers; + } else if (!ifArrayItemContainsIdentifier(program, typespecType as any)) { + array["x-ms-identifiers"] = []; + } return applyIntrinsicDecorators(typespecType, array); } From d7cce7a627dafab73fc9b708b517012fb184440b Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Mon, 16 Dec 2024 17:06:17 -0800 Subject: [PATCH 04/11] update examples with x-ms-identifiers comming from keys --- .../2021-09-21-preview/openapi.json | 30 +++++++++++++++---- .../2021-10-01-preview/openapi.json | 5 +++- .../2023-03-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 5 +++- .../2023-03-01-preview/openapi.json | 5 +++- .../2023-03-01-preview/openapi.json | 5 +++- .../2023-03-01-preview/openapi.json | 5 +++- .../2023-08-01-preview/openapi.json | 15 ++++++++-- .../2023-11-01-preview/openapi.json | 15 ++++++++-- .../2021-10-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 10 +++++-- .../2021-10-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 5 +++- .../2021-10-01-preview/openapi.json | 5 +++- 16 files changed, 104 insertions(+), 26 deletions(-) diff --git a/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json index fa15dbca46..68b770380a 100644 --- a/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json @@ -1708,7 +1708,10 @@ "description": "The AllPropertiesResource items on this page", "items": { "$ref": "#/definitions/AllPropertiesResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2118,7 +2121,10 @@ "description": "The TestExtensionResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestExtensionResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2161,7 +2167,10 @@ "description": "The TestTenantResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTenantResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2204,7 +2213,10 @@ "description": "The TestTrackedChild items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTrackedChild" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2225,7 +2237,10 @@ "description": "The TestTrackedResource2 items on this page", "items": { "$ref": "#/definitions/Microsoft.OperationsTest.TestTrackedResource2" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2246,7 +2261,10 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTrackedResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 39bf6c0ec1..1c3c2fc219 100644 --- a/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -395,7 +395,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index dc8b04501c..c34f315edf 100644 --- a/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -427,7 +427,10 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index ad71805d22..a7b8ff2ecb 100644 --- a/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -624,7 +624,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index 22d4543ac4..2e287e2e89 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -476,7 +476,10 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index c31a6041a9..64241d80a0 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -423,7 +423,10 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index a476b4b43c..7e58765e41 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -427,7 +427,10 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json index 410346aa0f..e3f22a97bb 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json @@ -667,7 +667,10 @@ "description": "The PrivateEndpointConnectionResource items on this page", "items": { "$ref": "#/definitions/PrivateEndpointConnectionResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -704,7 +707,10 @@ "description": "The PrivateLinkResource items on this page", "items": { "$ref": "#/definitions/PrivateLinkResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -769,7 +775,10 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/TestTrackedResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json index 4645f79a80..030ffb1bdc 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json @@ -667,7 +667,10 @@ "description": "The PrivateEndpointConnectionResource items on this page", "items": { "$ref": "#/definitions/PrivateEndpointConnectionResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -704,7 +707,10 @@ "description": "The PrivateLinkResource items on this page", "items": { "$ref": "#/definitions/PrivateLinkResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -769,7 +775,10 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/TestTrackedResource" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index d4128eafac..ef3e8c5215 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -420,7 +420,10 @@ "description": "The RoleAssignment items on this page", "items": { "$ref": "#/definitions/RoleAssignment" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index f2912fd099..69ec1d9626 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -473,7 +473,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index f71fbe1202..4119af6f8c 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -767,7 +767,10 @@ "description": "The Dependent items on this page", "items": { "$ref": "#/definitions/Dependent" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -859,7 +862,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index a702a89021..b4e7e45aa5 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -372,7 +372,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 7bf19e0f7d..f400bc38f5 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -410,7 +410,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 01aa20793b..de1217236a 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -486,7 +486,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index ed019d6da6..71e14cb760 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -578,7 +578,10 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - } + }, + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", From 28c371d2d2b0e424b12d450229a8c1fa588a4f7b Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Tue, 17 Dec 2024 10:07:13 -0800 Subject: [PATCH 05/11] missing identifiers on openapi.json files --- .../typespec-autorest/2022-08-31/openapi.json | 9 +++++++-- .../typespec-autorest/2022-08-31/openapi.json | 4 +++- .../typespec-autorest/2022-08-31/openapi.json | 9 +++++++-- .../typespec-autorest/2023-02-07/openapi.json | 9 +++++++-- .../typespec-autorest/2022-08-31/openapi.json | 13 +++++++++--- .../typespec-autorest/openapi.json | 20 +++++++++++++++---- 6 files changed, 50 insertions(+), 14 deletions(-) diff --git a/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 8e88d3c379..bcfab54747 100644 --- a/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -1188,7 +1188,10 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -1210,7 +1213,9 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 584e71a2fa..91b847dbc4 100644 --- a/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -631,7 +631,9 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 844583ba11..72caf3680f 100644 --- a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -1092,7 +1092,10 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -1114,7 +1117,9 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json index 68dae847bc..13a538572f 100644 --- a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json @@ -1188,7 +1188,10 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -1210,7 +1213,9 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json index b046890c90..856551ea53 100644 --- a/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -2086,7 +2086,10 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -2108,7 +2111,9 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", @@ -2130,7 +2135,9 @@ "items": { "$ref": "#/definitions/WidgetPart" }, - "x-ms-identifiers": [] + "x-ms-identifiers": [ + "name" + ] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json b/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json index b9c8a49efa..8f1e4efc8a 100644 --- a/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json +++ b/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json @@ -739,7 +739,10 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Checkup" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -831,7 +834,10 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Owner" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -913,7 +919,10 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Pet" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", @@ -1020,7 +1029,10 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Toy" - } + }, + "x-ms-identifiers": [ + "id" + ] }, "nextLink": { "type": "string", From 37fcd7a6c38ac53690f615a33f14d067dee0b6ea Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Thu, 26 Dec 2024 10:57:33 -0800 Subject: [PATCH 06/11] Feedback: id/name are default keys so no need to show them or trigger warning when they are present --- .../typespec-autorest/2022-08-31/openapi.json | 9 ++---- .../typespec-autorest/2022-08-31/openapi.json | 4 +-- .../typespec-autorest/2022-08-31/openapi.json | 9 ++---- .../typespec-autorest/2023-02-07/openapi.json | 9 ++---- .../typespec-autorest/2022-08-31/openapi.json | 13 ++------ .../2021-09-21-preview/openapi.json | 30 ++++--------------- .../2021-10-01-preview/openapi.json | 5 +--- .../2023-03-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 5 +--- .../2023-03-01-preview/openapi.json | 5 +--- .../2023-03-01-preview/openapi.json | 5 +--- .../2023-03-01-preview/openapi.json | 5 +--- .../2023-08-01-preview/openapi.json | 15 ++-------- .../2023-11-01-preview/openapi.json | 15 ++-------- .../2021-10-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 10 ++----- .../2021-10-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 5 +--- .../2021-10-01-preview/openapi.json | 5 +--- .../typespec-autorest/openapi.json | 20 +++---------- packages/typespec-autorest/src/openapi.ts | 10 ++++++- .../test/openapi-output.test.ts | 19 ++++++++++++ .../generated-defs/Azure.ResourceManager.ts | 4 +-- .../src/resource.ts | 12 ++++++++ .../src/rules/missing-x-ms-identifiers.ts | 2 +- .../rules/missing-x-ms-identifiers.test.ts | 16 ++++++++++ 28 files changed, 99 insertions(+), 158 deletions(-) diff --git a/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json index bcfab54747..8e88d3c379 100644 --- a/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/api-path-parameter/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -1188,10 +1188,7 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -1213,9 +1210,7 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 91b847dbc4..584e71a2fa 100644 --- a/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/custom-error-type/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -631,9 +631,7 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 72caf3680f..844583ba11 100644 --- a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -1092,10 +1092,7 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -1117,9 +1114,7 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json index 13a538572f..68dae847bc 100644 --- a/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/trait-versioning/@azure-tools/typespec-autorest/2023-02-07/openapi.json @@ -1188,10 +1188,7 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -1213,9 +1210,7 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json b/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json index 856551ea53..b046890c90 100644 --- a/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json +++ b/packages/samples/test/output/azure/core/data-plane/widget-manager/@azure-tools/typespec-autorest/2022-08-31/openapi.json @@ -2086,10 +2086,7 @@ "description": "The Manufacturer items on this page", "items": { "$ref": "#/definitions/Manufacturer" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -2111,9 +2108,7 @@ "items": { "$ref": "#/definitions/Widget" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", @@ -2135,9 +2130,7 @@ "items": { "$ref": "#/definitions/WidgetPart" }, - "x-ms-identifiers": [ - "name" - ] + "x-ms-identifiers": [] }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json index 68b770380a..fa15dbca46 100644 --- a/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/arm-library/@azure-tools/typespec-autorest/2021-09-21-preview/openapi.json @@ -1708,10 +1708,7 @@ "description": "The AllPropertiesResource items on this page", "items": { "$ref": "#/definitions/AllPropertiesResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -2121,10 +2118,7 @@ "description": "The TestExtensionResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestExtensionResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -2167,10 +2161,7 @@ "description": "The TestTenantResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTenantResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -2213,10 +2204,7 @@ "description": "The TestTrackedChild items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTrackedChild" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -2237,10 +2225,7 @@ "description": "The TestTrackedResource2 items on this page", "items": { "$ref": "#/definitions/Microsoft.OperationsTest.TestTrackedResource2" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -2261,10 +2246,7 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/Microsoft.InterfacesTest.TestTrackedResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 1c3c2fc219..39bf6c0ec1 100644 --- a/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/contoso/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -395,10 +395,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index c34f315edf..dc8b04501c 100644 --- a/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/legacy/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -427,10 +427,7 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index a7b8ff2ecb..ad71805d22 100644 --- a/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/operations/nobody-action/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -624,10 +624,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index 2e287e2e89..22d4543ac4 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/common-properties/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -476,10 +476,7 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index 64241d80a0..c31a6041a9 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/encryption/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -423,10 +423,7 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json index 7e58765e41..a476b4b43c 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/managed-identity/@azure-tools/typespec-autorest/2023-03-01-preview/openapi.json @@ -427,10 +427,7 @@ "description": "The WidgetResource items on this page", "items": { "$ref": "#/definitions/WidgetResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json index e3f22a97bb..410346aa0f 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-08-01-preview/openapi.json @@ -667,10 +667,7 @@ "description": "The PrivateEndpointConnectionResource items on this page", "items": { "$ref": "#/definitions/PrivateEndpointConnectionResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -707,10 +704,7 @@ "description": "The PrivateLinkResource items on this page", "items": { "$ref": "#/definitions/PrivateLinkResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -775,10 +769,7 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/TestTrackedResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json index 030ffb1bdc..4645f79a80 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-common-properties/private-links/@azure-tools/typespec-autorest/2023-11-01-preview/openapi.json @@ -667,10 +667,7 @@ "description": "The PrivateEndpointConnectionResource items on this page", "items": { "$ref": "#/definitions/PrivateEndpointConnectionResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -707,10 +704,7 @@ "description": "The PrivateLinkResource items on this page", "items": { "$ref": "#/definitions/PrivateLinkResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -775,10 +769,7 @@ "description": "The TestTrackedResource items on this page", "items": { "$ref": "#/definitions/TestTrackedResource" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index ef3e8c5215..d4128eafac 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/extension/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -420,10 +420,7 @@ "description": "The RoleAssignment items on this page", "items": { "$ref": "#/definitions/RoleAssignment" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 69ec1d9626..f2912fd099 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/location/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -473,10 +473,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 4119af6f8c..f71fbe1202 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/proxy/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -767,10 +767,7 @@ "description": "The Dependent items on this page", "items": { "$ref": "#/definitions/Dependent" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", @@ -862,10 +859,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index b4e7e45aa5..a702a89021 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/singleton/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -372,10 +372,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index f400bc38f5..7bf19e0f7d 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/tenant/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -410,10 +410,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index de1217236a..01aa20793b 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/tracked/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -486,10 +486,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json b/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json index 71e14cb760..ed019d6da6 100644 --- a/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json +++ b/packages/samples/test/output/azure/resource-manager/resource-types/virtual-resource/@azure-tools/typespec-autorest/2021-10-01-preview/openapi.json @@ -578,10 +578,7 @@ "description": "The Employee items on this page", "items": { "$ref": "#/definitions/Employee" - }, - "x-ms-identifiers": [ - "name" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json b/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json index 8f1e4efc8a..b9c8a49efa 100644 --- a/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json +++ b/packages/samples/test/output/core/rest/petstore/@azure-tools/typespec-autorest/openapi.json @@ -739,10 +739,7 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Checkup" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -834,10 +831,7 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Owner" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -919,10 +913,7 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Pet" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", @@ -1029,10 +1020,7 @@ "description": "The items on this page", "items": { "$ref": "#/definitions/Toy" - }, - "x-ms-identifiers": [ - "id" - ] + } }, "nextLink": { "type": "string", diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index dabcec7c8b..eb0f9336cc 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -1834,6 +1834,10 @@ export async function getOpenAPIForService( ); } + function ifArmIdentifiersDefault(armIdentifiers: string[]) { + return armIdentifiers.every((identifier) => identifier === "id" || identifier === "name"); + } + function getSchemaForUnionVariant( variant: UnionVariant, schemaContext: SchemaContext, @@ -2376,7 +2380,11 @@ export async function getOpenAPIForService( }; const armIdentifiers = getArmIdentifiers(program, typespecType); - if (armIdentifiers !== undefined && armIdentifiers.length > 0) { + if ( + armIdentifiers !== undefined && + armIdentifiers.length > 0 && + !ifArmIdentifiersDefault(armIdentifiers) + ) { array["x-ms-identifiers"] = armIdentifiers; } else if (!ifArrayItemContainsIdentifier(program, typespecType as any)) { array["x-ms-identifiers"] = []; diff --git a/packages/typespec-autorest/test/openapi-output.test.ts b/packages/typespec-autorest/test/openapi-output.test.ts index aeba3e2ed0..8610e30d48 100644 --- a/packages/typespec-autorest/test/openapi-output.test.ts +++ b/packages/typespec-autorest/test/openapi-output.test.ts @@ -824,6 +824,25 @@ describe("typespec-autorest: extension decorator", () => { }); describe("typespec-azure: identifiers decorator", () => { + it("ignores name/id keys for x-ms-identifiers", async () => { + const oapi = await openApiFor( + ` + model Pet { + @key + name: string; + @key + id: int32; + } + model PetList { + value: Pet[] + } + @route("/Pets") + @get op list(): PetList; + `, + ); + ok(oapi.paths["/Pets"].get); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], undefined); + }); it("uses identifiers decorator for properties", async () => { const oapi = await openApiFor( ` diff --git a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts index 3fda61fd7f..2beded8e88 100644 --- a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts +++ b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts @@ -268,13 +268,13 @@ export type ResourceBaseTypeDecorator = ( ) => void; /** - * This decorator is used to indicate the identifying properties of objects in the array, e.g. name + * This decorator is used to indicate the identifying properties of objects in the array, e.g. size * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. * * @example * ```typespec * model Pet { - * @identifiers(["name"]) + * @identifiers(["size"]) * dog: Dog; * } * ``` diff --git a/packages/typespec-azure-resource-manager/src/resource.ts b/packages/typespec-azure-resource-manager/src/resource.ts index 4d08d38f50..683204fca8 100644 --- a/packages/typespec-azure-resource-manager/src/resource.ts +++ b/packages/typespec-azure-resource-manager/src/resource.ts @@ -376,6 +376,18 @@ export const $armProviderNameValue: ArmProviderNameValueDecorator = ( } }; +/** + * This decorator is used to indicate the identifying properties of objects in the array, e.g. size + * The properties that are used as identifiers for the object needs to be provided as a list of strings. + * + * @example + * ```typespec + * model Pet { + * @identifiers(["size"]) + * dog: Dog; + * } + * ``` + */ export const $identifiers: IdentifiersDecorator = ( context: DecoratorContext, entity: ModelProperty, diff --git a/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts b/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts index 2967bbbd65..0ec879469f 100644 --- a/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts +++ b/packages/typespec-azure-resource-manager/src/rules/missing-x-ms-identifiers.ts @@ -49,7 +49,7 @@ export const missingXmsIdentifiersRule = createRule({ return false; } - if (getProperty(elementType, "id")) { + if (getProperty(elementType, "id") || getProperty(elementType, "name")) { return false; } diff --git a/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts b/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts index 6377bd9c40..0b84b96d79 100644 --- a/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/missing-x-ms-identifiers.test.ts @@ -198,6 +198,22 @@ describe("typespec-azure-core: no-enum rule", () => { .toBeValid(); }); + it("allow x-ms-identifiers from keys on default identifiers", async () => { + await tester + .expect( + ` + model Pet { + pet: Dog[]; + } + + model Dog { + name: string; + } + `, + ) + .toBeValid(); + }); + it("allow x-ms-identifiers from identifiers decorator", async () => { await tester .expect( From 170f81975682ffb51493ae577483887a9c7aa9d2 Mon Sep 17 00:00:00 2001 From: Alitzel Mendez <6895254+AlitzelMendez@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:58:22 -0800 Subject: [PATCH 07/11] Update packages/typespec-azure-resource-manager/src/lib.ts Co-authored-by: Mark Cowlishaw --- packages/typespec-azure-resource-manager/src/lib.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typespec-azure-resource-manager/src/lib.ts b/packages/typespec-azure-resource-manager/src/lib.ts index d745b90a2a..e823b7116c 100644 --- a/packages/typespec-azure-resource-manager/src/lib.ts +++ b/packages/typespec-azure-resource-manager/src/lib.ts @@ -17,7 +17,7 @@ export const $lib = createTypeSpecLibrary({ armIdentifiersIncorrectEntity: "The @identifiers decorator must be applied to a property that is an array of objects", armIdentifiersProperties: - "The @identifiers decorator expects a parameter that is an array of strings or an empty array as a parameter.", + "The @identifiers decorator expects a parameter that is an array of strings or an empty array.", }, }, "arm-resource-circular-ancestry": { From ed89e107e587e3cc137ecd45ca1a798f6dcce4bf Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Thu, 26 Dec 2024 11:04:13 -0800 Subject: [PATCH 08/11] Add more documentation --- packages/typespec-azure-resource-manager/src/resource.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/typespec-azure-resource-manager/src/resource.ts b/packages/typespec-azure-resource-manager/src/resource.ts index 683204fca8..ac454cd782 100644 --- a/packages/typespec-azure-resource-manager/src/resource.ts +++ b/packages/typespec-azure-resource-manager/src/resource.ts @@ -425,6 +425,11 @@ export const $identifiers: IdentifiersDecorator = ( ); }; +/** + * This function returns all arm identifiers for the given array model type + * This includes the identifiers specified using the @identifiers decorator + * and the identifiers using the @key decorator. + */ export function getArmIdentifiers(program: Program, entity: ArrayModelType): string[] | undefined { const value = entity.indexer.value; From 8a6684d85b75e12ad83d2730b95409a852912917 Mon Sep 17 00:00:00 2001 From: Alitzel Mendez Bustillo Date: Thu, 26 Dec 2024 11:27:14 -0800 Subject: [PATCH 09/11] fix test & more docs --- packages/typespec-autorest/test/openapi-output.test.ts | 4 ++-- packages/typespec-azure-resource-manager/src/resource.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/typespec-autorest/test/openapi-output.test.ts b/packages/typespec-autorest/test/openapi-output.test.ts index 8610e30d48..4a1f02484b 100644 --- a/packages/typespec-autorest/test/openapi-output.test.ts +++ b/packages/typespec-autorest/test/openapi-output.test.ts @@ -851,7 +851,7 @@ describe("typespec-azure: identifiers decorator", () => { age: int32; } model PetList { - @identifiers(["name"]) + @identifiers(["age"]) value: Pet[] } @route("/Pets") @@ -859,7 +859,7 @@ describe("typespec-azure: identifiers decorator", () => { `, ); ok(oapi.paths["/Pets"].get); - deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], ["name"]); + deepStrictEqual(oapi.definitions.PetList.properties.value["x-ms-identifiers"], ["age"]); }); it("identifies keys correctly as x-ms-identifiers", async () => { const oapi = await openApiFor( diff --git a/packages/typespec-azure-resource-manager/src/resource.ts b/packages/typespec-azure-resource-manager/src/resource.ts index ac454cd782..12bb2f85c0 100644 --- a/packages/typespec-azure-resource-manager/src/resource.ts +++ b/packages/typespec-azure-resource-manager/src/resource.ts @@ -380,6 +380,10 @@ export const $armProviderNameValue: ArmProviderNameValueDecorator = ( * This decorator is used to indicate the identifying properties of objects in the array, e.g. size * The properties that are used as identifiers for the object needs to be provided as a list of strings. * + * @param context The decorator context + * @param entity The model property in which the identifiers are being set. + * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. + * * @example * ```typespec * model Pet { @@ -429,6 +433,10 @@ export const $identifiers: IdentifiersDecorator = ( * This function returns all arm identifiers for the given array model type * This includes the identifiers specified using the @identifiers decorator * and the identifiers using the @key decorator. + * + * @param program The program to process. + * @param entity The array model type to check. + * @returns returns list of arm identifiers for the given array model type if any or undefined. */ export function getArmIdentifiers(program: Program, entity: ArrayModelType): string[] | undefined { const value = entity.indexer.value; From c580cf25cef3b4f8213e73baf6cc695c38cd0721 Mon Sep 17 00:00:00 2001 From: AlitzelMendez Date: Tue, 7 Jan 2025 11:43:50 -0800 Subject: [PATCH 10/11] Documentation --- .../typespec-azure-resource-manager/README.md | 18 +++++++++++++++--- .../generated-defs/Azure.ResourceManager.ts | 12 ------------ .../lib/decorators.tsp | 14 ++++++++++++++ .../src/resource.ts | 16 ---------------- .../reference/decorators.md | 18 +++++++++++++++--- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/packages/typespec-azure-resource-manager/README.md b/packages/typespec-azure-resource-manager/README.md index c20620db91..e78cf6d03b 100644 --- a/packages/typespec-azure-resource-manager/README.md +++ b/packages/typespec-azure-resource-manager/README.md @@ -356,6 +356,9 @@ None #### `@identifiers` +This decorator is used to indicate the identifying properties of objects in the array, e.g. size +The properties that are used as identifiers for the object needs to be provided as a list of strings. + ```typespec @Azure.ResourceManager.identifiers(properties: string[]) ``` @@ -366,9 +369,18 @@ None ##### Parameters -| Name | Type | Description | -| ---------- | ---------- | ----------- | -| properties | `string[]` | | +| Name | Type | Description | +| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------- | +| properties | `string[]` | The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. | + +##### Examples + +```typespec +model Pet { + @identifiers(["size"]) + dog: Dog; +} +``` #### `@locationResource` diff --git a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts index 2beded8e88..0b6b4d39aa 100644 --- a/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts +++ b/packages/typespec-azure-resource-manager/generated-defs/Azure.ResourceManager.ts @@ -267,18 +267,6 @@ export type ResourceBaseTypeDecorator = ( baseType: Type, ) => void; -/** - * This decorator is used to indicate the identifying properties of objects in the array, e.g. size - * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. - * - * @example - * ```typespec - * model Pet { - * @identifiers(["size"]) - * dog: Dog; - * } - * ``` - */ export type IdentifiersDecorator = ( context: DecoratorContext, target: ModelProperty, diff --git a/packages/typespec-azure-resource-manager/lib/decorators.tsp b/packages/typespec-azure-resource-manager/lib/decorators.tsp index 7f36e603c7..d56bc315b0 100644 --- a/packages/typespec-azure-resource-manager/lib/decorators.tsp +++ b/packages/typespec-azure-resource-manager/lib/decorators.tsp @@ -192,4 +192,18 @@ extern dec resourceBaseType( baseType: "Tenant" | "Subscription" | "ResourceGroup" | "Location" | "Extension" ); +/** + * This decorator is used to indicate the identifying properties of objects in the array, e.g. size + * The properties that are used as identifiers for the object needs to be provided as a list of strings. + * + * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. + * + * @example + * ```typespec + * model Pet { + * @identifiers(["size"]) + * dog: Dog; + * } + * ``` + */ extern dec identifiers(entity: ModelProperty, properties: string[]); diff --git a/packages/typespec-azure-resource-manager/src/resource.ts b/packages/typespec-azure-resource-manager/src/resource.ts index 12bb2f85c0..aee7ce9753 100644 --- a/packages/typespec-azure-resource-manager/src/resource.ts +++ b/packages/typespec-azure-resource-manager/src/resource.ts @@ -376,22 +376,6 @@ export const $armProviderNameValue: ArmProviderNameValueDecorator = ( } }; -/** - * This decorator is used to indicate the identifying properties of objects in the array, e.g. size - * The properties that are used as identifiers for the object needs to be provided as a list of strings. - * - * @param context The decorator context - * @param entity The model property in which the identifiers are being set. - * @param properties The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. - * - * @example - * ```typespec - * model Pet { - * @identifiers(["size"]) - * dog: Dog; - * } - * ``` - */ export const $identifiers: IdentifiersDecorator = ( context: DecoratorContext, entity: ModelProperty, diff --git a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md index e0bcfa3673..8f07c32af2 100644 --- a/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md +++ b/website/src/content/docs/docs/libraries/azure-resource-manager/reference/decorators.md @@ -274,6 +274,9 @@ None ### `@identifiers` {#@Azure.ResourceManager.identifiers} +This decorator is used to indicate the identifying properties of objects in the array, e.g. size +The properties that are used as identifiers for the object needs to be provided as a list of strings. + ```typespec @Azure.ResourceManager.identifiers(properties: string[]) ``` @@ -284,9 +287,18 @@ None #### Parameters -| Name | Type | Description | -| ---------- | ---------- | ----------- | -| properties | `string[]` | | +| Name | Type | Description | +| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------- | +| properties | `string[]` | The list of properties that are used as identifiers for the object. This needs to be provided as a list of strings. | + +#### Examples + +```typespec +model Pet { + @identifiers(["size"]) + dog: Dog; +} +``` ### `@locationResource` {#@Azure.ResourceManager.locationResource} From cd50b980c57aff62e9114344c7b104627fe64084 Mon Sep 17 00:00:00 2001 From: AlitzelMendez Date: Thu, 9 Jan 2025 16:08:55 -0800 Subject: [PATCH 11/11] fix typo --- packages/typespec-autorest/test/openapi-output.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/typespec-autorest/test/openapi-output.test.ts b/packages/typespec-autorest/test/openapi-output.test.ts index 4a1f02484b..81d13e7aff 100644 --- a/packages/typespec-autorest/test/openapi-output.test.ts +++ b/packages/typespec-autorest/test/openapi-output.test.ts @@ -924,11 +924,11 @@ describe("typespec-azure: identifiers decorator", () => { } model Dog { - bread: string; + breed: string; } model PetList { - @identifiers(["dogs/bread"]) + @identifiers(["dogs/breed"]) pets: Pet[] } @route("/Pets") @@ -936,7 +936,7 @@ describe("typespec-azure: identifiers decorator", () => { `, ); ok(oapi.paths["/Pets"].get); - deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], ["dogs/bread"]); + deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], ["dogs/breed"]); }); it("supports inner properties for keys", async () => { const oapi = await openApiFor( @@ -948,7 +948,7 @@ describe("typespec-azure: identifiers decorator", () => { model Dog { @key - bread: string; + breed: string; } model Cat @@ -972,7 +972,7 @@ describe("typespec-azure: identifiers decorator", () => { ); ok(oapi.paths["/Pets"].get); deepStrictEqual(oapi.definitions.PetList.properties.pets["x-ms-identifiers"], [ - "dogs/bread", + "dogs/breed", "cats/features/color", ]); });