Skip to content

Commit

Permalink
Upgrade tsp to 0.58 (#4998)
Browse files Browse the repository at this point in the history
Upgrade tsp version of converter to 0.58

Uptake changes from 

- Azure/typespec-azure#709

1. For brownfield: add flag `arm-resource-flattening`, add
`@@flattenProperty` to properties if needed, direct use of
Azure.ResourceManager.XXXResource allows us not need
`x-ms-client-flatten` any more.
2. For greenfield: no flag `arm-resource-flattening`, no
`@@flattenProperty`

- Azure/typespec-azure#862

Remove all the workaround for Azure.ResourceManager.XXXResource.

---------

Co-authored-by: Pan Shao <[email protected]>
  • Loading branch information
pshao25 and Pan Shao authored Aug 12, 2024
1 parent 4d3ee05 commit 812da78
Show file tree
Hide file tree
Showing 233 changed files with 3,074 additions and 2,228 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@autorest/openapi-to-typespec",
"comment": "upgrade tsp version of converter to 0.58",
"type": "patch"
}
],
"packageName": "@autorest/openapi-to-typespec"
}
499 changes: 328 additions & 171 deletions common/config/rush/pnpm-lock.yaml

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions packages/extensions/openapi-to-typespec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@
"@azure-tools/codegen": "~2.10.0",
"@autorest/extension-base": "~3.6.0",
"@autorest/codemodel": "~4.20.0",
"@typespec/compiler": "^0.57.0",
"@typespec/rest": "^0.57.0",
"@typespec/http": "^0.57.0",
"@typespec/versioning": "^0.57.0",
"@typespec/prettier-plugin-typespec": "^0.57.0",
"@azure-tools/typespec-azure-core": "^0.43.0",
"@azure-tools/typespec-autorest": "^0.43.0",
"@azure-tools/typespec-azure-resource-manager": "^0.43.0",
"@typespec/openapi": "^0.57.0",
"@typespec/openapi3": "^0.57.0",
"@typespec/compiler": "^0.58.0",
"@typespec/rest": "^0.58.0",
"@typespec/http": "^0.58.0",
"@typespec/versioning": "^0.58.0",
"@typespec/prettier-plugin-typespec": "^0.58.0",
"@azure-tools/typespec-azure-core": "^0.44.0",
"@azure-tools/typespec-autorest": "^0.44.0",
"@azure-tools/typespec-azure-resource-manager": "^0.44.0",
"@typespec/openapi": "^0.58.0",
"@typespec/openapi3": "^0.58.0",
"prettier": "~3.1.0",
"lodash": "~4.17.20",
"pluralize": "^8.0.0",
Expand All @@ -68,8 +68,8 @@
"fs-extra": "^10.1.0",
"@types/fs-extra": "^9.0.13",
"chalk": "^4.1.0",
"@azure-tools/typespec-autorest": "^0.43.0",
"@azure-tools/typespec-client-generator-core": "^0.43.0",
"@azure-tools/typespec-autorest": "^0.44.0",
"@azure-tools/typespec-client-generator-core": "^0.44.0",
"webpack-cli": "~5.1.4",
"webpack": "~5.89.0",
"@typescript-eslint/eslint-plugin": "^6.11.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { formatFile } from "../utils/format";

export async function emitTypespecConfig(filePath: string, programDetails: TypespecProgram): Promise<void> {
const session = getSession();
const { isArm } = getOptions();
const { isArm, isFullCompatible } = getOptions();
let content = `
emit:
- "@azure-tools/typespec-autorest"
Expand Down Expand Up @@ -43,7 +43,12 @@ options:
emitter-output-dir: "{project-root}/.."
azure-resource-provider-folder: "resource-manager"
output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/${swaggerName}"
examples-directory: "{project-root}/examples"
examples-directory: "{project-root}/examples"${
isFullCompatible
? `
arm-resource-flattening: true`
: ""
}
linter:
extends:
- "@azure-tools/typespec-azure-resource-manager/all"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ export function generateArmResource(resource: TspArmResource): string {
}

function generateArmResourceModel(resource: TspArmResource): string {
const { isFullCompatible } = getOptions();

let definitions: string[] = [];

for (const fixme of resource.fixMe ?? []) {
Expand All @@ -58,57 +56,16 @@ function generateArmResourceModel(resource: TspArmResource): string {
definitions.push(`@parentResource(${resource.locationParent})`);
}

if (
!isFullCompatible ||
(getArmCommonTypeVersion() &&
!resource.propertiesPropertyRequired &&
resource.propertiesPropertyVisibility.length === 2 &&
resource.propertiesPropertyVisibility.includes("read") &&
resource.propertiesPropertyVisibility.includes("create"))
) {
definitions.push(
`model ${resource.name} is Azure.ResourceManager.${resource.resourceKind}<${resource.propertiesModelName}> {`,
);

if (resource.keyExpression) {
definitions.push(`${resource.keyExpression}`);
}
definitions = [...definitions, ...getModelPropertiesDeclarations(resource.properties)];
} else {
definitions.push(
`#suppress "@azure-tools/typespec-azure-core/composition-over-inheritance" "For backward compatibility"`,
);
definitions.push(
`#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property" "For backward compatibility"`,
);
definitions.push(`@includeInapplicableMetadataInPayload(false)`);

if (!getArmCommonTypeVersion()) {
if (resource.baseModelName) {
definitions.push(`model ${resource.name} extends ${resource.baseModelName} {`);
} else {
definitions.push(`model ${resource.name} {`);
}
} else {
definitions.push(`@Azure.ResourceManager.Private.armResourceInternal(${resource.propertiesModelName})`);
definitions.push(`model ${resource.name} extends Foundations.${resource.resourceKind} {`);
}

if (resource.keyExpression) {
definitions.push(`${resource.keyExpression}`);
}
definitions = [...definitions, ...getModelPropertiesDeclarations(resource.properties)];

const propertyDoc = generateDocs({ doc: resource.propertiesPropertyDescription });
propertyDoc && definitions.push(propertyDoc);

definitions.push(`@extension("x-ms-client-flatten", true)`);
if (resource.propertiesPropertyVisibility.length > 0) {
definitions.push(`@visibility("${resource.propertiesPropertyVisibility.join(",")}")`);
}
definitions.push(
`model ${resource.name} is Azure.ResourceManager.${resource.resourceKind}<${resource.propertiesModelName}${
resource.propertiesPropertyRequired ? ", false" : ""
}> {`,
);

definitions.push(`properties${resource.propertiesPropertyRequired ? "" : "?"}: ${resource.propertiesModelName}`);
if (resource.keyExpression) {
definitions.push(`${resource.keyExpression}`);
}
definitions = [...definitions, ...getModelPropertiesDeclarations(resource.properties)];

for (const p of resource.optionalStandardProperties) {
definitions.push(`\n...${p}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,11 @@ export function generateArmResourceClientDecorator(resource: TspArmResource): st
decorators && definitions.push(decorators);
}

const propertyDecorators = generateAugmentedDecorators(
`${resource.name}.properties`,
resource.propertiesPropertyClientDecorator,
);
propertyDecorators && definitions.push(propertyDecorators);

return definitions.join("\n");
}
2 changes: 1 addition & 1 deletion packages/extensions/openapi-to-typespec/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ export interface TspArmResource extends TypespecObject {
keyExpression: string | undefined;
propertiesModelName: string;
propertiesPropertyRequired: boolean;
propertiesPropertyVisibility: string[];
propertiesPropertyDescription: string;
propertiesPropertyClientDecorator: TypespecDecorator[];
resourceParent?: TspArmResource;
resourceOperations: TspArmResourceOperation[];
normalOperations: TypespecOperation[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Operation, Parameter, Response, SchemaResponse, SchemaType } from "@autorest/codemodel";
import { Operation, Parameter, Property, Response, SchemaResponse, SchemaType } from "@autorest/codemodel";
import _ from "lodash";
import pluralize, { singular } from "pluralize";
import { getArmCommonTypeVersion, getSession } from "../autorest-session";
Expand Down Expand Up @@ -54,6 +54,7 @@ function addGeneratedResourceObjectIfNotExits(name: string, mapping: string) {
}

export function transformTspArmResource(schema: ArmResourceSchema): TspArmResource {
const { isFullCompatible } = getOptions();
const fixMe: string[] = [];

if (!getSession().configuration["namespace"]) {
Expand All @@ -80,14 +81,12 @@ export function transformTspArmResource(schema: ArmResourceSchema): TspArmResour
const propertiesModelSchema = propertiesModel?.schema;
let propertiesModelName = propertiesModelSchema?.language.default.name;
let propertiesPropertyRequired = false;
let propertiesPropertyVisibility = ["read", "create"];
let propertiesPropertyDescription = "";

if (propertiesModelSchema?.type === SchemaType.Dictionary) {
propertiesModelName = "Record<unknown>";
} else if (propertiesModelSchema?.type === SchemaType.Object) {
propertiesPropertyRequired = propertiesModel?.required ?? false;
propertiesPropertyVisibility = propertiesModel?.extensions?.["x-ms-mutability"] ?? [];
propertiesPropertyDescription = propertiesModel?.language.default.description ?? "";
}

Expand Down Expand Up @@ -120,13 +119,29 @@ export function transformTspArmResource(schema: ArmResourceSchema): TspArmResour
const keyProperty = buildKeyProperty(schema);
const properties = [...getOtherProperties(schema, !getArmCommonTypeVersion())];
let keyExpression, augmentDecorators;
if (keyProperty.name === "name" && keyProperty.type === "string") {
if (keyProperty.name === "name") {
keyExpression = buildKeyExpression(schema, keyProperty);
augmentDecorators = buildKeyAugmentDecorators(schema, keyProperty);
} else {
properties.unshift(keyProperty);
}

if (propertiesModel) {
if (augmentDecorators === undefined) augmentDecorators = buildPropertiesAugmentDecorators(schema, propertiesModel);
else augmentDecorators.push(...buildPropertiesAugmentDecorators(schema, propertiesModel));
}

const propertiesPropertyClientDecorator = [];
if (isFullCompatible && propertiesModel?.extensions?.["x-ms-client-flatten"]) {
propertiesPropertyClientDecorator.push({
name: "flattenProperty",
module: "@azure-tools/typespec-client-generator-core",
namespace: "Azure.ClientGenerator.Core",
suppressionCode: "deprecated",
suppressionMessage: "@flattenProperty decorator is not recommended to use.",
});
}

return {
fixMe,
resourceKind: getResourceKind(schema),
Expand All @@ -138,8 +153,8 @@ export function transformTspArmResource(schema: ArmResourceSchema): TspArmResour
resourceParent: getParentResource(schema),
propertiesModelName,
propertiesPropertyRequired,
propertiesPropertyVisibility,
propertiesPropertyDescription,
propertiesPropertyClientDecorator,
doc: schema.language.default.description,
decorators,
clientDecorators,
Expand Down Expand Up @@ -844,6 +859,7 @@ function buildKeyExpression(schema: ArmResourceSchema, keyProperty: TypespecObje
${keyName ? `, KeyName = "${keyName}"` : ""}
${segmentName ? `, SegmentName = "${segmentName}"` : ""},
NamePattern = ${namePattern ? `"${namePattern}"` : `""`}
${keyProperty.type !== "string" ? `, Type = ${keyProperty.type}` : ""}
>`;
}

Expand All @@ -865,6 +881,16 @@ function buildKeyAugmentDecorators(
});
}

function buildPropertiesAugmentDecorators(schema: ArmResourceSchema, propertiesModel: Property): TypespecDecorator[] {
return [
{
name: "doc",
target: `${schema.resourceMetadata.SwaggerModelName}.properties`,
arguments: [generateDocsContent({ doc: propertiesModel?.language.default.description })],
},
];
}

function buildKeyProperty(schema: ArmResourceSchema): TypespecObjectProperty {
let parameter;
if (!schema.resourceMetadata.IsSingletonResource) {
Expand Down
14 changes: 13 additions & 1 deletion packages/extensions/openapi-to-typespec/src/utils/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
isNumberSchema,
} from "@autorest/codemodel";
import { TypespecDecorator, DecoratorArgument } from "../interfaces";
import { getOptions } from "../options";
import { createCSharpNameDecorator } from "../pretransforms/rename-pretransform";
import { getOwnDiscriminator } from "./discriminator";
import { isSealedChoiceSchema, isStringSchema } from "./schemas";
Expand Down Expand Up @@ -68,6 +69,7 @@ export function getModelClientDecorators(model: ObjectSchema): TypespecDecorator
}

export function getPropertyDecorators(element: Property | Parameter): TypespecDecorator[] {
const { isFullCompatible } = getOptions();
const decorators: TypespecDecorator[] = [];

const paging = element.language.default.paging ?? {};
Expand Down Expand Up @@ -158,13 +160,23 @@ export function getPropertyDecorators(element: Property | Parameter): TypespecDe
});
}

if (element.extensions?.["x-ms-client-flatten"] && isFullCompatible) {
decorators.push({
name: "extension",
module: "@typespec/openapi",
namespace: "TypeSpec.OpenAPI",
arguments: [{ value: `"x-ms-client-flatten"` }, { value: "true" }],
});
}

return decorators;
}

export function getPropertyClientDecorators(element: Property | Parameter): TypespecDecorator[] {
const { isFullCompatible } = getOptions();
const decorators: TypespecDecorator[] = [];

if (element.extensions?.["x-ms-client-flatten"]) {
if (element.extensions?.["x-ms-client-flatten"] && isFullCompatible) {
decorators.push({
name: "flattenProperty",
module: "@azure-tools/typespec-client-generator-core",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function getClientImports(program: TypespecProgram) {
for (const op of resource.normalOperations) {
addImports(op.clientDecorators);
}
addImports(resource.propertiesPropertyClientDecorator);
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,15 @@ namespace Azure.ResourceManager.AgFoodPlatform;
/**
* DataConnector Model.
*/
#suppress "@azure-tools/typespec-azure-core/composition-over-inheritance" "For backward compatibility"
#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property" "For backward compatibility"
@parentResource(DataManagerForAgriculture)
@includeInapplicableMetadataInPayload(false)
@Azure.ResourceManager.Private.armResourceInternal(DataConnectorProperties)
model DataConnector extends Foundations.ProxyResource {
model DataConnector
is Azure.ResourceManager.ProxyResource<DataConnectorProperties, false> {
...ResourceNameParameter<
Resource = DataConnector,
KeyName = "dataConnectorName",
SegmentName = "dataConnectors",
NamePattern = ""
>;

/**
* DataConnector Properties.
*/
@extension("x-ms-client-flatten", true)
properties: DataConnectorProperties;

...Azure.ResourceManager.EntityTagProperty;
}

Expand Down Expand Up @@ -85,6 +75,7 @@ interface DataConnectors {
@@maxLength(DataConnector.name, 63);
@@minLength(DataConnector.name, 1);
@@doc(DataConnector.name, "Connector name.");
@@doc(DataConnector.properties, "DataConnector Properties.");
@@encodedName(DataConnectors.createOrUpdate::parameters.resource,
"application/json",
"body"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,14 @@ namespace Azure.ResourceManager.AgFoodPlatform;
/**
* Data Manager For Agriculture ARM Resource.
*/
#suppress "@azure-tools/typespec-azure-core/composition-over-inheritance" "For backward compatibility"
#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property" "For backward compatibility"
@includeInapplicableMetadataInPayload(false)
@Azure.ResourceManager.Private.armResourceInternal(
DataManagerForAgricultureProperties
)
model DataManagerForAgriculture extends Foundations.TrackedResource {
model DataManagerForAgriculture
is Azure.ResourceManager.TrackedResource<DataManagerForAgricultureProperties> {
...ResourceNameParameter<
Resource = DataManagerForAgriculture,
KeyName = "dataManagerForAgricultureResourceName",
SegmentName = "farmBeats",
NamePattern = "^[A-Za-z0-9]+(-[A-Za-z0-9]+)*$"
>;

/**
* Data Manager For Agriculture ARM Resource properties.
*/
@extension("x-ms-client-flatten", true)
properties?: DataManagerForAgricultureProperties;

...Azure.ResourceManager.ManagedServiceIdentityProperty;
}

Expand Down Expand Up @@ -111,6 +99,9 @@ interface DataManagerForAgricultures {
@@doc(DataManagerForAgriculture.name,
"DataManagerForAgriculture resource name."
);
@@doc(DataManagerForAgriculture.properties,
"Data Manager For Agriculture ARM Resource properties."
);
@@encodedName(DataManagerForAgricultures.createOrUpdate::parameters.resource,
"application/json",
"request"
Expand Down
Loading

0 comments on commit 812da78

Please sign in to comment.