Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Pan Shao committed Sep 6, 2024
1 parent 3b6e320 commit da1b864
Show file tree
Hide file tree
Showing 93 changed files with 3,842 additions and 6,102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { generateArmResource, generateArmResourceExamples } from "../generate/ge
import { TypespecProgram, TspArmResource } from "../interfaces";
import { formatTypespecFile } from "../utils/format";
import { getNamespaceStatement } from "../utils/namespace";
import { Metadata } from "../utils/resource-discovery";

export async function emitArmResources(program: TypespecProgram, basePath: string) {
export async function emitArmResources(program: TypespecProgram, metadata: Metadata, basePath: string) {
// Create a file per resource
const session = getSession();
const { serviceInformation } = program;
Expand Down Expand Up @@ -35,6 +36,13 @@ export async function emitArmResources(program: TypespecProgram, basePath: strin
}
}
}

const multiPathResources = Object.keys(metadata.Resources).filter(key => key.endsWith("FixMe"));
for (const resource of multiPathResources) {
const originalName = resource.replace("FixMe", "");
const filePath = join(basePath, `${resource}.tsp`);
session.writeFile({ filename: filePath, content: `// You defined multiple pathes under the model ${originalName}. We currently don't support it. Please fix it manually.` });
}
}

export function getResourcesImports(_program: TypespecProgram, armResource: TspArmResource) {
Expand Down
20 changes: 11 additions & 9 deletions packages/extensions/openapi-to-typespec/src/emiters/emit-main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Metadata } from "../utils/resource-discovery";
import { getSession } from "../autorest-session";
import { generateServiceInformation } from "../generate/generate-service-information";
import { TypespecProgram } from "../interfaces";
import { getOptions } from "../options";
import { formatTypespecFile } from "../utils/format";
import { getArmResourcesMetadata } from "../utils/resource-discovery";
const packageInfo = require("../../package.json");

export async function emitMain(filePath: string, program: TypespecProgram): Promise<void> {
export async function emitMain(filePath: string, program: TypespecProgram, metadata: Metadata | undefined): Promise<void> {
const { isArm } = getOptions();
const content = `${getHeaders()}\n${isArm ? getArmServiceInformation(program) : getServiceInformation(program)}`;
const content = `${getHeaders()}\n${isArm ? getArmServiceInformation(program, metadata!) : getServiceInformation(program)}`;
const session = getSession();
session.writeFile({ filename: filePath, content: await formatTypespecFile(content, filePath) });
}
Expand Down Expand Up @@ -40,14 +40,14 @@ function getServiceInformation(program: TypespecProgram) {
return [...imports, content].join("\n");
}

function getArmServiceInformation(program: TypespecProgram) {
function getArmServiceInformation(program: TypespecProgram, metadata: Metadata) {
const imports = [
`import "@typespec/rest";`,
`import "@typespec/versioning";`,
`import "@azure-tools/typespec-azure-core";`,
`import "@azure-tools/typespec-azure-resource-manager";`,
`import "./models.tsp";`,
...getArmResourceImports(program),
...getArmResourceImports(program, metadata),
``,
`using TypeSpec.Rest;`,
`using TypeSpec.Http;`,
Expand All @@ -61,12 +61,14 @@ function getArmServiceInformation(program: TypespecProgram) {
return [...imports, content].join("\n");
}

function getArmResourceImports(program: TypespecProgram): string[] {
const resourceMetadata = getArmResourcesMetadata();
function getArmResourceImports(program: TypespecProgram, metadata: Metadata): string[] {
const imports: string[] = [];

for (const resource in resourceMetadata.Resources) {
imports.push(`import "./${resourceMetadata.Resources[resource].SwaggerModelName}.tsp";`);
for (const resource in metadata.Resources) {
const fileName = metadata.Resources[resource].Name;
if (fileName) {
imports.push(`import "./${fileName}.tsp";`);
}
}

if (program.operationGroups.length > 0) {
Expand Down
9 changes: 6 additions & 3 deletions packages/extensions/openapi-to-typespec/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ export async function processConverter(host: AutorestExtensionHost) {
const codeModel = session.model;
pretransformNames(codeModel);
const { isArm } = getOptions();
let metadata = undefined;
if (isArm) {
// await host.writeFile({ filename: "codeModel.yaml", content: serialize(codeModel, codeModelSchema)} );
const metadata = parseMetadata(codeModel);
metadata = parseMetadata(codeModel);
await host.writeFile({ filename: "resources.json", content: JSON.stringify(metadata, null, 2) });
pretransformArmResources(codeModel, metadata);
pretransformRename(codeModel, metadata);
Expand All @@ -42,10 +43,12 @@ export async function processConverter(host: AutorestExtensionHost) {
markErrorModels(codeModel);
markResources(codeModel);
const programDetails = getModel(codeModel);
await emitArmResources(programDetails, getOutuptDirectory(session));
if (isArm) {
await emitArmResources(programDetails, metadata!, getOutuptDirectory(session));
}
await emitModels(getFilePath(session, "models.tsp"), programDetails);
await emitRoutes(getFilePath(session, "routes.tsp"), programDetails);
await emitMain(getFilePath(session, "main.tsp"), programDetails);
await emitMain(getFilePath(session, "main.tsp"), programDetails, metadata);
await emitPackage(getFilePath(session, "package.json"), programDetails);
await emitTypespecConfig(getFilePath(session, "tspconfig.yaml"), programDetails);
await emitClient(getFilePath(session, "client.tsp"), programDetails);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { TypespecDecorator } from "../interfaces";
import { getOptions } from "../options";
import { getLogger } from "../utils/logger";
import { Metadata, getArmResourcesMetadata } from "../utils/resource-discovery";
import { Metadata } from "../utils/resource-discovery";

type RenamableSchema = Schema | Property | Parameter | ChoiceValue | Operation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ export function populateSingletonRequestPath(set: OperationSet): void {
updatedSegments.push(segment);
} else {
const keyName = segment.replace(/^\{(\w+)\}$/, "$1");
const resourceKeyParameter = set.Operations[0].parameters?.find((p) => p.language.default.name === keyName);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${keyName}`;
const resourceKeyParameter = set.Operations[0].parameters?.find((p) => p.language.default.name === keyName || p.language.default.serializedName === keyName);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${keyName} in operation ${set.Operations[0].operationId}`;

if (!isConstantSchema(resourceKeyParameter.schema)) {
updatedSegments.push(segment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,33 @@ export function parseMetadata(codeModel: CodeModel): Metadata {
for (const resourceSchemaName in operationSetsByResourceDataSchemaName) {
const operationSets = operationSetsByResourceDataSchemaName[resourceSchemaName];
if (operationSets.length > 1) {
console.warn(
`We cannot support multi path with same model. Some operations will be lost. \nResource schema name: ${resourceSchemaName}.\nPath:\n${operationSets
logger().info(`We cannot support multi path with same model. Some operations will be lost. \nResource schema name: ${resourceSchemaName}.\nPath:\n${operationSets
.map((o) => o.RequestPath)
.join("\n")}`,
);
.join("\n")}`);
resources[resourceSchemaName + "FixMe"] = {
Name: resourceSchemaName + "FixMe",
GetOperations: [],
CreateOperations: [],
UpdateOperations: [],
DeleteOperations: [],
ListOperations: [],
OperationsFromResourceGroupExtension: [],
OperationsFromSubscriptionExtension: [],
OperationsFromManagementGroupExtension: [],
OperationsFromTenantExtension: [],
OtherOperations: [],
Parents: [],
SwaggerModelName: "",
ResourceType: "",
ResourceKey: "",
ResourceKeySegment: "",
IsTrackedResource: false,
IsTenantResource: false,
IsSubscriptionResource: false,
IsManagementGroupResource: false,
IsExtensionResource: false,
IsSingletonResource: false,
}
}
resources[resourceSchemaName] = buildResource(
resourceSchemaName,
Expand Down Expand Up @@ -180,8 +202,7 @@ function buildResourceOperationFromOperation(operation: Operation, operationName
pagingMetadata = {
Method: operation.language.default.name,
ItemName: itemName,
NextLinkName: nextLinkName,
NextPageMethod: undefined, // We are not using it
NextLinkName: nextLinkName
};
}

Expand Down
4 changes: 2 additions & 2 deletions packages/extensions/openapi-to-typespec/src/resource/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export function isSingleton(set: OperationSet): boolean {
if (lastSegment.match(/^\{\w+\}$/) === null) return true;

const resourceKey = lastSegment.replace(/^\{(\w+)\}$/, "$1");
const resourceKeyParameter = set.Operations[0].parameters?.find((p) => p.language.default.name === resourceKey);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${resourceKey}`;
const resourceKeyParameter = set.Operations[0].parameters?.find((p) => p.language.default.name === resourceKey|| p.language.default.serializedName === resourceKey);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${resourceKey} in operation ${set.Operations[0].operationId}`;
return isConstantSchema(resourceKeyParameter?.schema);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export interface _ArmResourceOperation {

export interface _ArmPagingMetadata {
Method: string;
NextPageMethod?: string;
ItemName: string;
NextLinkName: string;
}
Expand Down Expand Up @@ -124,24 +123,6 @@ export function getResourceExistOperation(resource: ArmResource): Operation | un
}
}

export function getArmResourcesMetadata(): Metadata {
if (metadataCache) {
return metadataCache;
}
const session = getSession();
const outputFolder: string = session.configuration["output-folder"] ?? "";

try {
const content = readFileSync(join(outputFolder, "resources.json"), "utf-8");
const metadata: Metadata = JSON.parse(content);
metadataCache = metadata;

return metadataCache;
} catch (e) {
throw new Error(`Failed to load resources.json from ${outputFolder} \n ${e}`);
}
}

export interface ArmResourceSchema extends ObjectSchema {
resourceMetadata: ArmResource;
}
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit da1b864

Please sign in to comment.