@adtrackify/at-service-common 1.0.0 → 1.0.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/.babelrc +22 -0
- package/.editorconfig +12 -0
- package/.eslintrc.json +33 -0
- package/.husky/pre-push +4 -0
- package/dist/clients/dynamodb-client.d.ts +15 -0
- package/dist/clients/dynamodb-client.js +126 -0
- package/dist/clients/dynamodb-client.js.map +1 -0
- package/dist/clients/eventbridge-client.d.ts +13 -0
- package/dist/clients/eventbridge-client.js +43 -0
- package/dist/clients/eventbridge-client.js.map +1 -0
- package/dist/clients/http-client.d.ts +30 -0
- package/dist/clients/http-client.js +39 -0
- package/dist/clients/http-client.js.map +1 -0
- package/dist/clients/index.d.ts +3 -0
- package/dist/clients/index.js +20 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/helpers/index.d.ts +3 -0
- package/dist/helpers/index.js +20 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/input-validation-helper.d.ts +2 -0
- package/dist/helpers/input-validation-helper.js +52 -0
- package/dist/helpers/input-validation-helper.js.map +1 -0
- package/dist/helpers/logging-helper.d.ts +1 -0
- package/dist/helpers/logging-helper.js +38 -0
- package/dist/helpers/logging-helper.js.map +1 -0
- package/dist/helpers/response-helper.d.ts +36 -0
- package/dist/helpers/response-helper.js +43 -0
- package/dist/helpers/response-helper.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/libs/crypto.d.ts +1 -0
- package/dist/libs/crypto.js +13 -0
- package/dist/libs/crypto.js.map +1 -0
- package/dist/libs/dates.d.ts +3 -0
- package/dist/libs/dates.js +17 -0
- package/dist/libs/dates.js.map +1 -0
- package/dist/libs/http-error.d.ts +21 -0
- package/dist/libs/http-error.js +70 -0
- package/dist/libs/http-error.js.map +1 -0
- package/dist/libs/http-status-codes.d.ts +344 -0
- package/dist/libs/http-status-codes.js +349 -0
- package/dist/libs/http-status-codes.js.map +1 -0
- package/dist/libs/index.d.ts +4 -0
- package/dist/libs/index.js +21 -0
- package/dist/libs/index.js.map +1 -0
- package/dist/types/db/index.d.ts +1 -0
- package/dist/types/db/index.js +18 -0
- package/dist/types/db/index.js.map +1 -0
- package/dist/types/db/shopify-app-install.d.ts +28 -0
- package/dist/types/db/shopify-app-install.js +3 -0
- package/dist/types/db/shopify-app-install.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/{cjs → types}/index.js +17 -17
- package/dist/types/index.js.map +1 -0
- package/env.yml +9 -0
- package/jest.config.js +39 -0
- package/package.json +53 -63
- package/prettier.config.js +9 -0
- package/src/clients/axios.d.ts +8 -0
- package/src/clients/dynamodb-client.ts +85 -0
- package/src/clients/eventbridge-client.ts +38 -0
- package/src/clients/http-client.ts +36 -0
- package/src/clients/index.ts +3 -0
- package/src/helpers/index.ts +3 -0
- package/src/helpers/input-validation-helper.ts +22 -0
- package/src/helpers/logging-helper.ts +10 -0
- package/src/helpers/response-helper.ts +40 -0
- package/src/index.ts +4 -0
- package/src/libs/crypto.ts +6 -0
- package/src/libs/dates.ts +14 -0
- package/src/libs/http-error.ts +100 -0
- package/src/libs/http-status-codes.ts +344 -0
- package/src/libs/index.ts +4 -0
- package/src/types/db/index.ts +1 -0
- package/src/types/db/shopify-app-install.ts +31 -0
- package/src/types/index.ts +1 -0
- package/tsconfig.json +25 -0
- package/tslint.json +6 -0
- package/README.md +0 -1
- package/dist/cjs/fingerprint.d.ts +0 -3
- package/dist/cjs/fingerprint.js +0 -9
- package/dist/cjs/fingerprint.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/sources/architecture.d.ts +0 -1
- package/dist/cjs/sources/architecture.js +0 -16
- package/dist/cjs/sources/architecture.js.map +0 -1
- package/dist/cjs/sources/cookie-enabled.d.ts +0 -1
- package/dist/cjs/sources/cookie-enabled.js +0 -12
- package/dist/cjs/sources/cookie-enabled.js.map +0 -1
- package/dist/cjs/sources/cpu-class.d.ts +0 -1
- package/dist/cjs/sources/cpu-class.js +0 -12
- package/dist/cjs/sources/cpu-class.js.map +0 -1
- package/dist/cjs/sources/device-memory.d.ts +0 -1
- package/dist/cjs/sources/device-memory.js +0 -12
- package/dist/cjs/sources/device-memory.js.map +0 -1
- package/dist/cjs/sources/platform.d.ts +0 -1
- package/dist/cjs/sources/platform.js +0 -12
- package/dist/cjs/sources/platform.js.map +0 -1
- package/dist/cjs/sources/plugins.d.ts +0 -1
- package/dist/cjs/sources/plugins.js +0 -26
- package/dist/cjs/sources/plugins.js.map +0 -1
- package/dist/cjs/sources/timezone.d.ts +0 -1
- package/dist/cjs/sources/timezone.js +0 -12
- package/dist/cjs/sources/timezone.js.map +0 -1
- package/dist/cjs/sources/user-agent.d.ts +0 -1
- package/dist/cjs/sources/user-agent.js +0 -12
- package/dist/cjs/sources/user-agent.js.map +0 -1
- package/dist/esm/fingerprint.d.ts +0 -3
- package/dist/esm/fingerprint.js +0 -5
- package/dist/esm/fingerprint.js.map +0 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/sources/architecture.d.ts +0 -1
- package/dist/esm/sources/architecture.js +0 -13
- package/dist/esm/sources/architecture.js.map +0 -1
- package/dist/esm/sources/cookie-enabled.d.ts +0 -1
- package/dist/esm/sources/cookie-enabled.js +0 -9
- package/dist/esm/sources/cookie-enabled.js.map +0 -1
- package/dist/esm/sources/cpu-class.d.ts +0 -1
- package/dist/esm/sources/cpu-class.js +0 -9
- package/dist/esm/sources/cpu-class.js.map +0 -1
- package/dist/esm/sources/device-memory.d.ts +0 -1
- package/dist/esm/sources/device-memory.js +0 -9
- package/dist/esm/sources/device-memory.js.map +0 -1
- package/dist/esm/sources/platform.d.ts +0 -1
- package/dist/esm/sources/platform.js +0 -9
- package/dist/esm/sources/platform.js.map +0 -1
- package/dist/esm/sources/plugins.d.ts +0 -1
- package/dist/esm/sources/plugins.js +0 -22
- package/dist/esm/sources/plugins.js.map +0 -1
- package/dist/esm/sources/timezone.d.ts +0 -1
- package/dist/esm/sources/timezone.js +0 -9
- package/dist/esm/sources/timezone.js.map +0 -1
- package/dist/esm/sources/user-agent.d.ts +0 -1
- package/dist/esm/sources/user-agent.js +0 -9
- package/dist/esm/sources/user-agent.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adtrackify/at-service-common",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
],
|
|
8
|
-
"main": "./dist/cjs/index.js",
|
|
9
|
-
"module": "./dist/esm/index.js",
|
|
10
|
-
"type": "module",
|
|
11
|
-
"engines": {
|
|
12
|
-
"npm": ">=8.0.0 <9.0.0",
|
|
13
|
-
"node": ">=16.0.0 <18.14.2"
|
|
14
|
-
},
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.ts",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
15
7
|
"scripts": {
|
|
16
8
|
"clean": "rimraf dist",
|
|
17
|
-
"build": "
|
|
9
|
+
"build": "node ./node_modules/typescript/bin/tsc",
|
|
18
10
|
"build:dev": "npm run clean && npm run verify && cross-env NODE_ENV=production stage=dev APP_ENV=dev npm run build",
|
|
19
|
-
"build:qa": "npm run clean && npm run verify && cross-env NODE_ENV=production stage=qa APP_ENV=qa
|
|
20
|
-
"build:prod": "npm run clean && npm run verify && cross-env NODE_ENV=production stage=prod APP_ENV=prod
|
|
21
|
-
"elint": "eslint .",
|
|
11
|
+
"build:qa": "npm run clean && npm run verify && cross-env NODE_ENV=production stage=qa APP_ENV=qa webpack",
|
|
12
|
+
"build:prod": "npm run clean && npm run verify && cross-env NODE_ENV=production stage=prod APP_ENV=prod webpack",
|
|
13
|
+
"elint": "eslint --ignore-path .gitignore .",
|
|
22
14
|
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
|
|
23
|
-
"lint": "
|
|
24
|
-
"lint:fix": "eslint . --fix",
|
|
15
|
+
"lint": "tslint -p tsconfig.json",
|
|
16
|
+
"lint:fix": "eslint --ignore-path .gitignore . --fix",
|
|
25
17
|
"coverage": "npm run test:all -- --coverage --group=unit",
|
|
26
18
|
"test": "jest --group=unit --coverage",
|
|
27
19
|
"test:all": "cross-env AWS_REGION=us-east-2 NODE_ENV=test jest --group=unit --coverage",
|
|
@@ -29,72 +21,70 @@
|
|
|
29
21
|
"verify": "npm run clean && npm run type-check && npm run lint:fix",
|
|
30
22
|
"version": "npm run format && git add -A src",
|
|
31
23
|
"postversion": "git push && git push --tags",
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
24
|
+
"type-check": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@types/axios": "^0.14.0",
|
|
28
|
+
"@types/deep-freeze": "^0.1.2",
|
|
29
|
+
"@types/ua-parser-js": "^0.7.36",
|
|
30
|
+
"aws-sdk": "^2.1189.0",
|
|
31
|
+
"axios": "^0.27.2",
|
|
32
|
+
"axios-retry": "^3.3.1",
|
|
33
|
+
"crypto": "^1.0.1",
|
|
34
|
+
"esbuild": "^0.14.53",
|
|
35
|
+
"http-status-codes": "^2.2.0",
|
|
36
|
+
"joi": "^17.6.0",
|
|
37
|
+
"lambda-log": "^3.1.0",
|
|
38
|
+
"typescript": "^4.7.4",
|
|
39
|
+
"ua-parser-js": "^1.0.2"
|
|
36
40
|
},
|
|
37
|
-
"dependencies": {},
|
|
38
|
-
"peerDependencies": {},
|
|
39
41
|
"devDependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@types/jest": "^28.1.8",
|
|
51
|
-
"@types/lambda-log": "^3.0.0",
|
|
52
|
-
"@types/luxon": "^3.0.1",
|
|
42
|
+
"@babel/cli": "^7.13.16",
|
|
43
|
+
"@babel/core": "^7.13.10",
|
|
44
|
+
"@babel/plugin-proposal-optional-chaining": "^7.13.8",
|
|
45
|
+
"@babel/plugin-transform-runtime": "^7.10.3",
|
|
46
|
+
"@babel/preset-env": "^7.16.8",
|
|
47
|
+
"@babel/preset-typescript": "^7.16.7",
|
|
48
|
+
"@babel/runtime-corejs3": "^7.13.17",
|
|
49
|
+
"@types/jest": "^27.4.1",
|
|
50
|
+
"@types/lambda-log": "^2.2.1",
|
|
51
|
+
"@types/luxon": "^3.0.0",
|
|
53
52
|
"@types/node": "^17.0.8",
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
|
54
|
+
"@typescript-eslint/parser": "^5.21.0",
|
|
55
|
+
"babel-eslint": "^10.1.0",
|
|
56
|
+
"babel-jest": "^26.6.3",
|
|
57
|
+
"babel-loader": "^8.2.2",
|
|
58
|
+
"babel-polyfill": "^6.26.0",
|
|
59
|
+
"core-js": "^3.21.1",
|
|
59
60
|
"cross-env": "^7.0.3",
|
|
60
|
-
"
|
|
61
|
-
"eslint": "^8.23.1",
|
|
61
|
+
"eslint": "^8.14.0",
|
|
62
62
|
"eslint-config-standard": "^17.0.0",
|
|
63
|
+
"eslint-loader": "^4.0.2",
|
|
63
64
|
"eslint-plugin-babel": "^5.3.1",
|
|
64
65
|
"eslint-plugin-import": "^2.26.0",
|
|
65
|
-
"eslint-plugin-n": "^15.2.
|
|
66
|
-
"eslint-plugin-promise": "^6.0.
|
|
66
|
+
"eslint-plugin-n": "^15.2.0",
|
|
67
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
68
|
+
"eslint-webpack-plugin": "^3.1.1",
|
|
67
69
|
"glob": "^8.0.3",
|
|
68
70
|
"husky": "^6.0.0",
|
|
69
|
-
"jest": "^
|
|
71
|
+
"jest": "^27.5.1",
|
|
70
72
|
"jest-cucumber": "3.0.1",
|
|
71
73
|
"jest-junit": "13.0.0",
|
|
72
|
-
"jest-runner": "
|
|
73
|
-
"jest-runner-groups": "2.2.0",
|
|
74
|
-
"npm-dts": "^1.3.12",
|
|
74
|
+
"jest-runner-groups": "2.1.0",
|
|
75
75
|
"npm-run-all": "^4.1.5",
|
|
76
76
|
"npm-scripts-info": "^0.3.9",
|
|
77
77
|
"prettier": "^2.7.1",
|
|
78
78
|
"regenerator-runtime": "^0.13.9",
|
|
79
79
|
"rimraf": "^3.0.2",
|
|
80
|
-
"swc-loader": "^0.2.3",
|
|
81
|
-
"ts-jest": "^29.0.5",
|
|
82
|
-
"ts-jest-resolver": "^2.0.1",
|
|
83
|
-
"ts-loader": "^9.4.2",
|
|
84
|
-
"ts-node": "^10.9.1",
|
|
85
80
|
"tslint": "^6.1.3",
|
|
86
|
-
"tslint-config-prettier": "^1.18.0"
|
|
87
|
-
"typescript": "4.9.5"
|
|
81
|
+
"tslint-config-prettier": "^1.18.0"
|
|
88
82
|
},
|
|
89
83
|
"repository": {
|
|
90
84
|
"type": "git",
|
|
91
|
-
"url": "git+
|
|
85
|
+
"url": "git+ssh://git@bitbucket.org/eacap/at-tracking-event-types.git"
|
|
92
86
|
},
|
|
93
87
|
"author": "",
|
|
94
88
|
"license": "ISC",
|
|
95
|
-
"
|
|
96
|
-
"bugs": {
|
|
97
|
-
"url": "https://bitbucket.org/eacap/fingerprint/issues"
|
|
98
|
-
},
|
|
99
|
-
"homepage": "https://bitbucket.org/eacap/fingerprint#readme"
|
|
89
|
+
"homepage": "https://bitbucket.org/eacap/at-tracking-event-types#readme"
|
|
100
90
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import AWS from 'aws-sdk';
|
|
2
|
+
import * as log from 'lambda-log';
|
|
3
|
+
import { BatchGetItemInput, DeleteItemInput, GetItemInput, PutItemInput, QueryInput, QueryOutput, ScanInput, UpdateItemInput } from 'aws-sdk/clients/dynamodb';
|
|
4
|
+
const client = new AWS.DynamoDB.DocumentClient();
|
|
5
|
+
|
|
6
|
+
export default class DynamoDbClient {
|
|
7
|
+
static safeGet = async (tableName: string, keyName: string, keyValue: any) => {
|
|
8
|
+
try {
|
|
9
|
+
const params = {
|
|
10
|
+
TableName: tableName,
|
|
11
|
+
Key: {
|
|
12
|
+
[keyName]: keyValue
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const res = await client.get(params).promise();
|
|
16
|
+
return res?.Item ?? null;
|
|
17
|
+
} catch (e: any) {
|
|
18
|
+
log.error(e, { message: 'Dynamo Client Get Failed' });
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
static safePut = async (tableName: string, data: any) => {
|
|
24
|
+
try {
|
|
25
|
+
const params = {
|
|
26
|
+
TableName: tableName,
|
|
27
|
+
Item: data
|
|
28
|
+
};
|
|
29
|
+
const res = await client.put(params).promise();
|
|
30
|
+
return res;
|
|
31
|
+
} catch (e: any) {
|
|
32
|
+
log.error(e, { message: 'Dynamo failed simplePut' })
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
static safeBatchGet = async (tableName: string, keys: AWS.DynamoDB.KeyList) => {
|
|
38
|
+
try {
|
|
39
|
+
const params: BatchGetItemInput = {
|
|
40
|
+
RequestItems: {}
|
|
41
|
+
};
|
|
42
|
+
params.RequestItems[tableName] = {
|
|
43
|
+
Keys: keys
|
|
44
|
+
};
|
|
45
|
+
const res = await client.batchGet(params).promise();
|
|
46
|
+
log.info('batchget res', { batchGetRes: res })
|
|
47
|
+
if (res?.Responses?.[tableName]) {
|
|
48
|
+
return res?.Responses?.[tableName];
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
} catch (e: any) {
|
|
52
|
+
log.error(e, { message: 'Dynamo failed safeBatchGet' })
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
static queryAll = async (params: QueryInput) => {
|
|
58
|
+
try {
|
|
59
|
+
log.info('Invoke Query All', { params });
|
|
60
|
+
let currentResult: QueryOutput, exclusiveStartKey;
|
|
61
|
+
let accumulatedResults: any[] = [];
|
|
62
|
+
do {
|
|
63
|
+
params.ExclusiveStartKey = exclusiveStartKey;
|
|
64
|
+
params.Limit = 200;
|
|
65
|
+
currentResult = await client.query(params).promise();
|
|
66
|
+
if (currentResult.Items) {
|
|
67
|
+
exclusiveStartKey = currentResult.LastEvaluatedKey;
|
|
68
|
+
accumulatedResults = [...accumulatedResults, ...currentResult.Items];
|
|
69
|
+
}
|
|
70
|
+
} while (currentResult.Items && currentResult.Items.length > 0 && currentResult.LastEvaluatedKey);
|
|
71
|
+
return accumulatedResults;
|
|
72
|
+
} catch (e: any) {
|
|
73
|
+
log.error(e, { message: 'Dynamo failed queryAll' })
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
static batchGet = (params: BatchGetItemInput) => client.batchGet(params).promise();
|
|
79
|
+
static get = (params: GetItemInput) => client.get(params).promise();
|
|
80
|
+
static put = (params: PutItemInput) => client.put(params).promise();
|
|
81
|
+
static query = (params: QueryInput) => client.query(params).promise();
|
|
82
|
+
static scan = (params: ScanInput) => client.scan(params).promise();
|
|
83
|
+
static update = (params: UpdateItemInput) => client.update(params).promise();
|
|
84
|
+
static delete = (params: DeleteItemInput) => client.delete(params).promise();
|
|
85
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { EventBridge } from 'aws-sdk';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { getCurrentTimestamp } from '../libs/dates';
|
|
4
|
+
|
|
5
|
+
export class EventBridgeClient {
|
|
6
|
+
public eventBridge: EventBridge;
|
|
7
|
+
public EVENT_BUS_NAME: string;
|
|
8
|
+
|
|
9
|
+
constructor (eventBusName: string) {
|
|
10
|
+
this.eventBridge = new EventBridge();
|
|
11
|
+
this.EVENT_BUS_NAME = eventBusName;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public buildEvent = (eventType: string, eventData: any, eventId: string = uuidv4(), eventTime: string = getCurrentTimestamp()) => {
|
|
15
|
+
return {
|
|
16
|
+
eventId,
|
|
17
|
+
eventType,
|
|
18
|
+
eventTime,
|
|
19
|
+
eventData
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
public putEvent = async (source: string, detailType: string, data: any, headers: any = null) => {
|
|
25
|
+
const params = {
|
|
26
|
+
Entries: [ {
|
|
27
|
+
Detail: JSON.stringify({ headers, data }),
|
|
28
|
+
DetailType: detailType,
|
|
29
|
+
EventBusName: this.EVENT_BUS_NAME,
|
|
30
|
+
Source: source,
|
|
31
|
+
Time: new Date(),
|
|
32
|
+
} ],
|
|
33
|
+
};
|
|
34
|
+
return await this.eventBridge.putEvents(params).promise();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import axios, { AxiosRequestConfig } from 'axios';
|
|
2
|
+
import axiosRetry from 'axios-retry';
|
|
3
|
+
import https from 'https'
|
|
4
|
+
import httpAdapter from 'axios/lib/adapters/http';
|
|
5
|
+
|
|
6
|
+
const httpResponse = (res: any = {}) => {
|
|
7
|
+
return {
|
|
8
|
+
headers: res?.header || {},
|
|
9
|
+
data: res?.data || {},
|
|
10
|
+
status: res?.status || 0,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const axiosHttpService = (config: AxiosRequestConfig = {}) => {
|
|
15
|
+
config.adapter = httpAdapter;
|
|
16
|
+
config.httpsAgent = new https.Agent({ keepAlive: true });
|
|
17
|
+
const axiosService = axios.create(config);
|
|
18
|
+
|
|
19
|
+
axiosRetry(axiosService, { retryDelay: axiosRetry.exponentialDelay, retries: 3 });
|
|
20
|
+
|
|
21
|
+
const handleAxiosError = (error: any) => {
|
|
22
|
+
if (!error?.response && !error?.request) throw error;
|
|
23
|
+
return error.response ? httpResponse(error.response) : httpResponse({ status: 500, data: { error: error.request } });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
instance: () => axiosService,
|
|
28
|
+
get: (url: string, config?: AxiosRequestConfig) => axiosService.get(url, config).then(httpResponse, handleAxiosError),
|
|
29
|
+
post: (url: string, data?: any, config?: AxiosRequestConfig) => axiosService.post(url, data, config).then(httpResponse, handleAxiosError),
|
|
30
|
+
delete: (url: string, config?: AxiosRequestConfig) => axiosService.delete(url, config).then(httpResponse, handleAxiosError),
|
|
31
|
+
put: (url: string, data?: any, config?: AxiosRequestConfig) => axiosService.put(url, data, config).then(httpResponse, handleAxiosError),
|
|
32
|
+
patch: (url: string, data?: any, config?: AxiosRequestConfig) => axiosService.patch(url, data, config).then(httpResponse, handleAxiosError),
|
|
33
|
+
setBaseUrl: (url: string) => !!(axiosService.defaults.baseURL = url)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import HttpError from '../libs/http-error';
|
|
2
|
+
import * as log from 'lambda-log';
|
|
3
|
+
import Joi from 'joi';
|
|
4
|
+
|
|
5
|
+
export const validateInput = (schema: Joi.ObjectSchema<any>, input: any) => {
|
|
6
|
+
const { error, value } = schema.validate(input);
|
|
7
|
+
if (error) {
|
|
8
|
+
log.info('', { error });
|
|
9
|
+
|
|
10
|
+
const httperr = HttpError.badRequest('Input Validation Failure', {
|
|
11
|
+
errors: error.details.map(detail => ({
|
|
12
|
+
message: detail?.message,
|
|
13
|
+
key: detail?.context?.key,
|
|
14
|
+
path: detail?.path,
|
|
15
|
+
}))
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
log.info('', { httperr });
|
|
19
|
+
throw httperr;
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as log from 'lambda-log';
|
|
2
|
+
const stage = process?.env?.STAGE;
|
|
3
|
+
|
|
4
|
+
export const configureLogger = (event: any, context: any, debug: boolean = true) => {
|
|
5
|
+
log.options.meta.stage = stage;
|
|
6
|
+
log.options.meta.source_name = context?.functionName || 'unknown';
|
|
7
|
+
log.options.meta.awsRequestId = context?.awsRequestId || 'unknown';
|
|
8
|
+
log.options.meta.lambdaEvent = event;
|
|
9
|
+
log.options.debug = debug;
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
export const success = (body: any) => {
|
|
3
|
+
return buildResponse(200, body);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const defaultError = {
|
|
7
|
+
message: 'internalServerError'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const failure = (error: any, statusCode: number = 500) => {
|
|
11
|
+
statusCode = error?.statusCode ?? statusCode;
|
|
12
|
+
|
|
13
|
+
let body = defaultError;
|
|
14
|
+
if (error?.body) {
|
|
15
|
+
body = error.body;
|
|
16
|
+
}
|
|
17
|
+
else if (error?.message) {
|
|
18
|
+
body = { message: error.message };
|
|
19
|
+
} else if (statusCode === 500) {
|
|
20
|
+
body = defaultError;
|
|
21
|
+
}
|
|
22
|
+
return buildResponse(statusCode, body);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const buildResponse = (statusCode: number, body: any = {}) => {
|
|
26
|
+
delete body.stack;
|
|
27
|
+
return {
|
|
28
|
+
statusCode: statusCode,
|
|
29
|
+
headers: {
|
|
30
|
+
'Access-Control-Allow-Origin': '*',
|
|
31
|
+
'Access-Control-Allow-Credentials': true,
|
|
32
|
+
'cache-control': 'max-age=86400',
|
|
33
|
+
Date: new Date(),
|
|
34
|
+
'Last-Modified': new Date(),
|
|
35
|
+
'Access-Control-Allow-Headers':
|
|
36
|
+
'Content-Type, Content-Encoding'
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify(body),
|
|
39
|
+
};
|
|
40
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
3
|
+
|
|
4
|
+
export const getCurrentTimestamp = (): string => {
|
|
5
|
+
return DateTime.utc().toJSDate().toISOString();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getDateFromTimestamp = (timestamp: string) => {
|
|
9
|
+
return timestamp.split('T')[0];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const getCurrentDate = (): string => {
|
|
13
|
+
return getDateFromTimestamp(getCurrentTimestamp());
|
|
14
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* eslint-disable no-dupe-class-members */
|
|
2
|
+
import { strict as assert } from 'assert';
|
|
3
|
+
import deepFreeze from 'deep-freeze';
|
|
4
|
+
|
|
5
|
+
const deepClone = (o = {}) => JSON.parse(JSON.stringify(o));
|
|
6
|
+
const containsStackTrace = (text: string = '') => /at.+\.js:\d+:\d+/.test(text);
|
|
7
|
+
const objectContainsStackTrace = (obj: any) =>
|
|
8
|
+
!obj ? false : containsStackTrace(JSON.stringify(obj));
|
|
9
|
+
|
|
10
|
+
// may only be expanded by governance, never reduced
|
|
11
|
+
const supportedStatusCodes: any = {
|
|
12
|
+
400: 'Bad Request',
|
|
13
|
+
401: 'Unauthorized',
|
|
14
|
+
403: 'Forbidden',
|
|
15
|
+
404: 'Not Found',
|
|
16
|
+
405: 'Method Not Allowed',
|
|
17
|
+
409: 'Conflict',
|
|
18
|
+
412: 'Precondition Failed',
|
|
19
|
+
413: 'Payload Too Large',
|
|
20
|
+
415: 'Unsupported Media Type',
|
|
21
|
+
428: 'Precondition Required',
|
|
22
|
+
429: 'Too Many Requests',
|
|
23
|
+
500: 'Internal Server Error',
|
|
24
|
+
501: 'Not Implemented',
|
|
25
|
+
502: 'Bad Gateway',
|
|
26
|
+
503: 'Service Unavailable',
|
|
27
|
+
504: 'Gateway Timeout'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const supportedStatusCodesMessage = `statusCode must be one of the following: ${JSON.stringify(Object.keys(supportedStatusCodes))}`;
|
|
31
|
+
const onlyStatusCodeMessage = 'Server errors may not specify any parameter except statusCode';
|
|
32
|
+
|
|
33
|
+
const isNullOrUndefined = (value: any) => value === null || value === undefined;
|
|
34
|
+
|
|
35
|
+
export default class HttpError extends Error {
|
|
36
|
+
body: {
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
};
|
|
39
|
+
headers: object[];
|
|
40
|
+
statusCode: number;
|
|
41
|
+
isServerError: boolean;
|
|
42
|
+
|
|
43
|
+
constructor(statusCode: number,
|
|
44
|
+
message?: string,
|
|
45
|
+
body?: {
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
},
|
|
48
|
+
headers?: object[]) {
|
|
49
|
+
assert(statusCode in supportedStatusCodes, supportedStatusCodesMessage);
|
|
50
|
+
|
|
51
|
+
const isServerError = statusCode > 499;
|
|
52
|
+
|
|
53
|
+
if (isServerError) {
|
|
54
|
+
assert(
|
|
55
|
+
isNullOrUndefined(message) && isNullOrUndefined(body),
|
|
56
|
+
onlyStatusCodeMessage
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
message = supportedStatusCodes[statusCode] as string;
|
|
60
|
+
} else {
|
|
61
|
+
assert(
|
|
62
|
+
body === undefined || typeof body === 'object',
|
|
63
|
+
'body must be an object or omitted'
|
|
64
|
+
);
|
|
65
|
+
assert(
|
|
66
|
+
headers === undefined || typeof headers === 'object',
|
|
67
|
+
'headers must be an object or omitted'
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
message = message ?? supportedStatusCodes[statusCode];
|
|
71
|
+
|
|
72
|
+
assert(
|
|
73
|
+
!containsStackTrace(message) && !objectContainsStackTrace(body),
|
|
74
|
+
'the message or data parameters may not contain errors or stack traces'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
super(message);
|
|
79
|
+
|
|
80
|
+
this.body = deepClone(body);
|
|
81
|
+
this.headers = deepFreeze(deepClone(headers));
|
|
82
|
+
this.statusCode = statusCode;
|
|
83
|
+
this.isServerError = isServerError;
|
|
84
|
+
if (!this?.body?.message) {
|
|
85
|
+
this.body.message = this.message;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
static get supportedStatusCodes() { return supportedStatusCodes; }
|
|
91
|
+
static badRequest = (message?: string, body?: object, headers?: object[]) => { return new HttpError(400, message, body, headers) };
|
|
92
|
+
static unauthorized = (message?: string, body?: object, headers?: object[]) => new HttpError(401, message, body, headers);
|
|
93
|
+
static forbidden = (message?: string, body?: object, headers?: object[]) => new HttpError(403, message, body, headers);
|
|
94
|
+
static notFound = (message?: string, body?: object, headers?: object[]) => new HttpError(404, message, body, headers);
|
|
95
|
+
static internal = (message?: string, body?: object, headers?: object[]) => new HttpError(500, message, body, headers);
|
|
96
|
+
static notImplemented = () => new HttpError(501);
|
|
97
|
+
static badGateway = () => new HttpError(502);
|
|
98
|
+
static serviceUnavailable = (headers: object[]) => new HttpError(503, undefined, undefined, headers);
|
|
99
|
+
static gatewayTimeout = () => new HttpError(504);
|
|
100
|
+
}
|