Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions packages/typespec-ts/src/modular/buildClassicalClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ import {
} from "../utils/operationUtil.js";
import { useContext } from "../contextManager.js";
import { refkey } from "../framework/refkey.js";
import { SimplePollerHelpers } from "./static-helpers-metadata.js";
import {
PagingHelpers,
SimplePollerHelpers
} from "./static-helpers-metadata.js";
import { AzurePollingDependencies } from "./external-dependencies.js";
import { getPagingLROMethodName } from "./helpers/classicalOperationHelpers.js";

export function buildClassicalClient(
dpgContext: SdkContext,
Expand Down Expand Up @@ -253,7 +257,11 @@ function generateMethod(
});

// add LRO helper methods if applicable
if (context.rlcOptions?.compatibilityLro && declaration?.isLro) {
if (
context.rlcOptions?.compatibilityLro &&
declaration?.isLro &&
!declaration?.isLroPaging
) {
const operationStateReference = resolveReference(
AzurePollingDependencies.OperationState
);
Expand Down Expand Up @@ -291,6 +299,26 @@ function generateMethod(
parameters: methodParams,
statements: `return await ${declarationRefKey}(${methodParamStr});`
});
} // For LRO+Paging operations, use different return types and implementation
else if (context.rlcOptions?.compatibilityLro && declaration?.isLroPaging) {
const returnType = declaration?.lropagingFinalReturnType ?? "void";
const pagedAsyncIterableIteratorReference = resolveReference(
PagingHelpers.PagedAsyncIterableIterator
);
const beginListAndWaitName = normalizeName(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap this with private method getPagingLROMethodName

and add UT for this.

`${getPagingLROMethodName(methodName)}`,
NameType.Method
);
// add begin and wait method for LRO+Paging - directly returns paged iterator
res.push({
isAsync: false,
docs: [`@deprecated use ${methodName} instead`],
name: beginListAndWaitName,
kind: StructureKind.Method,
returnType: `${pagedAsyncIterableIteratorReference}<${returnType}>`,
parameters: methodParams,
statements: `return ${declarationRefKey}(${methodParamStr});`
});
}

return res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import { ServiceOperation } from "../../utils/operationUtil.js";
import { refkey } from "../../framework/refkey.js";
import { resolveReference } from "../../framework/reference.js";
import { addDeclaration } from "../../framework/declaration.js";
import { SimplePollerHelpers } from "../static-helpers-metadata.js";
import {
SimplePollerHelpers,
PagingHelpers
} from "../static-helpers-metadata.js";
import { AzurePollingDependencies } from "../external-dependencies.js";

interface OperationDeclarationInfo {
Expand All @@ -33,8 +36,22 @@ interface OperationDeclarationInfo {
isLro?: boolean;
// only set when isLro is true
lroFinalReturnType?: string;
// set to true for LRO+Paging operations
isLroPaging?: boolean;
// only set when isLroPaging is true
lropagingFinalReturnType?: string;
}
export function getPagingLROMethodName(operationName: string) {
let initialOperationName = normalizeName(operationName, NameType.Operation);
if (initialOperationName.indexOf("list") === 0) {
initialOperationName = initialOperationName.replace("list", "");
} else if (initialOperationName.indexOf("get") === 0) {
initialOperationName = initialOperationName.replace("get", "");
} else {
initialOperationName = normalizeName(initialOperationName, NameType.Class);
}
return `beginList_${initialOperationName}_andWait`;
}

export function getClassicalOperation(
dpgContext: SdkContext,
clientMap: [string[], SdkClientType<SdkServiceOperation>],
Expand Down Expand Up @@ -82,7 +99,9 @@ export function getClassicalOperation(
oriName: operation.oriName,
declarationRefKey: resolveReference(refkey(operation, "api")),
isLro: declaration.isLro,
lroFinalReturnType: declaration.lroFinalReturnType
lroFinalReturnType: declaration.lroFinalReturnType,
isLroPaging: declaration.isLroPaging,
lropagingFinalReturnType: declaration.lropagingFinalReturnType
});
return declaration;
});
Expand Down Expand Up @@ -146,29 +165,50 @@ export function getClassicalOperation(
docs: d.docs
});
// add LRO helper methods if applicable
if (dpgContext.rlcOptions?.compatibilityLro && operationInfo?.isLro) {
if (
dpgContext.rlcOptions?.compatibilityLro &&
(operationInfo?.isLro || operationInfo?.isLroPaging)
) {
const operationStateReference = resolveReference(
AzurePollingDependencies.OperationState
);
const simplePollerLikeReference = resolveReference(
SimplePollerHelpers.SimplePollerLike
);
const returnType = operationInfo?.lroFinalReturnType ?? "void";
const beginName = `begin_${getClassicalMethodName(d)}`;
const beginAndWaitName = `${beginName}_andWait`;

properties.push({
kind: StructureKind.PropertySignature,
name: `${normalizeName(beginName, NameType.Method)}`,
type: `(${paramStr}) => Promise<${simplePollerLikeReference}<${operationStateReference}<${returnType}>, ${returnType}>>`,
docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
});
properties.push({
kind: StructureKind.PropertySignature,
name: `${normalizeName(beginAndWaitName, NameType.Method)}`,
type: `(${paramStr}) => Promise<${returnType}>`,
docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
});
if (operationInfo?.isLroPaging) {
// LRO+Paging operation
const returnType = operationInfo?.lropagingFinalReturnType ?? "void";
const pagedAsyncIterableIteratorReference = resolveReference(
PagingHelpers.PagedAsyncIterableIterator
);
const beginListAndWaitName = getPagingLROMethodName(
getClassicalMethodName(d)
);
properties.push({
kind: StructureKind.PropertySignature,
name: `${normalizeName(beginListAndWaitName, NameType.Method)}`,
type: `(${paramStr}) => ${pagedAsyncIterableIteratorReference}<${returnType}>`,
docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
});
} else {
// Regular LRO operation
const returnType = operationInfo?.lroFinalReturnType ?? "void";
properties.push({
kind: StructureKind.PropertySignature,
name: `${normalizeName(beginName, NameType.Method)}`,
type: `(${paramStr}) => Promise<${simplePollerLikeReference}<${operationStateReference}<${returnType}>, ${returnType}>>`,
docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
});
properties.push({
kind: StructureKind.PropertySignature,
name: `${normalizeName(beginAndWaitName, NameType.Method)}`,
type: `(${paramStr}) => Promise<${returnType}>`,
docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
});
}
}
});
}
Expand Down Expand Up @@ -237,35 +277,51 @@ export function getClassicalOperation(
// add LRO helper methods if applicable
if (
dpgContext.rlcOptions?.compatibilityLro &&
operationInfo?.isLro
(operationInfo?.isLro || operationInfo?.isLroPaging)
) {
const getSimplePollerReference = resolveReference(
SimplePollerHelpers.getSimplePoller
);
const beginName = `begin_${getClassicalMethodName(d)}`;
const beginAndWaitName = `${beginName}_andWait`;
ret.push(
`${normalizeName(
beginName,
NameType.Method
)}: async (${classicalParamStr}) => {
const poller = ${operationInfo?.declarationRefKey}(${
apiParamStr
});
await poller.submitted();
return ${getSimplePollerReference}(poller);
}`
);
ret.push(
`${normalizeName(
beginAndWaitName,
NameType.Method
)}: async (${classicalParamStr}) => {
return await ${operationInfo?.declarationRefKey}(${
apiParamStr
});
}`
const beginListAndWaitName = getPagingLROMethodName(
getClassicalMethodName(d)
);

if (operationInfo?.isLroPaging) {
ret.push(
`${normalizeName(
beginListAndWaitName,
NameType.Method
)}: (${classicalParamStr}) => {
return ${operationInfo?.declarationRefKey}(${apiParamStr});
}`
);
} else {
// Regular LRO operation
ret.push(
`${normalizeName(
beginName,
NameType.Method
)}: async (${classicalParamStr}) => {
const poller = ${operationInfo?.declarationRefKey}(${
apiParamStr
});
await poller.submitted();
return ${getSimplePollerReference}(poller);
}`
);
ret.push(
`${normalizeName(
beginAndWaitName,
NameType.Method
)}: async (${classicalParamStr}) => {
return await ${operationInfo?.declarationRefKey}(${
apiParamStr
});
}`
);
}
}
return ret.join(",");
})
Expand Down
10 changes: 9 additions & 1 deletion packages/typespec-ts/src/modular/helpers/operationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,8 @@ export function getOperationFunction(
propertyName?: string;
isLro?: boolean;
lroFinalReturnType?: string;
isLroPaging?: boolean;
lropagingFinalReturnType?: string;
} {
const operation = method[1];
// Extract required parameters
Expand Down Expand Up @@ -1026,7 +1028,11 @@ function getLroAndPagingOperationFunction(
method: [string[], SdkLroPagingServiceMethod<SdkHttpOperation>],
clientType: string,
optionalParamName: string = "options"
): FunctionDeclarationStructure & { propertyName?: string } {
): FunctionDeclarationStructure & {
isLroPaging?: boolean;
propertyName?: string;
lropagingFinalReturnType?: string;
} {
const operation = method[1];
const parameters = getOperationSignatureParameters(
context,
Expand Down Expand Up @@ -1087,6 +1093,8 @@ function getLroAndPagingOperationFunction(
],
isAsync: false,
isExported: true,
isLroPaging: true,
lropagingFinalReturnType: returnType.type,
name,
propertyName: normalizeName(operation.name, NameType.Property),
parameters,
Expand Down
Loading