ag-common 0.0.92 → 0.0.96

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.
@@ -0,0 +1,11 @@
1
+ export declare const enforceDynamoProvisionCap: ({ tables, readsMax, writesMax, }: {
2
+ tables: any[];
3
+ /**
4
+ * default 25
5
+ */
6
+ readsMax?: number | undefined;
7
+ /**
8
+ * default 25
9
+ */
10
+ writesMax?: number | undefined;
11
+ }) => void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceDynamoProvisionCap = void 0;
4
+ const log_1 = require("../../common/helpers/log");
5
+ const math_1 = require("../../common/helpers/math");
6
+ const string_1 = require("../../common/helpers/string");
7
+ const extractSum = ({ str, regex }) => {
8
+ var _a;
9
+ return (0, math_1.sumArray)(((_a = str
10
+ .match(regex)) === null || _a === void 0 ? void 0 : _a.map((s2) => (0, string_1.trim)(s2.substring(s2.indexOf(':') + 1), ':', ',', ' ')).filter((r) => r && Number(r)).map((r) => Number(r))) || []);
11
+ };
12
+ const enforceDynamoProvisionCap = ({ tables, readsMax = 25, writesMax = 25, }) => {
13
+ if (!tables || tables.length === 0) {
14
+ (0, log_1.warn)('error in dynamo FT enforce');
15
+ return;
16
+ }
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ const t = tables[0];
19
+ const s = (0, string_1.safeStringify)(t.node._children.Resource.node.scope);
20
+ const reads = extractSum({ str: s, regex: /readCapacityUnits.*/gim });
21
+ const writes = extractSum({ str: s, regex: /writeCapacityUnits.*/gim });
22
+ if (reads > readsMax) {
23
+ (0, log_1.warn)(`dynamo table provisioned reads:${reads} greater than max:${readsMax}`);
24
+ throw new Error('exceeded dynamo provision cap');
25
+ }
26
+ if (writes > writesMax) {
27
+ (0, log_1.warn)(`dynamo table provisioned writes:${writes} greater than max:${writesMax}`);
28
+ throw new Error('exceeded dynamo provision cap');
29
+ }
30
+ (0, log_1.warn)(`dynamo provisioned total: R=${reads} W=${writes}`);
31
+ };
32
+ exports.enforceDynamoProvisionCap = enforceDynamoProvisionCap;
@@ -1,6 +1,7 @@
1
1
  export * from './api';
2
2
  export * from './aws';
3
3
  export * from './dynamo';
4
+ export * from './enforceDynamoProvisionCap';
4
5
  export * from './dynamoInfra';
5
6
  export * from './openApiHelpers';
6
7
  export * from './s3';
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./api"), exports);
14
14
  __exportStar(require("./aws"), exports);
15
15
  __exportStar(require("./dynamo"), exports);
16
+ __exportStar(require("./enforceDynamoProvisionCap"), exports);
16
17
  __exportStar(require("./dynamoInfra"), exports);
17
18
  __exportStar(require("./openApiHelpers"), exports);
18
19
  __exportStar(require("./s3"), exports);
@@ -8,10 +8,14 @@ export declare type NextType<T> = ({ event, body, params, userProfile, lang, }:
8
8
  userProfile?: User;
9
9
  lang: TLang;
10
10
  }) => Promise<APIGatewayProxyResult>;
11
- export declare function validateOpenApi<T>({ event, next, authorized, schema, COGNITO_USER_POOL_ID, }: {
11
+ export declare function validateOpenApi<T>({ event, next, authorized, schema, COGNITO_USER_POOL_ID, jwksRegion, }: {
12
12
  COGNITO_USER_POOL_ID: string;
13
13
  schema: any;
14
14
  event: APIGatewayEvent;
15
15
  next: NextType<T>;
16
16
  authorized?: true | false | 'optional';
17
+ /**
18
+ * default ap-southeast-2
19
+ */
20
+ jwksRegion?: string;
17
21
  }): Promise<APIGatewayProxyResult>;
@@ -43,7 +43,7 @@ const getOperation = ({ path, method, resource, schema, }) => {
43
43
  const pathParams = (re === null || re === void 0 ? void 0 : re.groups) && JSON.parse(JSON.stringify(re === null || re === void 0 ? void 0 : re.groups));
44
44
  return { operation, pathParams };
45
45
  };
46
- function validateOpenApi({ event, next, authorized, schema, COGNITO_USER_POOL_ID, }) {
46
+ function validateOpenApi({ event, next, authorized, schema, COGNITO_USER_POOL_ID, jwksRegion = 'ap-southeast-2', }) {
47
47
  var _a, _b, _c, _d, _e;
48
48
  return __awaiter(this, void 0, void 0, function* () {
49
49
  if (!schema) {
@@ -107,6 +107,7 @@ function validateOpenApi({ event, next, authorized, schema, COGNITO_USER_POOL_ID
107
107
  ({ error, userProfile } = yield (0, validations_1.getAndValidateToken)({
108
108
  tokenRaw: authHeader,
109
109
  COGNITO_USER_POOL_ID,
110
+ jwksRegion,
110
111
  }));
111
112
  if (error) {
112
113
  return error;
@@ -65,7 +65,7 @@ const getAndValidateToken = ({ tokenRaw, jwksRegion = 'ap-southeast-2', COGNITO_
65
65
  let token = '';
66
66
  try {
67
67
  if (!tokenRaw) {
68
- const m = 'no auth headers, auth failed';
68
+ const m = 'auth error: no auth headers';
69
69
  (0, log_1.error)(m);
70
70
  return {
71
71
  error: (0, api_1.returnCode)(403, m),
@@ -24,3 +24,10 @@ export declare function toTitleCase(str: string): string;
24
24
  */
25
25
  export declare function replaceRemove(str: string, ...params: string[]): string;
26
26
  export declare function containsInsensitive(str: string, ...args: string[]): boolean;
27
+ /**
28
+ * safely handles circular references
29
+ * @param obj
30
+ * @param indent
31
+ * @returns
32
+ */
33
+ export declare const safeStringify: (obj: any, indent?: number) => string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.containsInsensitive = exports.replaceRemove = exports.toTitleCase = exports.niceUrl = exports.truncate = exports.trim = exports.trimSide = exports.csvJSON = void 0;
3
+ exports.safeStringify = exports.containsInsensitive = exports.replaceRemove = exports.toTitleCase = exports.niceUrl = exports.truncate = exports.trim = exports.trimSide = exports.csvJSON = void 0;
4
4
  const csvJSON = (csv) => {
5
5
  const lines = csv.split('\n');
6
6
  const result = [];
@@ -117,3 +117,22 @@ function containsInsensitive(str, ...args) {
117
117
  return !!args.find((a) => l.includes(a));
118
118
  }
119
119
  exports.containsInsensitive = containsInsensitive;
120
+ /**
121
+ * safely handles circular references
122
+ * @param obj
123
+ * @param indent
124
+ * @returns
125
+ */
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ const safeStringify = (obj, indent = 2) => {
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+ let cache = [];
130
+ const retVal = JSON.stringify(obj, (_key, value) => typeof value === 'object' && value !== null
131
+ ? cache.includes(value)
132
+ ? undefined // Duplicate reference found, discard key
133
+ : cache.push(value) && value // Store value in our collection
134
+ : value, indent);
135
+ cache = null;
136
+ return retVal;
137
+ };
138
+ exports.safeStringify = safeStringify;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ag-common",
3
- "version": "0.0.92",
3
+ "version": "0.0.96",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Andrei Gec <@andreigec> (https://gec.dev/)",