export function transformRequest()

in packages/extensions/openapi-to-typespec/src/transforms/transform-operations.ts [109:227]


export function transformRequest(
  _request: Request,
  operation: Operation,
  codeModel: CodeModel,
  groupName: string | undefined = undefined,
): TypespecOperation | TspArmProviderActionOperation {
  const { isFullCompatible, isArm } = getOptions();
  const { language, responses, requests } = operation;
  const name = _.lowerFirst(language.default.name);
  const doc = language.default.description;
  const summary = language.default.summary;
  const { paging } = getLanguageMetadata(operation.language);
  const transformedResponses = transformResponses(responses ?? []);
  const visitedParameter: Set<Parameter> = new Set();
  let parameters = (operation.parameters ?? [])
    .filter((p) => filterOperationParameters(p, visitedParameter))
    .map((v) => transformParameter(v, codeModel));

  parameters = [
    ...parameters,
    ...getRequestParameters(operation)
      .filter((p) => filterOperationParameters(p, visitedParameter))
      .map((v) => transformParameter(v, codeModel)),
  ];

  const extensions: Extension[] = [];

  if (paging) {
    extensions.push("Pageable");
  }

  const resource = operation.language.default.resource;
  let decorators: TypespecDecorator[] | undefined = undefined;
  if (
    groupName &&
    operation.operationId &&
    operation.operationId !== `${Case.pascal(groupName)}_${Case.pascal(name)}`
  ) {
    const decorator = createOperationIdDecorator(operation.operationId!);
    if (isFullCompatible) {
      decorator.suppressionCode = "@azure-tools/typespec-azure-core/no-openapi";
      decorator.suppressionMessage = "non-standard operations";
    }
    decorators = [decorator];
  }

  if (isArm) {
    const route = transformRoute(requests?.[0].protocol);
    if (route.startsWith("/subscriptions/{subscriptionId}/providers/") || route.startsWith("/providers/")) {
      const action = getActionForPrviderTemplate(route);
      if (action !== undefined) {
        const isLongRunning = operation.extensions?.["x-ms-long-running-operation"] ?? false;
        decorators ??= [];
        decorators.push({
          name: "autoRoute",
          module: "@typespec/rest",
          namespace: "TypeSpec.Rest",
        });

        const verb = transformVerb(requests?.[0].protocol);

        // For Async, there should be a 202 response without body and might be a 200 response with body
        // For Sync, there might be a 200 response with body
        const response = transformedResponses.find((r) => r[0] === "200")?.[1] ?? undefined;
        const finalStateVia =
          operation.extensions?.["x-ms-long-running-operation-options"]?.["final-state-via"] ?? "location";
        const lroHeaders =
          isLongRunning && finalStateVia === "azure-async-operation" ? "Azure-AsyncOperation" : undefined;
        const suppressions =
          isFullCompatible && lroHeaders ? [getSuppressionWithCode(SuppressionCode.LroLocationHeader)] : undefined;
        return {
          kind: isLongRunning ? "ArmProviderActionAsync" : "ArmProviderActionSync",
          doc,
          summary,
          name,
          verb: verb === "post" ? undefined : verb,
          action: action === name ? undefined : action,
          scope: route.startsWith("/providers/") ? undefined : "SubscriptionActionScope",
          response,
          parameters: parameters
            .filter((p) => p.location !== "body")
            .map((p) => {
              if (p.location === "path") {
                const segment = getSegmentForPathParameter(route, p.name);
                if (p.decorators === undefined) p.decorators = [];
                p.decorators.push({
                  name: "segment",
                  arguments: [segment],
                });
              }
              return p;
            }),
          request: parameters.find((p) => p.location === "body"),
          decorators,
          lroHeaders,
          suppressions,
          examples: operation.extensions?.["x-ms-examples"],
          operationId: operation.operationId,
        };
      }
    }
  }

  return {
    name,
    doc,
    summary,
    parameters,
    clientDecorators: getOperationClientDecorators(operation),
    verb: transformVerb(requests?.[0].protocol),
    route: transformRoute(requests?.[0].protocol),
    responses: transformedResponses,
    extensions: [],
    resource,
    decorators,
    examples: operation.extensions?.["x-ms-examples"],
    operationId: operation.operationId,
  };
}