Skip to content

Commit fe431b7

Browse files
author
Alexander Melnyk
committed
add custom user agent middleware
1 parent 866837d commit fe431b7

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

packages/commons/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose",
1515
"test:e2e": "echo 'Not Applicable'",
1616
"watch": "jest --watch",
17+
"generateVersionFile": "echo \"// this file is auto generated, do not modify\nmodule.exports = { version: '$(jq -r '.version' package.json)' };\" > src/version.ts",
1718
"build": "tsc",
1819
"lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .",
1920
"lint-fix": "eslint --fix --ext .ts,.js --no-error-on-unmatched-pattern .",

packages/commons/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * as ContextExamples from './samples/resources/contexts';
55
export * as Events from './samples/resources/events';
66
export * from './types/middy';
77
export * from './types/utils';
8+
export * from './middleware';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './cleanupMiddlewares';
22
export * from './constants';
3+
export * from './userAgentMiddleware';
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
2+
// @ts-nocheck
3+
/**
4+
* @internal
5+
*/
6+
import { version as PT_VERSION } from '../version';
7+
import { userAgentMiddleware } from '@aws-sdk/middleware-user-agent';
8+
9+
const EXEC_ENV = process.env.AWS_EXECUTION_ENV || 'NA';
10+
const middlewareOptions = {
11+
step: 'finalizeRequest',
12+
name: 'addPowertoolsToUserAgent',
13+
tags: ['POWERTOOLS', 'USER_AGENT'],
14+
};
15+
16+
/**
17+
* @internal
18+
* returns a middleware function for the MiddlewareStack, that can be used for the SDK clients
19+
* @param feature
20+
*/
21+
const customUserAgentMiddleware = (feature: string) => {
22+
return (next, _context) => async (args) => {
23+
const powertoolsUserAgent = `PT/${feature}/${PT_VERSION} PTEnv/${EXEC_ENV}`;
24+
args.request.headers['user-agent'] = args.request.headers['user-agent']
25+
? `${args.request.headers['user-agent']} ${powertoolsUserAgent}`
26+
: `${powertoolsUserAgent}`;
27+
28+
return await next(args);
29+
};
30+
};
31+
32+
const addUserAgentMiddleware = (client, feature): void => {
33+
client.middlewareStack.add(
34+
customUserAgentMiddleware(feature),
35+
middlewareOptions
36+
);
37+
};
38+
39+
export { addUserAgentMiddleware, userAgentMiddleware };

packages/commons/src/version.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// this file is auto generated, do not modify
2+
module.exports = { version: '1.10.0' };
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { addUserAgentMiddleware } from '../../src/middleware/userAgentMiddleware';
2+
import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda';
3+
4+
describe('Function: addUserAgentMiddleware', () => {
5+
it('adds powertools user agent to request header at the end', async () => {
6+
const lambdaClient = new LambdaClient({
7+
logger: console,
8+
region: 'us-east-1',
9+
endpoint: 'http://localhost:9001',
10+
maxAttempts: 1, // disable retry to have the correct number of assertions
11+
});
12+
addUserAgentMiddleware(lambdaClient, 'my-feature');
13+
14+
expect(lambdaClient.middlewareStack.identify()).toContain(
15+
'addPowertoolsToUserAgent: POWERTOOLS,USER_AGENT'
16+
);
17+
18+
lambdaClient.middlewareStack.add(
19+
(next) => (args) => {
20+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
21+
// @ts-ignore
22+
const userAgent = args?.request?.headers['user-agent'];
23+
expect(userAgent).toContain('PT/my-feature/1.10.0 PTEnv/NA');
24+
// make sure it's at the end of the user agent
25+
expect(
26+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
27+
// @ts-ignore
28+
userAgent
29+
?.split(' ')
30+
.slice(userAgent?.split(' ').length - 2)
31+
.join(' ')
32+
).toEqual('PT/my-feature/1.10.0 PTEnv/NA');
33+
34+
return next(args);
35+
},
36+
{
37+
step: 'finalizeRequest',
38+
}
39+
);
40+
try {
41+
await lambdaClient.send(
42+
new InvokeCommand({
43+
FunctionName: 'test',
44+
Payload: new TextEncoder().encode(JSON.stringify('foo')),
45+
})
46+
);
47+
} catch (e) {}
48+
});
49+
});

0 commit comments

Comments
 (0)