@gravity-ui/gateway 2.0.0 → 2.1.0
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/build/components/grpc.js
CHANGED
|
@@ -628,13 +628,30 @@ function createGrpcAction({ root, credentials }, endpoints, config, serviceKey,
|
|
|
628
628
|
packageRoot: root,
|
|
629
629
|
ErrorConstructor,
|
|
630
630
|
});
|
|
631
|
-
|
|
631
|
+
const responseHeaders = {};
|
|
632
|
+
if (config.proxyResponseHeaders) {
|
|
633
|
+
const proxyResponseHeaders = [];
|
|
634
|
+
const headersFromMetadata = (0, common_2.getHeadersFromMetadata)(trailingMetadata);
|
|
635
|
+
if (typeof config.proxyResponseHeaders === 'function') {
|
|
636
|
+
Object.assign(responseHeaders, config.proxyResponseHeaders(headersFromMetadata, 'grpc'));
|
|
637
|
+
}
|
|
638
|
+
else if (Array.isArray(config.proxyResponseHeaders)) {
|
|
639
|
+
proxyResponseHeaders.push(...config.proxyResponseHeaders);
|
|
640
|
+
}
|
|
641
|
+
for (const headerName of proxyResponseHeaders) {
|
|
642
|
+
if (responseHeaders[headerName] === undefined) {
|
|
643
|
+
responseHeaders[headerName] =
|
|
644
|
+
headersFromMetadata[headerName];
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
Object.assign(debugHeaders, (0, common_2.getHeadersFromMetadata)(trailingMetadata, 'x-metadata-'));
|
|
632
649
|
sendStats(200, Object.assign(Object.assign({}, requestData), { responseSize: (0, object_sizeof_1.default)(response), grpcStatus: 0 }));
|
|
633
650
|
ctx.log('Request completed', {
|
|
634
651
|
debugHeaders: (0, common_2.sanitizeDebugHeaders)(debugHeaders),
|
|
635
652
|
});
|
|
636
653
|
ctx.end();
|
|
637
|
-
return resolve({ responseData, debugHeaders });
|
|
654
|
+
return resolve({ responseData, responseHeaders, debugHeaders });
|
|
638
655
|
});
|
|
639
656
|
call.on('status', (status) => {
|
|
640
657
|
trailingMetadata = status.metadata.toJSON();
|
|
@@ -3,5 +3,6 @@ import { GatewayContext } from '../models/context';
|
|
|
3
3
|
import { AppErrorConstructor } from '../models/error';
|
|
4
4
|
export default function createRestAction<Context extends GatewayContext>(endpoints: EndpointsConfig | undefined, config: ApiServiceRestActionConfig<Context, any, any>, serviceKey: string, actionName: string, options: GatewayApiOptions<Context>, ErrorConstructor: AppErrorConstructor): (actionConfig: ApiActionConfig<Context, any>) => Promise<{
|
|
5
5
|
responseData: unknown;
|
|
6
|
+
responseHeaders?: Headers | undefined;
|
|
6
7
|
debugHeaders: Headers;
|
|
7
8
|
}>;
|
package/build/components/rest.js
CHANGED
|
@@ -220,6 +220,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
|
|
|
220
220
|
}
|
|
221
221
|
try {
|
|
222
222
|
const response = await axiosClient.request(requestConfig);
|
|
223
|
+
const responseHeaders = {};
|
|
223
224
|
const endRequestTime = Date.now();
|
|
224
225
|
requestData.requestTime = endRequestTime - startRequestTime;
|
|
225
226
|
if (config.transformResponseData) {
|
|
@@ -235,6 +236,20 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
|
|
|
235
236
|
(0, common_1.handleError)(ErrorConstructor, error, ctx, 'Transform response data failed');
|
|
236
237
|
}
|
|
237
238
|
}
|
|
239
|
+
if (config.proxyResponseHeaders) {
|
|
240
|
+
const proxyResponseHeaders = [];
|
|
241
|
+
if (typeof config.proxyResponseHeaders === 'function') {
|
|
242
|
+
Object.assign(responseHeaders, config.proxyResponseHeaders(Object.assign({}, response.headers), 'rest'));
|
|
243
|
+
}
|
|
244
|
+
else if (Array.isArray(config.proxyResponseHeaders)) {
|
|
245
|
+
proxyResponseHeaders.push(...config.proxyResponseHeaders);
|
|
246
|
+
}
|
|
247
|
+
for (const headerName of proxyResponseHeaders) {
|
|
248
|
+
if (responseHeaders[headerName] === undefined) {
|
|
249
|
+
responseHeaders[headerName] = response.headers[headerName];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
238
253
|
if (options === null || options === void 0 ? void 0 : options.sendStats) {
|
|
239
254
|
options.sendStats(Object.assign(Object.assign({}, requestData), { responseSize: getRestResponseSize(response === null || response === void 0 ? void 0 : response.data, ctx, ErrorConstructor), restStatus: 200 }), (0, redact_sensitive_headers_1.redactSensitiveHeaders)(parentCtx, headers), parentCtx, { debugHeaders: (0, common_1.sanitizeDebugHeaders)(debugHeaders) });
|
|
240
255
|
}
|
|
@@ -243,7 +258,7 @@ function createRestAction(endpoints, config, serviceKey, actionName, options, Er
|
|
|
243
258
|
}
|
|
244
259
|
ctx.log('Request completed', { debugHeaders: (0, common_1.sanitizeDebugHeaders)(debugHeaders) });
|
|
245
260
|
ctx.end();
|
|
246
|
-
return { responseData: response.data, debugHeaders };
|
|
261
|
+
return { responseData: response.data, responseHeaders, debugHeaders };
|
|
247
262
|
}
|
|
248
263
|
catch (error) {
|
|
249
264
|
let parsedError;
|
package/build/index.js
CHANGED
|
@@ -178,7 +178,7 @@ function generateGatewayApiController(schemasByScope, Api, config, controllerAct
|
|
|
178
178
|
throw { error, debugHeaders: {} };
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
const { responseData, debugHeaders } = await apiAction({
|
|
181
|
+
const { responseData, responseHeaders, debugHeaders } = await apiAction({
|
|
182
182
|
requestId: req.id,
|
|
183
183
|
headers: req.headers,
|
|
184
184
|
ctx: req.ctx,
|
|
@@ -188,6 +188,9 @@ function generateGatewayApiController(schemasByScope, Api, config, controllerAct
|
|
|
188
188
|
if (withDebugHeaders) {
|
|
189
189
|
res.set(debugHeaders);
|
|
190
190
|
}
|
|
191
|
+
if (responseHeaders) {
|
|
192
|
+
res.set(responseHeaders);
|
|
193
|
+
}
|
|
191
194
|
if (onRequestSuccess) {
|
|
192
195
|
return onRequestSuccess(req, res, responseData);
|
|
193
196
|
}
|
package/build/models/common.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ export interface GatewayError {
|
|
|
62
62
|
}
|
|
63
63
|
export type ProxyHeadersFunction = (headers: IncomingHttpHeaders, type: ControllerType) => IncomingHttpHeaders;
|
|
64
64
|
export type ProxyHeaders = string[] | ProxyHeadersFunction;
|
|
65
|
+
export type ProxyResponseHeadersFunction = (headers: Headers, type: ControllerType) => Headers;
|
|
66
|
+
export type ProxyResponseHeaders = string[] | ProxyResponseHeadersFunction;
|
|
65
67
|
export type GetAuthHeadersParams<AuthArgs = Record<string, unknown>> = {
|
|
66
68
|
actionType: 'rest' | 'grpc';
|
|
67
69
|
serviceName: string;
|
|
@@ -114,6 +116,7 @@ export interface ApiServiceBaseActionConfig<Context extends GatewayContext, TOut
|
|
|
114
116
|
retries?: number;
|
|
115
117
|
idempotency?: boolean;
|
|
116
118
|
proxyHeaders?: ProxyHeaders;
|
|
119
|
+
proxyResponseHeaders?: ProxyResponseHeaders;
|
|
117
120
|
metadata?: Record<string, string | number | boolean>;
|
|
118
121
|
}
|
|
119
122
|
export interface ApiServiceRestActionConfig<Context extends GatewayContext, TOutput, TParams = undefined, TTransformed = TOutput> extends ApiServiceBaseActionConfig<Context, TOutput, TParams, TTransformed> {
|
|
@@ -185,6 +188,7 @@ export interface GatewayActionHeaders {
|
|
|
185
188
|
}
|
|
186
189
|
export interface GatewayActionUnaryResponse<TAction> extends GatewayActionHeaders {
|
|
187
190
|
responseData: ApiActionResponseType<TAction>;
|
|
191
|
+
responseHeaders?: Headers;
|
|
188
192
|
}
|
|
189
193
|
export interface GatewayActionClientStreamResponse<TAction> extends GatewayActionHeaders {
|
|
190
194
|
stream: ClientWritableStream<ApiActionResponseType<TAction>>;
|
package/build/utils/common.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export declare function getKeys<T extends object>(obj: T): (keyof T)[];
|
|
|
11
11
|
* This function should only use to sanitize debugHeaders that are creating in our code
|
|
12
12
|
*/
|
|
13
13
|
export declare function sanitizeDebugHeaders(debugHeaders: Headers): _.Omit<Headers, "x-api-request-body">;
|
|
14
|
-
export declare function getHeadersFromMetadata(metadata: Record<string, grpc.MetadataValue[]
|
|
14
|
+
export declare function getHeadersFromMetadata(metadata: Record<string, grpc.MetadataValue[]>, prefix?: string): Record<string, string>;
|
|
15
15
|
export declare function handleError<Context extends GatewayContext>(ErrorConstructor: AppErrorConstructor, error: unknown, ctx: Context, message: string, extra?: Dict): void;
|
package/build/utils/common.js
CHANGED
|
@@ -30,11 +30,9 @@ function sanitizeDebugHeaders(debugHeaders) {
|
|
|
30
30
|
return lodash_1.default.omit(debugHeaders, ['x-api-request-body']);
|
|
31
31
|
}
|
|
32
32
|
exports.sanitizeDebugHeaders = sanitizeDebugHeaders;
|
|
33
|
-
function getHeadersFromMetadata(metadata) {
|
|
33
|
+
function getHeadersFromMetadata(metadata, prefix = '') {
|
|
34
34
|
return Object.entries(metadata).reduce((headers, [key, values]) => {
|
|
35
|
-
headers[
|
|
36
|
-
.filter((value) => typeof value === 'string')
|
|
37
|
-
.join(' ');
|
|
35
|
+
headers[`${prefix}${key}`] = values.filter((value) => typeof value === 'string').join(' ');
|
|
38
36
|
return headers;
|
|
39
37
|
}, {});
|
|
40
38
|
}
|