@azure-tools/typespec-ts 0.50.0 → 0.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +40 -16
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +6 -0
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +5 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
- package/dist/src/modular/buildRootIndex.js +19 -33
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/buildSubpathIndex.d.ts +7 -0
- package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
- package/dist/src/modular/buildSubpathIndex.js +44 -14
- package/dist/src/modular/buildSubpathIndex.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +2 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +108 -14
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +17 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +17 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +3 -1
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/index.ts +68 -19
- package/src/lib.ts +12 -0
- package/src/modular/buildRootIndex.ts +67 -63
- package/src/modular/buildSubpathIndex.ts +75 -34
- package/src/modular/helpers/operationHelpers.ts +143 -8
- package/src/modular/static-helpers-metadata.ts +18 -0
- package/src/transform/transfromRLCOptions.ts +3 -1
- package/static/static-helpers/storageCompatResponse.ts +90 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
PagingHelpers,
|
|
10
10
|
PollingHelpers,
|
|
11
11
|
SerializationHelpers,
|
|
12
|
+
StorageCompatHelpers,
|
|
12
13
|
UrlTemplateHelpers,
|
|
13
14
|
XmlHelpers
|
|
14
15
|
} from "../static-helpers-metadata.js";
|
|
@@ -99,6 +100,17 @@ import {
|
|
|
99
100
|
import { isExtensibleEnum } from "../type-expressions/get-enum-expression.js";
|
|
100
101
|
import { emitInlineModel } from "../type-expressions/get-model-expression.js";
|
|
101
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Checks whether a header should be skipped during serialization/deserialization.
|
|
105
|
+
* A header is skipped when it has the "headerCollectionPrefix" client option set,
|
|
106
|
+
* which indicates it uses a prefix-based dictionary pattern not handled by standard ser/deser.
|
|
107
|
+
*/
|
|
108
|
+
function shouldSkipHeaderSerialization(
|
|
109
|
+
header: SdkHttpParameter | SdkServiceResponseHeader
|
|
110
|
+
): boolean {
|
|
111
|
+
return getClientOptions(header, "headerCollectionPrefix") !== undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
export function getSendPrivateFunction(
|
|
103
115
|
dpgContext: SdkContext,
|
|
104
116
|
method: [string[], ServiceOperation],
|
|
@@ -398,7 +410,8 @@ export function getDeserializePrivateFunction(
|
|
|
398
410
|
|
|
399
411
|
/**
|
|
400
412
|
* Generates a private function to deserialize response headers.
|
|
401
|
-
* Only generated when response headers are present and include-headers-in-response
|
|
413
|
+
* Only generated when response headers are present and include-headers-in-response
|
|
414
|
+
* or enable-storage-compat is enabled.
|
|
402
415
|
*/
|
|
403
416
|
export function getDeserializeHeadersPrivateFunction(
|
|
404
417
|
context: SdkContext,
|
|
@@ -407,9 +420,14 @@ export function getDeserializeHeadersPrivateFunction(
|
|
|
407
420
|
const responseHeaders = getResponseHeaders(operation.operation.responses);
|
|
408
421
|
const isResponseHeadersEnabled =
|
|
409
422
|
context.rlcOptions?.includeHeadersInResponse === true;
|
|
423
|
+
const isStorageCompatEnabled =
|
|
424
|
+
context.rlcOptions?.enableStorageCompat === true;
|
|
410
425
|
|
|
411
|
-
// Only generate if headers exist and feature is enabled
|
|
412
|
-
if (
|
|
426
|
+
// Only generate if headers exist and a relevant feature is enabled
|
|
427
|
+
if (
|
|
428
|
+
responseHeaders.length === 0 ||
|
|
429
|
+
(!isResponseHeadersEnabled && !isStorageCompatEnabled)
|
|
430
|
+
) {
|
|
413
431
|
return undefined;
|
|
414
432
|
}
|
|
415
433
|
|
|
@@ -555,6 +573,7 @@ function getExceptionResponseHeaders(
|
|
|
555
573
|
const headerMap = new Map<string, SdkServiceResponseHeader>();
|
|
556
574
|
for (const exception of exceptions ?? []) {
|
|
557
575
|
for (const header of exception.headers ?? []) {
|
|
576
|
+
if (shouldSkipHeaderSerialization(header)) continue;
|
|
558
577
|
const key = header.serializedName ?? header.name;
|
|
559
578
|
if (!headerMap.has(key)) {
|
|
560
579
|
headerMap.set(key, header);
|
|
@@ -918,6 +937,15 @@ export function getOperationFunction(
|
|
|
918
937
|
const hasHeaderOnlyResponse = !response.type && responseHeaders.length > 0;
|
|
919
938
|
const isResponseHeadersEnabled =
|
|
920
939
|
context.rlcOptions?.includeHeadersInResponse === true;
|
|
940
|
+
const isStorageCompatEnabled =
|
|
941
|
+
context.rlcOptions?.enableStorageCompat === true;
|
|
942
|
+
|
|
943
|
+
// Track the raw body type separately for storage-compat (before header merging)
|
|
944
|
+
const hasResponseBody = !!response.type;
|
|
945
|
+
let bodyType = "void";
|
|
946
|
+
if (response.type) {
|
|
947
|
+
bodyType = getTypeExpression(context, response.type!);
|
|
948
|
+
}
|
|
921
949
|
|
|
922
950
|
let returnType = { name: "", type: "void" };
|
|
923
951
|
if (response.type) {
|
|
@@ -947,6 +975,37 @@ export function getOperationFunction(
|
|
|
947
975
|
type: `${buildHeaderOnlyResponseType(context, responseHeaders)}`
|
|
948
976
|
};
|
|
949
977
|
}
|
|
978
|
+
|
|
979
|
+
// When storage-compat is enabled, wrap the return type with StorageCompatResponseInfo
|
|
980
|
+
// Use the raw body type (not the header-augmented return type) for TBody
|
|
981
|
+
let finalReturnType = returnType.type;
|
|
982
|
+
if (isStorageCompatEnabled) {
|
|
983
|
+
const storageCompatInfoRef = resolveReference(
|
|
984
|
+
StorageCompatHelpers.StorageCompatResponseInfo
|
|
985
|
+
);
|
|
986
|
+
const headersType =
|
|
987
|
+
responseHeaders.length > 0
|
|
988
|
+
? buildHeaderOnlyResponseType(context, responseHeaders)
|
|
989
|
+
: "Record<string, unknown>";
|
|
990
|
+
if (!hasResponseBody) {
|
|
991
|
+
if (responseHeaders.length > 0) {
|
|
992
|
+
// Void with headers — headers at top level + StorageCompatResponseInfo
|
|
993
|
+
finalReturnType = `${headersType} & ${storageCompatInfoRef}<undefined, ${headersType}>`;
|
|
994
|
+
} else {
|
|
995
|
+
// Void without headers — just StorageCompatResponseInfo
|
|
996
|
+
finalReturnType = `${storageCompatInfoRef}<undefined, ${headersType}>`;
|
|
997
|
+
}
|
|
998
|
+
} else {
|
|
999
|
+
if (responseHeaders.length > 0) {
|
|
1000
|
+
// Body with headers — headers + body + StorageCompatResponseInfo at top level
|
|
1001
|
+
finalReturnType = `${headersType} & ${bodyType} & ${storageCompatInfoRef}<${bodyType}, ${headersType}>`;
|
|
1002
|
+
} else {
|
|
1003
|
+
// Body without headers — body + StorageCompatResponseInfo
|
|
1004
|
+
finalReturnType = `${bodyType} & ${storageCompatInfoRef}<${bodyType}, ${headersType}>`;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
950
1009
|
const { name, fixme = [] } = getOperationName(operation);
|
|
951
1010
|
const functionStatement = {
|
|
952
1011
|
kind: StructureKind.Function,
|
|
@@ -959,7 +1018,7 @@ export function getOperationFunction(
|
|
|
959
1018
|
name,
|
|
960
1019
|
propertyName: normalizeName(operation.name, NameType.Property),
|
|
961
1020
|
parameters,
|
|
962
|
-
returnType: `Promise<${
|
|
1021
|
+
returnType: `Promise<${finalReturnType}>`
|
|
963
1022
|
};
|
|
964
1023
|
|
|
965
1024
|
const statements: string[] = [];
|
|
@@ -969,6 +1028,29 @@ export function getOperationFunction(
|
|
|
969
1028
|
const resultVarName = generateLocallyUniqueName("result", paramNames);
|
|
970
1029
|
|
|
971
1030
|
const parameterList = parameters.map((p) => p.name).join(", ");
|
|
1031
|
+
|
|
1032
|
+
// When storage-compat is enabled, set up the onResponse interceptor before sending
|
|
1033
|
+
const storageCompatVarName = generateLocallyUniqueName(
|
|
1034
|
+
"_storageCompat",
|
|
1035
|
+
paramNames
|
|
1036
|
+
);
|
|
1037
|
+
if (isStorageCompatEnabled) {
|
|
1038
|
+
const createOnResponseRef = resolveReference(
|
|
1039
|
+
StorageCompatHelpers.createStorageCompatOnResponse
|
|
1040
|
+
);
|
|
1041
|
+
statements.push(
|
|
1042
|
+
`const ${storageCompatVarName} = ${createOnResponseRef}(${optionalParamName}.onResponse);`
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// Build the parameterList for the send call, injecting onResponse when storage-compat is enabled
|
|
1047
|
+
const sendParameterList = isStorageCompatEnabled
|
|
1048
|
+
? parameterList.replace(
|
|
1049
|
+
optionalParamName,
|
|
1050
|
+
`{...${optionalParamName}, onResponse: ${storageCompatVarName}.onResponse}`
|
|
1051
|
+
)
|
|
1052
|
+
: parameterList;
|
|
1053
|
+
|
|
972
1054
|
// Special case for binary-only bodies: use helper to call streaming methods so that Core doesn't poison the response body by
|
|
973
1055
|
// doing a UTF-8 decode on the raw bytes.
|
|
974
1056
|
if (response?.type?.kind === "bytes" && response.type.encode === "bytes") {
|
|
@@ -977,19 +1059,55 @@ export function getOperationFunction(
|
|
|
977
1059
|
paramNames
|
|
978
1060
|
);
|
|
979
1061
|
statements.push(
|
|
980
|
-
`const ${streamableMethodVarName} = _${name}Send(${
|
|
1062
|
+
`const ${streamableMethodVarName} = _${name}Send(${sendParameterList});`
|
|
981
1063
|
);
|
|
982
1064
|
statements.push(
|
|
983
1065
|
`const ${resultVarName} = await ${resolveReference(SerializationHelpers.getBinaryResponse)}(${streamableMethodVarName});`
|
|
984
1066
|
);
|
|
985
1067
|
} else {
|
|
986
1068
|
statements.push(
|
|
987
|
-
`const ${resultVarName} = await _${name}Send(${
|
|
1069
|
+
`const ${resultVarName} = await _${name}Send(${sendParameterList});`
|
|
988
1070
|
);
|
|
989
1071
|
}
|
|
990
1072
|
|
|
991
1073
|
// If the response has headers and the feature flag to include headers in response is enabled, build the headers object and include it in the return value
|
|
992
|
-
if (
|
|
1074
|
+
if (isStorageCompatEnabled) {
|
|
1075
|
+
// Storage-compat mode: wrap the return value with _response metadata using captured PipelineResponse
|
|
1076
|
+
const addStorageCompatRef = resolveReference(
|
|
1077
|
+
StorageCompatHelpers.addStorageCompatResponse
|
|
1078
|
+
);
|
|
1079
|
+
const parsedBodyVarName = generateLocallyUniqueName(
|
|
1080
|
+
"parsedBody",
|
|
1081
|
+
paramNames
|
|
1082
|
+
);
|
|
1083
|
+
const parsedHeadersVarName = generateLocallyUniqueName(
|
|
1084
|
+
"parsedHeaders",
|
|
1085
|
+
paramNames
|
|
1086
|
+
);
|
|
1087
|
+
|
|
1088
|
+
// Deserialize body
|
|
1089
|
+
if (!hasResponseBody) {
|
|
1090
|
+
statements.push(`await _${name}Deserialize(${resultVarName});`);
|
|
1091
|
+
} else {
|
|
1092
|
+
statements.push(
|
|
1093
|
+
`const ${parsedBodyVarName} = await _${name}Deserialize(${resultVarName});`
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Deserialize headers if present
|
|
1098
|
+
if (responseHeaders.length > 0) {
|
|
1099
|
+
statements.push(
|
|
1100
|
+
`const ${parsedHeadersVarName} = _${name}DeserializeHeaders(${resultVarName});`
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// Build the return statement using captured PipelineResponse
|
|
1105
|
+
const bodyArg = !hasResponseBody ? "undefined" : parsedBodyVarName;
|
|
1106
|
+
const headersArg = responseHeaders.length > 0 ? parsedHeadersVarName : "{}";
|
|
1107
|
+
statements.push(
|
|
1108
|
+
`return ${addStorageCompatRef}(${storageCompatVarName}.getRawResponse()!, ${bodyArg}, ${headersArg});`
|
|
1109
|
+
);
|
|
1110
|
+
} else if (responseHeaders.length > 0 && isResponseHeadersEnabled) {
|
|
993
1111
|
const headersVarName = generateLocallyUniqueName("headers", paramNames);
|
|
994
1112
|
statements.push(
|
|
995
1113
|
`const ${headersVarName} = _${name}DeserializeHeaders(result);`
|
|
@@ -1368,6 +1486,10 @@ function getHeaderAndBodyParameters(
|
|
|
1368
1486
|
) {
|
|
1369
1487
|
continue;
|
|
1370
1488
|
}
|
|
1489
|
+
// Skip headers marked with headerCollectionPrefix client option
|
|
1490
|
+
if (shouldSkipHeaderSerialization(param)) {
|
|
1491
|
+
continue;
|
|
1492
|
+
}
|
|
1371
1493
|
// Check if this parameter still exists in the corresponding method params (after override)
|
|
1372
1494
|
if (
|
|
1373
1495
|
param.methodParameterSegments &&
|
|
@@ -2696,6 +2818,7 @@ export function getResponseHeaders(
|
|
|
2696
2818
|
const headerMap = new Map<string, SdkServiceResponseHeader>();
|
|
2697
2819
|
for (const response of responses ?? []) {
|
|
2698
2820
|
for (const header of response.headers ?? []) {
|
|
2821
|
+
if (shouldSkipHeaderSerialization(header)) continue;
|
|
2699
2822
|
const key = header.serializedName ?? header.name;
|
|
2700
2823
|
if (!headerMap.has(key)) {
|
|
2701
2824
|
headerMap.set(key, header);
|
|
@@ -2720,7 +2843,19 @@ function buildCompositeResponseType(
|
|
|
2720
2843
|
): string {
|
|
2721
2844
|
const allParents = getAllAncestors(modelType);
|
|
2722
2845
|
const modelProps: (SdkModelPropertyType | SdkServiceResponseHeader)[] =
|
|
2723
|
-
getAllProperties(context, modelType, allParents)
|
|
2846
|
+
getAllProperties(context, modelType, allParents).filter((property) => {
|
|
2847
|
+
// Skip model properties that are headers with headerCollectionPrefix
|
|
2848
|
+
if (
|
|
2849
|
+
property.__raw &&
|
|
2850
|
+
isHeader(context.program, property.__raw) &&
|
|
2851
|
+
shouldSkipHeaderSerialization(
|
|
2852
|
+
property as SdkModelPropertyType & SdkServiceResponseHeader
|
|
2853
|
+
)
|
|
2854
|
+
) {
|
|
2855
|
+
return false;
|
|
2856
|
+
}
|
|
2857
|
+
return true;
|
|
2858
|
+
});
|
|
2724
2859
|
|
|
2725
2860
|
// Collect header property names already in the model to avoid duplicates
|
|
2726
2861
|
const modelHeaderNames = new Set<string>();
|
|
@@ -235,3 +235,21 @@ export const XmlHelpers = {
|
|
|
235
235
|
location: "serialization/xml-helpers.ts"
|
|
236
236
|
}
|
|
237
237
|
} as const;
|
|
238
|
+
|
|
239
|
+
export const StorageCompatHelpers = {
|
|
240
|
+
StorageCompatResponseInfo: {
|
|
241
|
+
kind: "interface",
|
|
242
|
+
name: "StorageCompatResponseInfo",
|
|
243
|
+
location: "storageCompatResponse.ts"
|
|
244
|
+
},
|
|
245
|
+
createStorageCompatOnResponse: {
|
|
246
|
+
kind: "function",
|
|
247
|
+
name: "createStorageCompatOnResponse",
|
|
248
|
+
location: "storageCompatResponse.ts"
|
|
249
|
+
},
|
|
250
|
+
addStorageCompatResponse: {
|
|
251
|
+
kind: "function",
|
|
252
|
+
name: "addStorageCompatResponse",
|
|
253
|
+
location: "storageCompatResponse.ts"
|
|
254
|
+
}
|
|
255
|
+
} as const;
|
|
@@ -92,6 +92,7 @@ function extractRLCOptions(
|
|
|
92
92
|
emitterOptions["ignore-enum-member-name-normalize"];
|
|
93
93
|
const compatibilityQueryMultiFormat =
|
|
94
94
|
emitterOptions["compatibility-query-multi-format"];
|
|
95
|
+
const enableStorageCompat = emitterOptions["enable-storage-compat"] === true;
|
|
95
96
|
const typespecTitleMap = emitterOptions["typespec-title-map"];
|
|
96
97
|
const hasSubscriptionId = getSubscriptionId(dpgContext);
|
|
97
98
|
const ignoreNullableOnOptional = getIgnoreNullableOnOptional(
|
|
@@ -134,7 +135,8 @@ function extractRLCOptions(
|
|
|
134
135
|
ignoreEnumMemberNameNormalize,
|
|
135
136
|
hasSubscriptionId,
|
|
136
137
|
ignoreNullableOnOptional,
|
|
137
|
-
isMultiService
|
|
138
|
+
isMultiService,
|
|
139
|
+
enableStorageCompat
|
|
138
140
|
};
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
FullOperationResponse,
|
|
6
|
+
RawResponseCallback
|
|
7
|
+
} from "@azure-rest/core-client";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Response metadata providing access to raw HTTP response details.
|
|
11
|
+
* Available when the `enable-storage-compat` emitter option is enabled.
|
|
12
|
+
*/
|
|
13
|
+
export interface StorageCompatResponseInfo<
|
|
14
|
+
TBody = unknown,
|
|
15
|
+
THeaders = Record<string, unknown>
|
|
16
|
+
> {
|
|
17
|
+
_response: {
|
|
18
|
+
/** The raw FullOperationResponse from the HTTP pipeline. */
|
|
19
|
+
rawResponse: FullOperationResponse;
|
|
20
|
+
/** The deserialized response body. */
|
|
21
|
+
parsedBody: TBody;
|
|
22
|
+
/** The deserialized response headers. */
|
|
23
|
+
parsedHeaders: THeaders;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates an onResponse callback that captures the raw FullOperationResponse.
|
|
29
|
+
* Chains with any existing user-provided onResponse callback.
|
|
30
|
+
* @param originalOnResponse - The user's original onResponse callback, if any.
|
|
31
|
+
* @returns An object with the onResponse callback and a getter for the captured response.
|
|
32
|
+
*/
|
|
33
|
+
export function createStorageCompatOnResponse(
|
|
34
|
+
originalOnResponse?: RawResponseCallback
|
|
35
|
+
): {
|
|
36
|
+
onResponse: RawResponseCallback;
|
|
37
|
+
getRawResponse: () => FullOperationResponse | undefined;
|
|
38
|
+
} {
|
|
39
|
+
let captured: FullOperationResponse | undefined;
|
|
40
|
+
return {
|
|
41
|
+
onResponse: (rawResponse: FullOperationResponse, error?: unknown) => {
|
|
42
|
+
captured = rawResponse;
|
|
43
|
+
originalOnResponse?.(rawResponse, error);
|
|
44
|
+
},
|
|
45
|
+
getRawResponse: () => captured
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Computes the return type for addStorageCompatResponse:
|
|
51
|
+
* - When TBody is undefined/void/null, returns THeaders & StorageCompatResponseInfo
|
|
52
|
+
* - Otherwise returns THeaders & TBody & StorageCompatResponseInfo
|
|
53
|
+
*
|
|
54
|
+
* Headers and body properties are spread at the top level of the result,
|
|
55
|
+
* in addition to being available under `_response.parsedHeaders` / `_response.parsedBody`.
|
|
56
|
+
*/
|
|
57
|
+
type StorageCompatResult<TBody, THeaders> = TBody extends
|
|
58
|
+
| undefined
|
|
59
|
+
| void
|
|
60
|
+
| null
|
|
61
|
+
? THeaders & StorageCompatResponseInfo<TBody, THeaders>
|
|
62
|
+
: THeaders & TBody & StorageCompatResponseInfo<TBody, THeaders>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Augments a deserialized response with raw HTTP response metadata.
|
|
66
|
+
* @param rawResponse - The raw FullOperationResponse from the HTTP pipeline.
|
|
67
|
+
* @param parsedBody - The deserialized response body.
|
|
68
|
+
* @param parsedHeaders - The deserialized response headers.
|
|
69
|
+
* @returns The parsedBody augmented with a `_response` property.
|
|
70
|
+
*/
|
|
71
|
+
export function addStorageCompatResponse<
|
|
72
|
+
TBody,
|
|
73
|
+
THeaders = Record<string, unknown>
|
|
74
|
+
>(
|
|
75
|
+
rawResponse: FullOperationResponse,
|
|
76
|
+
parsedBody: TBody,
|
|
77
|
+
parsedHeaders: THeaders
|
|
78
|
+
): StorageCompatResult<TBody, THeaders> {
|
|
79
|
+
const base =
|
|
80
|
+
parsedBody !== undefined && parsedBody !== null
|
|
81
|
+
? parsedBody
|
|
82
|
+
: ({} as TBody);
|
|
83
|
+
return Object.assign(base as any, parsedHeaders, {
|
|
84
|
+
_response: {
|
|
85
|
+
rawResponse,
|
|
86
|
+
parsedBody,
|
|
87
|
+
parsedHeaders
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|