in packages/extensions/openapi-to-typespec/src/resource/parse-metadata.ts [27:144]
export function parseMetadata(codeModel: CodeModel, configuration: Record<string, any>): Metadata {
const { isFullCompatible } = getOptions();
const operationSets: { [path: string]: OperationSet } = {};
const operations = codeModel.operationGroups.flatMap((og) => og.operations);
for (const operation of operations) {
const path = getNormalizeHttpPath(operation);
if (path in operationSets) {
operationSets[path].Operations.push(operation);
} else {
operationSets[path] = { RequestPath: path, Operations: [operation], SingletonRequestPath: undefined };
}
}
const operationSetsByResourceDataSchemaName: { [name: string]: OperationSet[] } = {};
for (const key in operationSets) {
const operationSet = operationSets[key];
let resourceSchemaName = getResourceDataSchema(operationSet);
if (resourceSchemaName === undefined) {
const resourceDataConfiguration = configuration["request-path-to-resource-data"] as Record<string, string>;
const configuredName = resourceDataConfiguration
? resourceDataConfiguration[operationSet.RequestPath]
: undefined;
if (configuredName && codeModel.schemas.objects?.find((o) => o.language.default.name === configuredName)) {
resourceSchemaName = configuredName;
setResourceDataSchema(operationSet, resourceSchemaName);
}
}
if (resourceSchemaName !== undefined) {
populateSingletonRequestPath(operationSet);
if (resourceSchemaName in operationSetsByResourceDataSchemaName) {
operationSetsByResourceDataSchemaName[resourceSchemaName].push(operationSet);
} else {
operationSetsByResourceDataSchemaName[resourceSchemaName] = [operationSet];
}
}
}
for (const key in operationSets) {
const operationSet = operationSets[key];
if (getResourceDataSchema(operationSet)) continue;
for (const operation of operationSet.Operations) {
// Check if this operation is a collection operation
if (
setParentOfResourceCollectionOperation(
operation,
key,
Object.values(operationSetsByResourceDataSchemaName).flat(),
)
)
continue;
// Otherwise we find a request path that is the longest parent of this, and belongs to a resource
if (setParentOfOtherOperation(operation, key, Object.values(operationSetsByResourceDataSchemaName).flat()))
continue;
setParentOfExtensionOperation(operation, key, Object.values(operationSetsByResourceDataSchemaName).flat());
}
}
const resources: { [name: string]: ArmResource[] } = {};
for (const resourceSchemaName in operationSetsByResourceDataSchemaName) {
const operationSets = operationSetsByResourceDataSchemaName[resourceSchemaName];
for (let index = 0; index < operationSets.length; index++) {
if (index >= 1 && !isFullCompatible) {
logger().info(
`Multi-path operations applied on the same resource. Some operations will be lost. \nResource schema name: ${resourceSchemaName}.\nPath:\n${operationSets
.map((o) => o.RequestPath)
.join("\n")}\nTurn on isFullCompatible to keep all operations, or adjust your TypeSpec.`,
);
resources[resourceSchemaName + "FixMe"] = [
{
Name: resourceSchemaName + "FixMe",
GetOperation: undefined,
ExistOperation: undefined,
CreateOperation: undefined,
UpdateOperation: undefined,
DeleteOperation: undefined,
ListOperations: [],
OperationsFromResourceGroupExtension: [],
OperationsFromSubscriptionExtension: [],
OperationsFromManagementGroupExtension: [],
OperationsFromTenantExtension: [],
OtherOperations: [],
Parents: [],
SwaggerModelName: "",
ResourceType: "",
ResourceKey: "",
ResourceKeySegment: "",
IsTrackedResource: false,
IsTenantResource: false,
IsSubscriptionResource: false,
IsManagementGroupResource: false,
IsExtensionResource: false,
IsSingletonResource: false,
},
];
break;
}
(resources[resourceSchemaName] ??= []).push(
buildResource(
resourceSchemaName,
operationSets[index],
Object.values(operationSetsByResourceDataSchemaName).flat(),
codeModel,
),
);
}
}
return {
Resources: resources,
RenameMapping: {},
OverrideOperationName: {},
};
}