@bitblit/ratchet-epsilon-common 6.0.145-alpha → 6.0.147-alpha

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.
Files changed (164) hide show
  1. package/package.json +10 -9
  2. package/src/background/background-dynamo-log-table-handler.ts +44 -0
  3. package/src/background/background-entry.ts +4 -0
  4. package/src/background/background-execution-event-type.ts +9 -0
  5. package/src/background/background-execution-event.ts +9 -0
  6. package/src/background/background-execution-listener.ts +6 -0
  7. package/src/background/background-handler.ts +352 -0
  8. package/src/background/background-http-adapter-handler.ts +166 -0
  9. package/src/background/background-meta-response-internal.ts +5 -0
  10. package/src/background/background-process-handling.ts +6 -0
  11. package/src/background/background-process-log-table-entry.ts +11 -0
  12. package/src/background/background-queue-response-internal.ts +9 -0
  13. package/src/background/background-validator.ts +105 -0
  14. package/src/background/epsilon-background-process-error.ts +110 -0
  15. package/src/background/internal-background-entry.ts +10 -0
  16. package/src/background/manager/abstract-background-manager.ts +120 -0
  17. package/src/background/manager/aws-large-payload-s3-sqs-sns-background-manager.ts +87 -0
  18. package/src/background/manager/aws-sqs-sns-background-manager.ts +201 -0
  19. package/src/background/manager/background-manager-like.ts +44 -0
  20. package/src/background/manager/background-manager.spec.ts +89 -0
  21. package/src/background/manager/single-thread-local-background-manager.ts +58 -0
  22. package/src/background/s3-background-transaction-logger.ts +65 -0
  23. package/src/build/ratchet-epsilon-common-info.ts +19 -0
  24. package/src/built-in/background/echo-processor.ts +17 -0
  25. package/src/built-in/background/log-and-enqueue-echo-processor.ts +14 -0
  26. package/src/built-in/background/log-message-background-error-processor.ts +10 -0
  27. package/src/built-in/background/no-op-processor.ts +12 -0
  28. package/src/built-in/background/retry-processor.ts +51 -0
  29. package/src/built-in/background/sample-delay-processor.ts +15 -0
  30. package/src/built-in/background/sample-input-validated-processor-data.ts +4 -0
  31. package/src/built-in/background/sample-input-validated-processor.ts +14 -0
  32. package/src/built-in/built-in-trace-id-generators.ts +22 -0
  33. package/src/built-in/daemon/daemon-authorizer-function.ts +4 -0
  34. package/src/built-in/daemon/daemon-config.ts +9 -0
  35. package/src/built-in/daemon/daemon-group-selection-function.ts +3 -0
  36. package/src/built-in/daemon/daemon-handler.ts +87 -0
  37. package/src/built-in/daemon/daemon-process-state-list.ts +9 -0
  38. package/src/built-in/http/apollo/apollo-util.ts +43 -0
  39. package/src/built-in/http/apollo/default-epsilon-apollo-context.ts +11 -0
  40. package/src/built-in/http/apollo/epsilon-apollo-context-builder-options.ts +5 -0
  41. package/src/built-in/http/apollo/epsilon-lambda-apollo-context-function-argument.ts +6 -0
  42. package/src/built-in/http/apollo/epsilon-lambda-apollo-options.ts +11 -0
  43. package/src/built-in/http/apollo-filter.ts +151 -0
  44. package/src/built-in/http/built-in-auth-filters.ts +73 -0
  45. package/src/built-in/http/built-in-authorizers.ts +22 -0
  46. package/src/built-in/http/built-in-filters.spec.ts +26 -0
  47. package/src/built-in/http/built-in-filters.ts +300 -0
  48. package/src/built-in/http/built-in-handlers.ts +85 -0
  49. package/src/built-in/http/log-level-manipulation-filter.ts +26 -0
  50. package/src/built-in/http/run-handler-as-filter.spec.ts +67 -0
  51. package/src/built-in/http/run-handler-as-filter.ts +102 -0
  52. package/src/cli/ratchet-cli-handler.ts +23 -0
  53. package/src/cli/run-background-process-from-command-line.ts +32 -0
  54. package/src/config/background/background-aws-config.ts +8 -0
  55. package/src/config/background/background-config.ts +15 -0
  56. package/src/config/background/background-error-processor.ts +5 -0
  57. package/src/config/background/background-processor.ts +14 -0
  58. package/src/config/background/background-transaction-log.ts +9 -0
  59. package/src/config/background/background-transaction-logger.ts +6 -0
  60. package/src/config/cron/abstract-cron-entry.ts +17 -0
  61. package/src/config/cron/cron-background-entry.ts +17 -0
  62. package/src/config/cron/cron-config.ts +10 -0
  63. package/src/config/dynamo-db-config.ts +6 -0
  64. package/src/config/epsilon-config.ts +30 -0
  65. package/src/config/epsilon-lambda-event-handler.ts +12 -0
  66. package/src/config/epsilon-logger-config.ts +23 -0
  67. package/src/config/espilon-server-mode.ts +10 -0
  68. package/src/config/generic-aws-event-handler-function.ts +1 -0
  69. package/src/config/http/authorizer-function.ts +9 -0
  70. package/src/config/http/epsilon-authorization-context.ts +5 -0
  71. package/src/config/http/epsilon-cors-approach.ts +7 -0
  72. package/src/config/http/extended-api-gateway-event.ts +8 -0
  73. package/src/config/http/filter-chain-context.ts +15 -0
  74. package/src/config/http/filter-function.ts +3 -0
  75. package/src/config/http/handler-function.ts +4 -0
  76. package/src/config/http/http-config.ts +27 -0
  77. package/src/config/http/http-processing-config.ts +23 -0
  78. package/src/config/http/mapped-http-processing-config.ts +12 -0
  79. package/src/config/http/null-returned-object-handling.ts +7 -0
  80. package/src/config/inter-api/inter-api-aws-config.ts +5 -0
  81. package/src/config/inter-api/inter-api-config.ts +7 -0
  82. package/src/config/inter-api/inter-api-process-mapping.ts +11 -0
  83. package/src/config/local-server/local-server-event-logging-style.ts +8 -0
  84. package/src/config/local-server/local-server-http-method-handling.ts +7 -0
  85. package/src/config/local-server/local-server-options.ts +12 -0
  86. package/src/config/logging-trace-id-generator.ts +3 -0
  87. package/src/config/no-handlers-found-error.ts +6 -0
  88. package/src/config/open-api/open-api-document-components.ts +4 -0
  89. package/src/config/open-api/open-api-document.ts +7 -0
  90. package/src/config/s3-config.ts +8 -0
  91. package/src/config/sns-config.ts +7 -0
  92. package/src/config/sqs-config.ts +7 -0
  93. package/src/epsilon-build-properties.ts +21 -0
  94. package/src/epsilon-constants.ts +62 -0
  95. package/src/epsilon-global-handler.ts +238 -0
  96. package/src/epsilon-instance.ts +20 -0
  97. package/src/epsilon-logging-extension-processor.ts +19 -0
  98. package/src/http/auth/api-gateway-adapter-authentication-handler.ts +95 -0
  99. package/src/http/auth/auth0-web-token-manipulator.ts +69 -0
  100. package/src/http/auth/basic-auth-token.ts +7 -0
  101. package/src/http/auth/google-web-token-manipulator.spec.ts +15 -0
  102. package/src/http/auth/google-web-token-manipulator.ts +80 -0
  103. package/src/http/auth/jwt-ratchet-local-web-token-manipulator.ts +37 -0
  104. package/src/http/auth/local-web-token-manipulator.spec.ts +34 -0
  105. package/src/http/auth/local-web-token-manipulator.ts +114 -0
  106. package/src/http/auth/web-token-manipulator.ts +9 -0
  107. package/src/http/error/bad-gateway.ts +11 -0
  108. package/src/http/error/bad-request-error.ts +11 -0
  109. package/src/http/error/conflict-error.ts +12 -0
  110. package/src/http/error/forbidden-error.ts +12 -0
  111. package/src/http/error/gateway-timeout.ts +12 -0
  112. package/src/http/error/method-not-allowed-error.ts +12 -0
  113. package/src/http/error/misconfigured-error.ts +12 -0
  114. package/src/http/error/not-found-error.ts +12 -0
  115. package/src/http/error/not-implemented.ts +12 -0
  116. package/src/http/error/request-timeout-error.ts +12 -0
  117. package/src/http/error/service-unavailable.ts +12 -0
  118. package/src/http/error/too-many-requests-error.ts +12 -0
  119. package/src/http/error/unauthorized-error.ts +12 -0
  120. package/src/http/event-util.spec.ts +190 -0
  121. package/src/http/event-util.ts +272 -0
  122. package/src/http/response-util.spec.ts +117 -0
  123. package/src/http/response-util.ts +164 -0
  124. package/src/http/route/epsilon-router.ts +9 -0
  125. package/src/http/route/extended-auth-response-context.ts +7 -0
  126. package/src/http/route/route-and-parse.ts +8 -0
  127. package/src/http/route/route-mapping.ts +21 -0
  128. package/src/http/route/route-validator-config.ts +5 -0
  129. package/src/http/route/router-util.spec.ts +33 -0
  130. package/src/http/route/router-util.ts +314 -0
  131. package/src/http/web-handler.spec.ts +99 -0
  132. package/src/http/web-handler.ts +157 -0
  133. package/src/http/web-v2-handler.ts +34 -0
  134. package/src/inter-api/inter-api-entry.ts +8 -0
  135. package/src/inter-api/inter-api-util.spec.ts +77 -0
  136. package/src/inter-api/inter-api-util.ts +71 -0
  137. package/src/inter-api-manager.ts +75 -0
  138. package/src/lambda-event-handler/cron-epsilon-lambda-event-handler.spec.ts +130 -0
  139. package/src/lambda-event-handler/cron-epsilon-lambda-event-handler.ts +132 -0
  140. package/src/lambda-event-handler/dynamo-epsilon-lambda-event-handler.ts +42 -0
  141. package/src/lambda-event-handler/generic-sns-epsilon-lambda-event-handler.ts +38 -0
  142. package/src/lambda-event-handler/generic-sqs-epsilon-lambda-event-handler.ts +43 -0
  143. package/src/lambda-event-handler/inter-api-epsilon-lambda-event-handler.ts +33 -0
  144. package/src/lambda-event-handler/s3-epsilon-lambda-event-handler.ts +50 -0
  145. package/src/local-container-server.ts +128 -0
  146. package/src/local-server.spec.ts +16 -0
  147. package/src/local-server.ts +426 -0
  148. package/src/open-api-util/open-api-doc-modifications.ts +9 -0
  149. package/src/open-api-util/open-api-doc-modifier.spec.ts +22 -0
  150. package/src/open-api-util/open-api-doc-modifier.ts +90 -0
  151. package/src/open-api-util/yaml-combiner.spec.ts +26 -0
  152. package/src/open-api-util/yaml-combiner.ts +35 -0
  153. package/src/sample/sample-server-components-with-apollo.ts +87 -0
  154. package/src/sample/sample-server-components.ts +183 -0
  155. package/src/sample/sample-server-static-files.ts +614 -0
  156. package/src/sample/test-error-server.ts +140 -0
  157. package/src/util/aws-util.ts +89 -0
  158. package/src/util/context-global-data.ts +13 -0
  159. package/src/util/context-util.ts +156 -0
  160. package/src/util/cron-util.spec.ts +190 -0
  161. package/src/util/cron-util.ts +86 -0
  162. package/src/util/epsilon-config-parser.ts +90 -0
  163. package/src/util/epsilon-server-util.spec.ts +18 -0
  164. package/src/util/epsilon-server-util.ts +16 -0
@@ -0,0 +1,26 @@
1
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
2
+ import { FilterChainContext } from '../../config/http/filter-chain-context.js';
3
+ import { LoggerLevelName } from '@bitblit/ratchet-common/logger/logger-level-name';
4
+
5
+ /**
6
+ * This only works because Node is single threaded...
7
+ */
8
+ export class LogLevelManipulationFilter {
9
+ private static LOG_LEVEL_BEFORE_CHANGE: LoggerLevelName = null;
10
+
11
+ // TODO: Implement me!!
12
+ public static async setLogLevelForTransaction(_fCtx: FilterChainContext): Promise<boolean> {
13
+ LogLevelManipulationFilter.LOG_LEVEL_BEFORE_CHANGE = Logger.getLevel();
14
+ // TODO: Set me too! Logger.setTracePrefix(null);
15
+ return true;
16
+ }
17
+
18
+ public static async clearLogLevelForTransaction(_fCtx: FilterChainContext): Promise<boolean> {
19
+ if (LogLevelManipulationFilter.LOG_LEVEL_BEFORE_CHANGE) {
20
+ Logger.setLevel(LogLevelManipulationFilter.LOG_LEVEL_BEFORE_CHANGE);
21
+ LogLevelManipulationFilter.LOG_LEVEL_BEFORE_CHANGE = null;
22
+ Logger.updateTracePrefix(null);
23
+ }
24
+ return true;
25
+ }
26
+ }
@@ -0,0 +1,67 @@
1
+ import { Context, ProxyResult } from 'aws-lambda';
2
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
3
+ import { EpsilonGlobalHandler } from '../../epsilon-global-handler.js';
4
+ import { SampleServerComponents } from '../../sample/sample-server-components.js';
5
+ import { RunHandlerAsFilter } from './run-handler-as-filter.js';
6
+ import { ExtendedAPIGatewayEvent } from '../../config/http/extended-api-gateway-event.js';
7
+ import { RouterUtil } from '../../http/route/router-util.js';
8
+ import { describe, expect, test } from 'vitest';
9
+ import { RouteAndParse } from '../../http/route/route-and-parse';
10
+
11
+ describe('#routerUtilApplyOpenApiDoc', function () {
12
+ test('should find the most specific route and the least specific', async () => {
13
+ const inst: EpsilonGlobalHandler = await SampleServerComponents.createSampleEpsilonGlobalHandler('jest-most specific route');
14
+
15
+ expect(inst.epsilon.modelValidator).toBeTruthy();
16
+
17
+ // TODO: move this to its own test
18
+ const evtFixed: ExtendedAPIGatewayEvent = {
19
+ httpMethod: 'get',
20
+ path: '/v0/multi/fixed',
21
+ requestContext: {
22
+ stage: 'v0',
23
+ },
24
+ queryStringParameters: {},
25
+ } as ExtendedAPIGatewayEvent;
26
+
27
+ const evtVar: ExtendedAPIGatewayEvent = {
28
+ httpMethod: 'get',
29
+ path: '/v0/multi/xyz',
30
+ requestContext: {
31
+ stage: 'v0',
32
+ },
33
+ queryStringParameters: {},
34
+ } as ExtendedAPIGatewayEvent;
35
+
36
+ const findFixedRP: RouteAndParse = await inst.epsilon.webHandler.findBestMatchingRoute(evtFixed);
37
+ const findVariableRP: RouteAndParse = await inst.epsilon.webHandler.findBestMatchingRoute(evtVar);
38
+ const findFixed: ProxyResult = await RunHandlerAsFilter.findHandler(findFixedRP, evtFixed, {} as Context, false);
39
+ const findVariable: ProxyResult = await RunHandlerAsFilter.findHandler(findVariableRP, evtVar, {} as Context, false);
40
+ expect(findFixed).toBeTruthy();
41
+ expect(findFixed['flag']).toEqual('fixed');
42
+ expect(findVariable).toBeTruthy();
43
+ expect(findVariable['flag']).toEqual('variable');
44
+ Logger.info('done');
45
+ });
46
+
47
+ test('should reformat a path to match the other library', function () {
48
+ const inString: string = '/meta/item/{itemId}';
49
+ const outString: string = RouterUtil.openApiPathToRouteParserPath(inString);
50
+ expect(outString).toEqual('/meta/item/:itemId');
51
+ });
52
+
53
+ test('should redact authorization values from events for logging', function () {
54
+ const inputEvent: any = {
55
+ authorization: {
56
+ raw: 'secret-access-token-here',
57
+ },
58
+ headers: {
59
+ authorization: 'Bearer secret-access-token-here',
60
+ },
61
+ };
62
+ // @ts-expect-error private method
63
+ const logEventObj: any = JSON.parse(RunHandlerAsFilter.eventToStringForLog(inputEvent));
64
+ expect(logEventObj.authorization.raw).toEqual(RunHandlerAsFilter.redact(inputEvent.authorization.raw));
65
+ expect(logEventObj.headers.authorization).toEqual(RunHandlerAsFilter.redact(logEventObj.headers.authorization));
66
+ });
67
+ });
@@ -0,0 +1,102 @@
1
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
2
+ import { PromiseRatchet } from '@bitblit/ratchet-common/lang/promise-ratchet';
3
+ import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
4
+ import { TimeoutToken } from '@bitblit/ratchet-common/lang/timeout-token';
5
+ import { RestfulApiHttpError } from '@bitblit/ratchet-common/network/restful-api-http-error';
6
+ import { Context } from 'aws-lambda';
7
+ import { ExtendedAPIGatewayEvent } from '../../config/http/extended-api-gateway-event.js';
8
+ import { RequestTimeoutError } from '../../http/error/request-timeout-error.js';
9
+ import { ResponseUtil } from '../../http/response-util.js';
10
+ import { NotFoundError } from '../../http/error/not-found-error.js';
11
+ import { NullReturnedObjectHandling } from '../../config/http/null-returned-object-handling.js';
12
+ import { FilterFunction } from '../../config/http/filter-function.js';
13
+ import { FilterChainContext } from '../../config/http/filter-chain-context.js';
14
+ import { RouteAndParse } from '../../http/route/route-and-parse.js';
15
+
16
+ export class RunHandlerAsFilter {
17
+ public static async runHandler(fCtx: FilterChainContext, rm: RouteAndParse): Promise<boolean> {
18
+ // Check for continue
19
+ // Run the controller
20
+ const handler: Promise<any> = RunHandlerAsFilter.findHandler(rm, fCtx.event, fCtx.context);
21
+ Logger.debug('Processing event with epsilon: %j', RunHandlerAsFilter.eventToStringForLog(fCtx.event));
22
+ let tmp: any = await handler;
23
+ if (TimeoutToken.isTimeoutToken(tmp)) {
24
+ (tmp as TimeoutToken).writeToLog();
25
+ throw new RequestTimeoutError('Timed out');
26
+ }
27
+ Logger.debug('Initial return value : %j', tmp);
28
+ tmp = RunHandlerAsFilter.applyNullReturnedObjectHandling(tmp, rm.mapping.metaProcessingConfig.nullReturnedObjectHandling);
29
+ fCtx.rawResult = tmp;
30
+ fCtx.result = ResponseUtil.coerceToProxyResult(tmp);
31
+
32
+ return true;
33
+ }
34
+
35
+ public static applyNullReturnedObjectHandling(result: any, handling: NullReturnedObjectHandling): any {
36
+ let rval: any = result;
37
+ if (result === null || result === undefined) {
38
+ if (handling === NullReturnedObjectHandling.Error) {
39
+ Logger.error('Null object returned and Error specified, throwing 500');
40
+ throw new RestfulApiHttpError('Null object').withHttpStatusCode(500);
41
+ } else if (handling === NullReturnedObjectHandling.Return404NotFoundResponse) {
42
+ throw new NotFoundError('Resource not found');
43
+ } else if (handling === NullReturnedObjectHandling.ConvertToEmptyString) {
44
+ Logger.warn('Null object returned from handler and convert not specified, converting to empty string');
45
+ rval = '';
46
+ } else {
47
+ throw new RestfulApiHttpError('Cant happen - failed enum check').withHttpStatusCode(500);
48
+ }
49
+ }
50
+ return rval;
51
+ }
52
+
53
+ public static async findHandler(
54
+ rm: RouteAndParse,
55
+ event: ExtendedAPIGatewayEvent,
56
+ context: Context,
57
+ add404OnMissing: boolean = true,
58
+ ): Promise<any> {
59
+ let rval: Promise<any> = null;
60
+ // Execute
61
+ if (rm) {
62
+ // We extend with the parsed params here in case we are using the AWS any proxy
63
+ event.pathParameters = Object.assign({}, event.pathParameters, rm.parsed);
64
+
65
+ rval = PromiseRatchet.timeout(
66
+ rm.mapping.function(event, context),
67
+ 'Timed out after ' +
68
+ rm.mapping.metaProcessingConfig.timeoutMS +
69
+ ' ms. Request was ' +
70
+ RunHandlerAsFilter.eventToStringForLog(event),
71
+ rm.mapping.metaProcessingConfig.timeoutMS,
72
+ );
73
+ } else if (add404OnMissing) {
74
+ throw new NotFoundError('No such endpoint');
75
+ }
76
+ return rval;
77
+ }
78
+
79
+ public static addRunHandlerAsFilterToList(filters: FilterFunction[], rm: RouteAndParse): void {
80
+ if (filters) {
81
+ filters.push((fCtx) => RunHandlerAsFilter.runHandler(fCtx, rm));
82
+ }
83
+ }
84
+
85
+ private static eventToStringForLog(event: any): string {
86
+ const eventToLog = structuredClone(event);
87
+
88
+ if (eventToLog?.authorization?.raw) {
89
+ eventToLog.authorization.raw = RunHandlerAsFilter.redact(eventToLog.authorization.raw);
90
+ }
91
+ if (eventToLog?.headers?.authorization) {
92
+ eventToLog.headers.authorization = RunHandlerAsFilter.redact(eventToLog.headers.authorization);
93
+ }
94
+
95
+ return JSON.stringify(eventToLog);
96
+ }
97
+
98
+ public static redact(input: string): string {
99
+ const rval: string = input ? StringRatchet.obscure(input, 1, 1) : input;
100
+ return rval;
101
+ }
102
+ }
@@ -0,0 +1,23 @@
1
+ import { AbstractRatchetCliHandler } from '@bitblit/ratchet-node-only/cli/abstract-ratchet-cli-handler';
2
+ import { BuildInformation } from '@bitblit/ratchet-common/build/build-information';
3
+ import { RunBackgroundProcessFromCommandLine } from './run-background-process-from-command-line.js';
4
+ import { TestErrorServer } from '../sample/test-error-server.js';
5
+ import { LocalContainerServer } from '../local-container-server.js';
6
+ import { RatchetEpsilonCommonInfo } from '../build/ratchet-epsilon-common-info.js';
7
+ import { LocalServer } from '../local-server.js';
8
+
9
+ export class RatchetCliHandler extends AbstractRatchetCliHandler {
10
+ fetchHandlerMap(): Record<string, any> {
11
+ return {
12
+ 'run-background-process': RunBackgroundProcessFromCommandLine.runFromCliArgs,
13
+ 'run-test-error-server': TestErrorServer.runFromCliArgs,
14
+ 'run-local-container-server': LocalContainerServer.runFromCliArgs,
15
+ 'run-sample-local-server': LocalServer.runSampleLocalServerFromCliArgs,
16
+ 'run-sample-local-batch-server': LocalServer.runSampleLocalServerFromCliArgs,
17
+ };
18
+ }
19
+
20
+ fetchVersionInfo(): BuildInformation {
21
+ return RatchetEpsilonCommonInfo.buildInformation();
22
+ }
23
+ }
@@ -0,0 +1,32 @@
1
+ import { EpsilonGlobalHandler } from '../epsilon-global-handler.js';
2
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
3
+ import { BooleanRatchet } from '@bitblit/ratchet-common/lang/boolean-ratchet';
4
+
5
+ /**
6
+ * IMPORTANT NOTE
7
+ * This file is part of the bootstrapper to bridge from the Epsilon Background processor
8
+ * to the AWS Batch processing Docker setup.
9
+ *
10
+ * DO NOT MESS WITH IT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING.
11
+ *
12
+ * You are likely to mess it up otherwise.
13
+ */
14
+ export class RunBackgroundProcessFromCommandLine {
15
+ public static async runFromCliArgs(args: string[]): Promise<void> {
16
+ if (args.length > 1) {
17
+ const procName: string = args[0];
18
+ const dryRun: boolean = args.length > 1 && BooleanRatchet.parseBool(args[1]);
19
+ const data: any = args.length > 2 ? JSON.parse(args[2]) : null;
20
+ const meta: any = args.length > 3 ? JSON.parse(args[3]) : null;
21
+ const epsilon: EpsilonGlobalHandler = null; // TODO: How to pass this in?
22
+
23
+ if (dryRun) {
24
+ Logger.info('Dry-Run, would have sent : %s %j %j', procName, data, meta);
25
+ } else {
26
+ await epsilon.processSingleBackgroundByParts(procName, data, meta);
27
+ }
28
+ } else {
29
+ console.log('Usage : run-background-process {processName} {dryRun true/false} {dataJson} {metaJson}');
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,8 @@
1
+ export interface BackgroundAwsConfig {
2
+ queueUrl: string;
3
+ notificationArn: string;
4
+ sendNotificationOnBackgroundError?: boolean;
5
+ sendNotificationOnBackgroundValidationFailure?: boolean;
6
+ // If either of the above are set to true, notifications will be sent here
7
+ backgroundProcessFailureSnsArn?: string;
8
+ }
@@ -0,0 +1,15 @@
1
+ import { BackgroundProcessor } from './background-processor.js';
2
+ import { BackgroundErrorProcessor } from './background-error-processor.js';
3
+ import { BackgroundExecutionListener } from '../../background/background-execution-listener.js';
4
+ import { BackgroundTransactionLogger } from './background-transaction-logger.js';
5
+
6
+ export interface BackgroundConfig {
7
+ transactionLogger?: BackgroundTransactionLogger;
8
+ errorProcessor?: BackgroundErrorProcessor;
9
+ httpStatusEndpoint?: string;
10
+ httpMetaEndpoint?: string;
11
+ httpSubmissionPath: string;
12
+ implyTypeFromPathSuffix: boolean;
13
+ processors: BackgroundProcessor<any>[];
14
+ executionListeners?: BackgroundExecutionListener<any>[];
15
+ }
@@ -0,0 +1,5 @@
1
+ import { InternalBackgroundEntry } from '../../background/internal-background-entry.js';
2
+
3
+ export interface BackgroundErrorProcessor {
4
+ handleError(submission: InternalBackgroundEntry<any>, error: Error): Promise<void>;
5
+ }
@@ -0,0 +1,14 @@
1
+ import { BackgroundManagerLike } from '../../background/manager/background-manager-like.js';
2
+
3
+ export interface BackgroundProcessor<T> {
4
+ typeName: string; // The name for this processor
5
+
6
+ // If set, data will be validated against this before submitted
7
+ // Yes, if using explicitly pathed and configured routes it'll get
8
+ // validated twice... the price I pay to support both pathed and
9
+ // single-post background support
10
+ dataSchemaName?: string;
11
+
12
+ // Allowed to return since it may be logged
13
+ handleEvent(data: T, mgr: BackgroundManagerLike): Promise<any>;
14
+ }
@@ -0,0 +1,9 @@
1
+ import { InternalBackgroundEntry } from '../../background/internal-background-entry.js';
2
+
3
+ export interface BackgroundTransactionLog {
4
+ request: InternalBackgroundEntry<any>;
5
+ running: boolean;
6
+ runtimeMS?: number;
7
+ result?: any;
8
+ error?: any;
9
+ }
@@ -0,0 +1,6 @@
1
+ import { BackgroundTransactionLog } from './background-transaction-log.js';
2
+
3
+ export interface BackgroundTransactionLogger {
4
+ logTransaction(txLog: BackgroundTransactionLog): Promise<void>;
5
+ readTransactionLog(txGuid: string): Promise<BackgroundTransactionLog>;
6
+ }
@@ -0,0 +1,17 @@
1
+ export interface AbstractCronEntry {
2
+ name?: string; // Just used for labeling in logs
3
+ eventFilter?: RegExp; // If set, matches against the schedule name from CloudWatch events
4
+ minuteFilter?: number[]; // If set and length>0, only minutes matching this array will trigger 0-59
5
+ hourFilter?: number[]; // If set and length>0, only hours matching this array will trigger (as defined by the timezone in cron config) 0-23
6
+ dayOfWeekFilter?: number[]; // If set and length>0, only days of week matching this array will trigger (as defined by the timezone in cron config) 0-6
7
+ dayOfMonthFilter?: number[]; // If set and length>0, only days of month matching this array will trigger (as defined by the timezone in cron config) 1-31
8
+ monthOfYearFilter?: number[]; // If set and length>0, only months of year matching this array will trigger (as defined by the timezone in cron config) 1-12
9
+ contextMatchFilter?: RegExp; // If set, the context must match this filter
10
+ contextNoMatchFilter?: RegExp; // If set, the context must NOT match this filter
11
+ // If both match and nomatch are set, the noMatch dominates over match
12
+
13
+ // If set, this will be used instead of the timezone in cron-config
14
+ // This override is to allow you to use a simple timezone like PT for most, while
15
+ // still scheduling certain things to run in UTC (Not DST switching)
16
+ overrideTimezone?: string;
17
+ }
@@ -0,0 +1,17 @@
1
+ import { AbstractCronEntry } from './abstract-cron-entry.js';
2
+
3
+ /**
4
+ of 2020-04-30, my recommendation is that CRON should be used ONLY to fire
5
+ * off Background tasks (this makes your CRON stuff easier to debug since it can
6
+ * be called from anywhere, not just CRON, and also makes sure that your processor
7
+ * gets the full 15 minutes if necessary)
8
+ *
9
+ * This simplifies doing that - you can basically just configure the set of
10
+ * constraints, and the background task to fire off if the constraints match.
11
+ */
12
+ export interface CronBackgroundEntry extends AbstractCronEntry {
13
+ backgroundTaskType: string;
14
+ fireImmediate: boolean;
15
+
16
+ data?: any;
17
+ }
@@ -0,0 +1,10 @@
1
+ import { CronBackgroundEntry } from './cron-background-entry.js';
2
+
3
+ export interface CronConfig {
4
+ // Timezone used to evaluate date and time (defaults to etc/gmt)
5
+ timezone: string;
6
+ // Define the current context of this cron executor (typically used to switch prod/qa/dev, etc)
7
+ context: string;
8
+
9
+ entries: CronBackgroundEntry[];
10
+ }
@@ -0,0 +1,6 @@
1
+ import { GenericAwsEventHandlerFunction } from './generic-aws-event-handler-function.js';
2
+ import { DynamoDBStreamEvent } from 'aws-lambda';
3
+
4
+ export interface DynamoDbConfig {
5
+ handlers: Map<string, GenericAwsEventHandlerFunction<DynamoDBStreamEvent>>;
6
+ }
@@ -0,0 +1,30 @@
1
+ import { HttpConfig } from './http/http-config.js';
2
+ import { BackgroundConfig } from './background/background-config.js';
3
+ import { CronConfig } from './cron/cron-config.js';
4
+ import { DynamoDbConfig } from './dynamo-db-config.js';
5
+ import { S3Config } from './s3-config.js';
6
+ import { SnsConfig } from './sns-config.js';
7
+ import { EpsilonLoggerConfig } from './epsilon-logger-config.js';
8
+ import { InterApiConfig } from './inter-api/inter-api-config.js';
9
+ import { SqsConfig } from './sqs-config.js';
10
+
11
+ export interface EpsilonConfig {
12
+ label?: string;
13
+ // If disabled, last resort timeout will instead roll to lambda (not recommended)
14
+ disableLastResortTimeout?: boolean;
15
+ throwErrorIfNoSuitableEventHandlers?: boolean;
16
+
17
+ openApiYamlString: string;
18
+ httpConfig?: HttpConfig;
19
+
20
+ backgroundConfig?: BackgroundConfig;
21
+ interApiConfig?: InterApiConfig;
22
+
23
+ cron?: CronConfig;
24
+ dynamoDb?: DynamoDbConfig;
25
+ s3?: S3Config;
26
+ sns?: SnsConfig;
27
+ sqs?: SqsConfig;
28
+
29
+ loggerConfig?: EpsilonLoggerConfig;
30
+ }
@@ -0,0 +1,12 @@
1
+ import { Context, ProxyResult } from 'aws-lambda';
2
+
3
+ export interface EpsilonLambdaEventHandler<T> {
4
+ handlesEvent(evt: any): boolean;
5
+ extractLabel(evt: T, context: Context): string;
6
+ processEvent(evt: T, context: Context): Promise<ProxyResult>;
7
+ // If you define a processUncaughtError function, then any errors that are thrown while running this handler,
8
+ // and not caught by the handler itself, will be processed by this. Usually you wouldn't implement this
9
+ // function (since you would want the default 'catch/log/return 500' logic, but if you want retries,
10
+ // (eg, for Dynamo, Kinesis, etc) you can override this to allow the error to slip outside Epsilon
11
+ processUncaughtError?(evt: T, context: Context, err: Error): Promise<ProxyResult>;
12
+ }
@@ -0,0 +1,23 @@
1
+ import { LoggerLevelName } from '@bitblit/ratchet-common/logger/logger-level-name';
2
+ import { LogMessageFormatType } from '@bitblit/ratchet-common/logger/log-message-format-type';
3
+ import { LoggingTraceIdGenerator } from './logging-trace-id-generator.js';
4
+
5
+ export interface EpsilonLoggerConfig {
6
+ // If set, the logger will be set to this instead of the default
7
+ envParamLogLevelName?: string;
8
+ // If set, and the user provides the query param, the logger level will be set to this
9
+ queryParamLogLevelName?: string;
10
+ // If set, and the user provides the query param, the logger will use this common prefix for the transaction
11
+ queryParamTracePrefixName?: string;
12
+ // If set, this will be used to generate trace ids when none are provided - otherwise, defaults to the aws request id
13
+ // If present, and a guid if not
14
+ traceIdGenerator?: LoggingTraceIdGenerator;
15
+ // Defaults to structured json - this is here so you can switch if you are running locally
16
+ logMessageFormatType?: LogMessageFormatType;
17
+ // Defaults to x-trace-id if not set
18
+ traceHeaderName?: string;
19
+ // Defaults to x-trace-depth if not set
20
+ traceDepthHeaderName?: string;
21
+ // Epsilon start/end messages are logged at this level (info by default)
22
+ epsilonStartEndMessageLogLevel?: LoggerLevelName;
23
+ }
@@ -0,0 +1,10 @@
1
+ // NOTE: This is a psuedo-enum to fix some issues with Typescript enums. See: https://exploringjs.com/tackling-ts/ch_enum-alternatives.html for details
2
+ export const EpsilonServerMode = {
3
+ Production: 'Production',
4
+ Development: 'Development',
5
+ QA: 'QA',
6
+ Red: 'Red',
7
+ Blue: 'Blue',
8
+ Green: 'Green',
9
+ };
10
+ export type EpsilonServerMode = (typeof EpsilonServerMode)[keyof typeof EpsilonServerMode];
@@ -0,0 +1 @@
1
+ export type GenericAwsEventHandlerFunction<T> = (event: T) => Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { RouteMapping } from '../../http/route/route-mapping.js';
2
+ import { EpsilonAuthorizationContext } from './epsilon-authorization-context.js';
3
+ import { ExtendedAPIGatewayEvent } from './extended-api-gateway-event.js';
4
+
5
+ export type AuthorizerFunction = (
6
+ authData: EpsilonAuthorizationContext<any>,
7
+ event?: ExtendedAPIGatewayEvent,
8
+ route?: RouteMapping,
9
+ ) => Promise<boolean>;
@@ -0,0 +1,5 @@
1
+ export interface EpsilonAuthorizationContext<T> {
2
+ raw: string;
3
+ auth: T;
4
+ error: string;
5
+ }
@@ -0,0 +1,7 @@
1
+ // NOTE: This is a psuedo-enum to fix some issues with Typescript enums. See: https://exploringjs.com/tackling-ts/ch_enum-alternatives.html for details
2
+ export const EpsilonCorsApproach = {
3
+ None: 'None',
4
+ All: 'All',
5
+ Reflective: 'Reflective',
6
+ };
7
+ export type EpsilonCorsApproach = (typeof EpsilonCorsApproach)[keyof typeof EpsilonCorsApproach];
@@ -0,0 +1,8 @@
1
+ import { APIGatewayEvent } from 'aws-lambda';
2
+ import { EpsilonAuthorizationContext } from './epsilon-authorization-context.js';
3
+
4
+ export interface ExtendedAPIGatewayEvent extends APIGatewayEvent {
5
+ parsedBody: any;
6
+ authorization: EpsilonAuthorizationContext<any>;
7
+ convertedFromV2Event: boolean;
8
+ }
@@ -0,0 +1,15 @@
1
+ import { Context, ProxyResult } from 'aws-lambda';
2
+ import { ExtendedAPIGatewayEvent } from './extended-api-gateway-event.js';
3
+ import { ModelValidator } from '@bitblit/ratchet-misc/model-validator/model-validator';
4
+ import { AuthorizerFunction } from './authorizer-function.js';
5
+ import { RouteAndParse } from '../../http/route/route-and-parse';
6
+
7
+ export interface FilterChainContext {
8
+ event: ExtendedAPIGatewayEvent;
9
+ context: Context;
10
+ rawResult: any; // Result before coercion to a proxyResult
11
+ result: ProxyResult;
12
+ routeAndParse: RouteAndParse;
13
+ modelValidator: ModelValidator;
14
+ authenticators: Map<string, AuthorizerFunction>;
15
+ }
@@ -0,0 +1,3 @@
1
+ import { FilterChainContext } from './filter-chain-context.js';
2
+
3
+ export type FilterFunction = (fCtx: FilterChainContext) => Promise<boolean>;
@@ -0,0 +1,4 @@
1
+ import { Context } from 'aws-lambda';
2
+ import { ExtendedAPIGatewayEvent } from './extended-api-gateway-event.js';
3
+
4
+ export type HandlerFunction<T> = (event: ExtendedAPIGatewayEvent, context?: Context) => Promise<T>;
@@ -0,0 +1,27 @@
1
+ import { HandlerFunction } from './handler-function.js';
2
+ import { AuthorizerFunction } from './authorizer-function.js';
3
+ import { HttpProcessingConfig } from './http-processing-config.js';
4
+ import { ModelValidator } from '@bitblit/ratchet-misc/model-validator/model-validator';
5
+ import { MappedHttpProcessingConfig } from './mapped-http-processing-config.js';
6
+
7
+ export interface HttpConfig {
8
+ // This is used for meta handling for any route not overridden by overrideMetaHandling
9
+ defaultMetaHandling: HttpProcessingConfig;
10
+ // Allows setting meta handling for any specific routes
11
+ // These are evaluated IN ORDER, to allow progressively less specific configuration
12
+ overrideMetaHandling?: MappedHttpProcessingConfig[];
13
+ // Maps routes to handlers
14
+ handlers: Map<string, HandlerFunction<any>>;
15
+ // Maps names to authorization functions
16
+ authorizers?: Map<string, AuthorizerFunction>;
17
+ // If set, paths matching the key will be dereferenced to paths on the server matching the value - use with care
18
+ // TODO: Implement
19
+ staticContentRoutes?: Record<string, string>;
20
+ // Should typically be your stage name, but can be different in weird cases like custom name map
21
+ // These will be matched case insensitive
22
+ prefixesToStripBeforeRouteMatch?: string[];
23
+ // If set, the system will use this model validator instead of the OpenAPI one (Uncommon)
24
+ overrideModelValidator?: ModelValidator;
25
+ // These paths are expected to be handled by a filter, and therefore should not cause a parse failure
26
+ filterHandledRouteMatches?: string[];
27
+ }
@@ -0,0 +1,23 @@
1
+ import { NullReturnedObjectHandling } from './null-returned-object-handling.js';
2
+ import { FilterFunction } from './filter-function.js';
3
+
4
+ export interface HttpProcessingConfig {
5
+ // If set, used in logging to help debugging
6
+ configName?: string;
7
+ // If set, matching routes will timeout after this amount of time (with a 50x error)
8
+ timeoutMS: number;
9
+ // Mainly here so that I can define authorizers that aren't viewable in the public doc
10
+ overrideAuthorizerName?: string;
11
+ // Filters that run before the handler function (eg validation, authorization, authentication)
12
+ preFilters?: FilterFunction[];
13
+ // Filters that run after the handler function runs successfully (eg, compression, CORS)
14
+ postFilters?: FilterFunction[];
15
+ // Filters that run in case an error is thrown (eg, making 500's safe for public consumption, adding CORS headers)
16
+ errorFilters?: FilterFunction[];
17
+ // CAW: Defines what should be done if a handler function returns null
18
+ // Handler functions should NOT return null - API Gateway/ALB won't accept it. But sometimes they do, so
19
+ // Epsilon can cleanup here. The reason I have this in here, and not as a filter, is because a single piece
20
+ // of code (run-handler-as-filter) both runs the handler, and converts its result into a proxy object, which
21
+ // I don't want to break apart, but this has to happen between those 2 steps.
22
+ nullReturnedObjectHandling?: NullReturnedObjectHandling;
23
+ }
@@ -0,0 +1,12 @@
1
+ import { HttpProcessingConfig } from './http-processing-config.js';
2
+
3
+ export interface MappedHttpProcessingConfig {
4
+ // If set and nonempty, only verbs in this list will match
5
+ methods?: string[];
6
+ // Must be set, only paths matching this regex will match
7
+ pathRegex: string;
8
+ // If true, paths NOT matching the regex are used instead of paths matching
9
+ invertPathMatching?: boolean;
10
+ // Config to use
11
+ config: HttpProcessingConfig;
12
+ }
@@ -0,0 +1,7 @@
1
+ // NOTE: This is a psuedo-enum to fix some issues with Typescript enums. See: https://exploringjs.com/tackling-ts/ch_enum-alternatives.html for details
2
+ export const NullReturnedObjectHandling = {
3
+ Error: 'Error',
4
+ ConvertToEmptyString: 'ConvertToEmptyString',
5
+ Return404NotFoundResponse: 'Return404NotFoundResponse',
6
+ };
7
+ export type NullReturnedObjectHandling = (typeof NullReturnedObjectHandling)[keyof typeof NullReturnedObjectHandling];
@@ -0,0 +1,5 @@
1
+ export interface InterApiAwsConfig {
2
+ localMode: boolean;
3
+ source: string; // used for publishing only
4
+ snsArn: string;
5
+ }
@@ -0,0 +1,7 @@
1
+ import { InterApiAwsConfig } from './inter-api-aws-config.js';
2
+ import { InterApiProcessMapping } from './inter-api-process-mapping.js';
3
+
4
+ export interface InterApiConfig {
5
+ aws: InterApiAwsConfig;
6
+ processMappings: InterApiProcessMapping[];
7
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * When an event matching the source and type is received, the listed background types will be
3
+ * enqueued with the data from the inter-api block being treated as the data block of the background
4
+ * task
5
+ */
6
+ export interface InterApiProcessMapping {
7
+ sourceRegex: string;
8
+ typeRegex: string;
9
+ disabled: boolean;
10
+ backgroundProcessTypes: string[];
11
+ }
@@ -0,0 +1,8 @@
1
+ // NOTE: This is a psuedo-enum to fix some issues with Typescript enums. See: https://exploringjs.com/tackling-ts/ch_enum-alternatives.html for details
2
+ export const LocalServerEventLoggingStyle = {
3
+ Full: 'Full', // Log the full event to output
4
+ FullWithBase64Decode: 'FullWithBase64Decode', // Log the full event and decode any base64 bodies
5
+ Summary: 'Summary', // Just log a summary to output
6
+ None: 'None', // Do not log events
7
+ };
8
+ export type LocalServerEventLoggingStyle = (typeof LocalServerEventLoggingStyle)[keyof typeof LocalServerEventLoggingStyle];