(lines: string[], name: string, method: RpcMethod, isSession: boolean, resolveType: (name: string) => string, groupExperimental = false, groupDeprecated = false)
| 3476 | } |
| 3477 | |
| 3478 | function emitMethod(lines: string[], name: string, method: RpcMethod, isSession: boolean, resolveType: (name: string) => string, groupExperimental = false, groupDeprecated = false): void { |
| 3479 | const isInternal = method.visibility === "internal"; |
| 3480 | const methodName = (isInternal ? "_" : "") + toSnakeCase(name); |
| 3481 | const resultSchema = getMethodResultSchema(method); |
| 3482 | const nullableInner = resultSchema ? getNullableInner(resultSchema) : undefined; |
| 3483 | const effectiveResultSchema = nullableInner ?? resultSchema; |
| 3484 | const hasResult = !isVoidSchema(resultSchema) && !nullableInner; |
| 3485 | const hasNullableResult = !!nullableInner; |
| 3486 | const resultIsOpaque = isOpaqueJson(effectiveResultSchema); |
| 3487 | const resultIsObject = !resultIsOpaque && isPythonObjectResultSchema(effectiveResultSchema); |
| 3488 | |
| 3489 | let resultType: string; |
| 3490 | if (hasNullableResult) { |
| 3491 | const innerTypeName = resolveType(pythonResultTypeName(method, nullableInner)); |
| 3492 | resultType = `${innerTypeName} | None`; |
| 3493 | } else if (hasResult) { |
| 3494 | resultType = resolveType(pythonResultTypeName(method)); |
| 3495 | } else { |
| 3496 | resultType = "None"; |
| 3497 | } |
| 3498 | |
| 3499 | const effectiveParams = getMethodParamsSchema(method); |
| 3500 | const paramProps = effectiveParams?.properties || {}; |
| 3501 | const nonSessionParams = Object.keys(paramProps).filter((k) => k !== "sessionId"); |
| 3502 | const hasParams = isSession ? nonSessionParams.length > 0 : hasSchemaPayload(effectiveParams); |
| 3503 | const paramsType = resolveType(pythonParamsTypeName(method)); |
| 3504 | const paramsOptional = isParamsOptional(method); |
| 3505 | |
| 3506 | // Build signature with typed params + optional timeout |
| 3507 | const sig = hasParams |
| 3508 | ? paramsOptional |
| 3509 | ? ` async def ${methodName}(self, params: ${paramsType} | None = None, *, timeout: float | None = None) -> ${resultType}:` |
| 3510 | : ` async def ${methodName}(self, params: ${paramsType}, *, timeout: float | None = None) -> ${resultType}:` |
| 3511 | : ` async def ${methodName}(self, *, timeout: float | None = None) -> ${resultType}:`; |
| 3512 | |
| 3513 | lines.push(sig); |
| 3514 | |
| 3515 | pushPyRpcMethodDocstring(lines, " ", method, { |
| 3516 | paramsName: hasParams ? "params" : undefined, |
| 3517 | paramsDescription: rpcParamsDescription(method, effectiveParams), |
| 3518 | resultDescription: rpcResultDescription(method, resultSchema), |
| 3519 | deprecated: method.deprecated && !groupDeprecated, |
| 3520 | experimental: method.stability === "experimental" && !groupExperimental, |
| 3521 | internal: method.visibility === "internal", |
| 3522 | }); |
| 3523 | |
| 3524 | // Deserialize helper |
| 3525 | const innerTypeName = hasNullableResult ? resolveType(pythonResultTypeName(method, nullableInner)) : resultType; |
| 3526 | const isAnyType = innerTypeName === "Any"; |
| 3527 | const deserialize = (expr: string) => { |
| 3528 | if (resultIsOpaque || isAnyType) { |
| 3529 | return expr; |
| 3530 | } |
| 3531 | if (hasNullableResult) { |
| 3532 | return resultIsObject |
| 3533 | ? `${innerTypeName}.from_dict(${expr}) if ${expr} is not None else None` |
| 3534 | : `${innerTypeName}(${expr}) if ${expr} is not None else None`; |
| 3535 | } |
no test coverage detected
searching dependent graphs…