@vyriy/handler 0.7.8 → 0.8.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.
Files changed (168) hide show
  1. package/README.md +375 -253
  2. package/api/api.d.ts +10 -0
  3. package/api/api.js +19 -0
  4. package/api/http/compose/compose.d.ts +2 -0
  5. package/api/http/compose/compose.js +1 -0
  6. package/api/http/compose/index.d.ts +1 -0
  7. package/api/http/compose/index.js +1 -0
  8. package/api/http/factory/factory.d.ts +2 -0
  9. package/api/http/factory/factory.js +1 -0
  10. package/api/http/factory/index.d.ts +1 -0
  11. package/api/http/factory/index.js +1 -0
  12. package/api/http/http.d.ts +3 -0
  13. package/api/http/http.js +14 -0
  14. package/api/http/index.d.ts +3 -0
  15. package/api/http/index.js +2 -0
  16. package/api/http/types.d.ts +18 -0
  17. package/api/http/wrappers/cors.d.ts +1 -0
  18. package/api/http/wrappers/cors.js +9 -0
  19. package/api/http/wrappers/error.d.ts +3 -0
  20. package/api/http/wrappers/error.js +21 -0
  21. package/api/http/wrappers/headers.d.ts +1 -0
  22. package/api/http/wrappers/headers.js +8 -0
  23. package/api/http/wrappers/healthcheck.d.ts +5 -0
  24. package/api/http/wrappers/healthcheck.js +19 -0
  25. package/api/http/wrappers/index.d.ts +5 -0
  26. package/api/http/wrappers/index.js +5 -0
  27. package/api/http/wrappers/logger.d.ts +2 -0
  28. package/api/http/wrappers/logger.js +28 -0
  29. package/api/index.d.ts +3 -0
  30. package/api/index.js +2 -0
  31. package/api/stream/compose/compose.d.ts +2 -0
  32. package/api/stream/compose/compose.js +1 -0
  33. package/api/stream/compose/index.d.ts +1 -0
  34. package/api/stream/compose/index.js +1 -0
  35. package/api/stream/factory/factory.d.ts +5 -0
  36. package/api/stream/factory/factory.js +3 -0
  37. package/api/stream/factory/index.d.ts +1 -0
  38. package/api/stream/factory/index.js +1 -0
  39. package/api/stream/index.d.ts +3 -0
  40. package/api/stream/index.js +2 -0
  41. package/api/stream/stream.d.ts +3 -0
  42. package/api/stream/stream.js +13 -0
  43. package/api/stream/types.d.ts +36 -0
  44. package/api/stream/wrappers/chaos.d.ts +2 -0
  45. package/{wrapper → api/stream/wrappers}/chaos.js +1 -12
  46. package/api/stream/wrappers/context.d.ts +1 -0
  47. package/api/stream/wrappers/context.js +6 -0
  48. package/api/stream/wrappers/cors.d.ts +1 -0
  49. package/api/stream/wrappers/cors.js +10 -0
  50. package/api/stream/wrappers/error.d.ts +3 -0
  51. package/api/stream/wrappers/error.js +25 -0
  52. package/api/stream/wrappers/headers.d.ts +1 -0
  53. package/api/stream/wrappers/headers.js +7 -0
  54. package/api/stream/wrappers/healthcheck.d.ts +2 -0
  55. package/api/stream/wrappers/healthcheck.js +27 -0
  56. package/api/stream/wrappers/index.d.ts +10 -0
  57. package/api/stream/wrappers/index.js +10 -0
  58. package/api/stream/wrappers/logger.d.ts +2 -0
  59. package/api/stream/wrappers/logger.js +20 -0
  60. package/api/stream/wrappers/smoke.d.ts +2 -0
  61. package/{wrapper → api/stream/wrappers}/smoke.js +1 -5
  62. package/api/stream/wrappers/timeout.d.ts +1 -0
  63. package/api/stream/wrappers/timeout.js +6 -0
  64. package/api/types.d.ts +17 -0
  65. package/api/wrappers/chaos.d.ts +1 -0
  66. package/api/wrappers/chaos.js +1 -0
  67. package/api/wrappers/cors.d.ts +1 -0
  68. package/api/wrappers/cors.js +11 -0
  69. package/api/wrappers/error.d.ts +4 -0
  70. package/api/wrappers/error.js +18 -0
  71. package/api/wrappers/headers.d.ts +1 -0
  72. package/api/wrappers/headers.js +13 -0
  73. package/api/wrappers/healthcheck.d.ts +8 -0
  74. package/api/wrappers/healthcheck.js +22 -0
  75. package/api/wrappers/index.d.ts +5 -0
  76. package/api/wrappers/index.js +5 -0
  77. package/compose/compose.d.ts +2 -0
  78. package/compose/compose.js +1 -0
  79. package/compose/index.d.ts +1 -0
  80. package/compose/index.js +1 -0
  81. package/create/create.d.ts +12 -0
  82. package/create/create.js +22 -0
  83. package/create/index.d.ts +1 -0
  84. package/create/index.js +1 -0
  85. package/dynamodb/dynamodb.d.ts +4 -0
  86. package/dynamodb/dynamodb.js +8 -0
  87. package/dynamodb/index.d.ts +1 -0
  88. package/dynamodb/index.js +1 -0
  89. package/eventBridge/eventBridge.d.ts +4 -0
  90. package/eventBridge/eventBridge.js +8 -0
  91. package/eventBridge/index.d.ts +1 -0
  92. package/eventBridge/index.js +1 -0
  93. package/factory/factory.d.ts +4 -0
  94. package/factory/factory.js +2 -0
  95. package/factory/index.d.ts +1 -0
  96. package/factory/index.js +1 -0
  97. package/index.d.ts +21 -19
  98. package/index.js +21 -19
  99. package/package.json +731 -185
  100. package/s3/index.d.ts +1 -0
  101. package/s3/index.js +1 -0
  102. package/s3/s3.d.ts +4 -0
  103. package/s3/s3.js +8 -0
  104. package/schedule/index.d.ts +1 -0
  105. package/schedule/index.js +1 -0
  106. package/schedule/schedule.d.ts +4 -0
  107. package/schedule/schedule.js +8 -0
  108. package/ses/index.d.ts +1 -0
  109. package/ses/index.js +1 -0
  110. package/ses/ses.d.ts +4 -0
  111. package/ses/ses.js +8 -0
  112. package/sns/index.d.ts +1 -0
  113. package/sns/index.js +1 -0
  114. package/sns/sns.d.ts +4 -0
  115. package/sns/sns.js +8 -0
  116. package/sqs/index.d.ts +1 -0
  117. package/sqs/index.js +1 -0
  118. package/sqs/sqs.d.ts +4 -0
  119. package/sqs/sqs.js +8 -0
  120. package/types.d.ts +12 -29
  121. package/{wrapper → wrappers}/chaos.d.ts +0 -1
  122. package/wrappers/chaos.js +35 -0
  123. package/{wrapper → wrappers}/context.d.ts +0 -1
  124. package/wrappers/context.js +6 -0
  125. package/{wrapper → wrappers}/error.d.ts +1 -4
  126. package/wrappers/error.js +9 -0
  127. package/wrappers/index.d.ts +6 -0
  128. package/wrappers/index.js +6 -0
  129. package/wrappers/logger.d.ts +4 -0
  130. package/wrappers/logger.js +21 -0
  131. package/wrappers/smoke.d.ts +2 -0
  132. package/wrappers/smoke.js +5 -0
  133. package/{wrapper → wrappers}/timeout.d.ts +0 -1
  134. package/wrappers/timeout.js +6 -0
  135. package/api.d.ts +0 -3
  136. package/api.js +0 -30
  137. package/compose.d.ts +0 -4
  138. package/compose.js +0 -3
  139. package/dynamodb.d.ts +0 -2
  140. package/dynamodb.js +0 -7
  141. package/eventBridge.d.ts +0 -2
  142. package/eventBridge.js +0 -7
  143. package/factory.d.ts +0 -8
  144. package/factory.js +0 -6
  145. package/s3.d.ts +0 -2
  146. package/s3.js +0 -7
  147. package/schedule.d.ts +0 -2
  148. package/schedule.js +0 -7
  149. package/ses.d.ts +0 -2
  150. package/ses.js +0 -7
  151. package/sns.d.ts +0 -2
  152. package/sns.js +0 -7
  153. package/sqs.d.ts +0 -2
  154. package/sqs.js +0 -7
  155. package/wrapper/context.js +0 -11
  156. package/wrapper/cors.d.ts +0 -3
  157. package/wrapper/cors.js +0 -28
  158. package/wrapper/error.js +0 -62
  159. package/wrapper/headers.d.ts +0 -3
  160. package/wrapper/headers.js +0 -25
  161. package/wrapper/healthcheck.d.ts +0 -13
  162. package/wrapper/healthcheck.js +0 -49
  163. package/wrapper/logger.d.ts +0 -6
  164. package/wrapper/logger.js +0 -65
  165. package/wrapper/smoke.d.ts +0 -3
  166. package/wrapper/timeout.js +0 -10
  167. /package/{wrapper → api/stream/wrappers}/stream.d.ts +0 -0
  168. /package/{wrapper → api/stream/wrappers}/stream.js +0 -0
package/s3/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createS3, createS3 as create, s3 } from './s3.js';
package/s3/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createS3, createS3 as create, s3 } from './s3.js';
package/s3/s3.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { S3Event } from 'aws-lambda';
2
+ import type { Decorator, EventHandlerOptions } from '../types.js';
3
+ export declare const createS3: (options?: EventHandlerOptions<S3Event>) => Decorator<S3Event, void>;
4
+ export declare const s3: Decorator<S3Event, void>;
package/s3/s3.js ADDED
@@ -0,0 +1,8 @@
1
+ import { compose } from '../compose/index.js';
2
+ import { withContext } from '../wrappers/context.js';
3
+ import { withError } from '../wrappers/error.js';
4
+ import { withLogger } from '../wrappers/logger.js';
5
+ import { withSmoke } from '../wrappers/smoke.js';
6
+ import { withTimeout } from '../wrappers/timeout.js';
7
+ export const createS3 = (options = {}) => compose(withError(options.error), withLogger(options.logger), withTimeout(), withContext(), withSmoke());
8
+ export const s3 = createS3();
@@ -0,0 +1 @@
1
+ export { createSchedule, createSchedule as create, schedule } from './schedule.js';
@@ -0,0 +1 @@
1
+ export { createSchedule, createSchedule as create, schedule } from './schedule.js';
@@ -0,0 +1,4 @@
1
+ import type { ScheduledEvent } from 'aws-lambda';
2
+ import type { Decorator, EventHandlerOptions } from '../types.js';
3
+ export declare const createSchedule: (options?: EventHandlerOptions<ScheduledEvent>) => Decorator<ScheduledEvent, void>;
4
+ export declare const schedule: Decorator<ScheduledEvent<any>, void>;
@@ -0,0 +1,8 @@
1
+ import { compose } from '../compose/index.js';
2
+ import { withContext } from '../wrappers/context.js';
3
+ import { withError } from '../wrappers/error.js';
4
+ import { withLogger } from '../wrappers/logger.js';
5
+ import { withSmoke } from '../wrappers/smoke.js';
6
+ import { withTimeout } from '../wrappers/timeout.js';
7
+ export const createSchedule = (options = {}) => compose(withError(options.error), withLogger(options.logger), withTimeout(), withContext(), withSmoke());
8
+ export const schedule = createSchedule();
package/ses/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createSes, createSes as create, ses } from './ses.js';
package/ses/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createSes, createSes as create, ses } from './ses.js';
package/ses/ses.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { SESEvent } from 'aws-lambda';
2
+ import type { Decorator, EventHandlerOptions } from '../types.js';
3
+ export declare const createSes: (options?: EventHandlerOptions<SESEvent>) => Decorator<SESEvent, void>;
4
+ export declare const ses: Decorator<SESEvent, void>;
package/ses/ses.js ADDED
@@ -0,0 +1,8 @@
1
+ import { compose } from '../compose/index.js';
2
+ import { withContext } from '../wrappers/context.js';
3
+ import { withError } from '../wrappers/error.js';
4
+ import { withLogger } from '../wrappers/logger.js';
5
+ import { withSmoke } from '../wrappers/smoke.js';
6
+ import { withTimeout } from '../wrappers/timeout.js';
7
+ export const createSes = (options = {}) => compose(withError(options.error), withLogger(options.logger), withTimeout(), withContext(), withSmoke());
8
+ export const ses = createSes();
package/sns/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createSns, createSns as create, sns } from './sns.js';
package/sns/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createSns, createSns as create, sns } from './sns.js';
package/sns/sns.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { SNSEvent } from 'aws-lambda';
2
+ import type { Decorator, EventHandlerOptions } from '../types.js';
3
+ export declare const createSns: (options?: EventHandlerOptions<SNSEvent>) => Decorator<SNSEvent, void>;
4
+ export declare const sns: Decorator<SNSEvent, void>;
package/sns/sns.js ADDED
@@ -0,0 +1,8 @@
1
+ import { compose } from '../compose/index.js';
2
+ import { withContext } from '../wrappers/context.js';
3
+ import { withError } from '../wrappers/error.js';
4
+ import { withLogger } from '../wrappers/logger.js';
5
+ import { withSmoke } from '../wrappers/smoke.js';
6
+ import { withTimeout } from '../wrappers/timeout.js';
7
+ export const createSns = (options = {}) => compose(withError(options.error), withLogger(options.logger), withTimeout(), withContext(), withSmoke());
8
+ export const sns = createSns();
package/sqs/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createSqs, createSqs as create, sqs } from './sqs.js';
package/sqs/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createSqs, createSqs as create, sqs } from './sqs.js';
package/sqs/sqs.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { SQSEvent } from 'aws-lambda';
2
+ import type { Decorator, EventHandlerOptions } from '../types.js';
3
+ export declare const createSqs: (options?: EventHandlerOptions<SQSEvent>) => Decorator<SQSEvent, void>;
4
+ export declare const sqs: Decorator<SQSEvent, void>;
package/sqs/sqs.js ADDED
@@ -0,0 +1,8 @@
1
+ import { compose } from '../compose/index.js';
2
+ import { withContext } from '../wrappers/context.js';
3
+ import { withError } from '../wrappers/error.js';
4
+ import { withLogger } from '../wrappers/logger.js';
5
+ import { withSmoke } from '../wrappers/smoke.js';
6
+ import { withTimeout } from '../wrappers/timeout.js';
7
+ export const createSqs = (options = {}) => compose(withError(options.error), withLogger(options.logger), withTimeout(), withContext(), withSmoke());
8
+ export const sqs = createSqs();
package/types.d.ts CHANGED
@@ -1,41 +1,24 @@
1
- import type { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
2
- import type { IncomingMessage, ServerResponse } from 'node:http';
1
+ import type { Context } from 'aws-lambda';
2
+ import type { ErrorOptions } from './wrappers/error.js';
3
+ import type { LoggerOptions } from './wrappers/logger.js';
3
4
  export type { Context } from 'aws-lambda';
4
- export type ResponseStream = {
5
- end: {
6
- (): unknown;
7
- (chunk: string | Buffer | Uint8Array): unknown;
8
- };
9
- setContentType?: (contentType: string) => unknown;
10
- writableEnded?: boolean;
11
- write(chunk: string | Buffer | Uint8Array): unknown;
12
- };
13
- export type ApiResult = APIGatewayProxyResult;
14
- export type ApiEvent = APIGatewayProxyEvent;
5
+ export type * from './api/types.js';
6
+ export type { Api as HttpApi, ApiOptions as HttpApiOptions, Compose as HttpCompose, Decorator as HttpDecorator, Factory as HttpFactory, Handler as HttpHandler, HandlerParams as HttpHandlerParams, Wrapper as HttpWrapper, } from './api/http/types.js';
7
+ export type { HealthcheckOptions as HttpHealthcheckOptions } from './api/http/wrappers/healthcheck.js';
8
+ export type { Api as StreamApi, ApiOptions as StreamApiOptions, Compose as StreamCompose, Decorator as StreamDecorator, Factory as StreamFactory, Handler as StreamHandler, HandlerParams as StreamHandlerParams, ResponseStream, TypedWrapper as StreamTypedWrapper, Wrapper as StreamWrapper, } from './api/stream/types.js';
9
+ export type { StreamMetadata } from './api/stream/wrappers/stream.js';
15
10
  export type HandlerParams<Event> = [event: Event, context: Context];
16
- export type StreamHandlerParams<Event> = [event: Event, responseStream: ResponseStream, context: Context];
17
11
  export type Response<Result> = Promise<Result>;
18
12
  export type Handler<Event, Result> = (event: Event, context: Context) => Response<Result>;
19
- export type StreamHandler<Event> = (event: Event, responseStream: ResponseStream, context: Context) => Response<void>;
20
- export type HttpHandler = (request: IncomingMessage, response: ServerResponse) => Promise<void> | void;
21
- export type HttpHandlerParams = [request: IncomingMessage, response: ServerResponse];
22
13
  export type Decorator<Event, Result> = (handler: Handler<Event, Result>) => Handler<Event, Result>;
23
- export type StreamDecorator<Event> = (handler: StreamHandler<Event>) => StreamHandler<Event>;
24
- export type HttpDecorator = (handler: HttpHandler) => HttpHandler;
14
+ export type EventHandlerOptions<Event> = {
15
+ error?: ErrorOptions<HandlerParams<Event>>;
16
+ logger?: LoggerOptions;
17
+ };
25
18
  export type Compose = <Event, Result>(...decorators: Array<Decorator<Event, Result>>) => Decorator<Event, Result>;
26
- export type StreamCompose = <Event>(...decorators: Array<StreamDecorator<Event>>) => StreamDecorator<Event>;
27
- export type HttpCompose = (...decorators: Array<HttpDecorator>) => HttpDecorator;
28
19
  export type Wrapper<Options> = <Event, Result>(handler: Handler<Event, Result>, args: HandlerParams<Event>, options?: Options) => Response<Result>;
29
- export type StreamWrapper<Options> = <Event>(handler: StreamHandler<Event>, args: StreamHandlerParams<Event>, options?: Options) => Response<void>;
30
- export type HttpWrapper<Options> = (handler: HttpHandler, args: HttpHandlerParams, options?: Options) => Response<void>;
31
20
  export type TypedWrapper<Event, Result, Options> = (handler: Handler<Event, Result>, args: HandlerParams<Event>, options?: Options) => Response<Result>;
32
- export type StreamTypedWrapper<Event, Options> = (handler: StreamHandler<Event>, args: StreamHandlerParams<Event>, options?: Options) => Response<void>;
33
21
  export type Factory = {
34
22
  <Options = undefined>(wrapper: Wrapper<Options>): <Event, Result>(options?: Options) => Decorator<Event, Result>;
35
23
  <Options, Event, Result>(wrapper: TypedWrapper<Event, Result, Options>): (options?: Options) => Decorator<Event, Result>;
36
24
  };
37
- export type StreamFactory = {
38
- <Options = undefined>(wrapper: StreamWrapper<Options>): <Event>(options?: Options) => StreamDecorator<Event>;
39
- <Options, Event>(wrapper: StreamTypedWrapper<Event, Options>): (options?: Options) => StreamDecorator<Event>;
40
- };
41
- export type HttpFactory = <Options = undefined>(wrapper: HttpWrapper<Options>) => (options?: Options) => HttpDecorator;
@@ -1,3 +1,2 @@
1
1
  import { type ChaosOptions } from '@vyriy/chaos';
2
2
  export declare const withChaos: <Event, Result>(options?: ChaosOptions | undefined) => import("../types.js").Decorator<Event, Result>;
3
- export declare const streamWithChaos: <Event>(options?: ChaosOptions | undefined) => import("../types.js").StreamDecorator<Event>;
@@ -0,0 +1,35 @@
1
+ import { chaos } from '@vyriy/chaos';
2
+ import { getConfig } from '@vyriy/config';
3
+ import { factory } from '../factory/index.js';
4
+ const getChaosEnabled = () => getConfig('CHAOS_ENABLED', false, 'boolean');
5
+ const getChaosErrorEnabled = () => getConfig('CHAOS_ERROR_ENABLED', true, 'boolean');
6
+ const getChaosTimeoutEnabled = () => getConfig('CHAOS_TIMEOUT_ENABLED', true, 'boolean');
7
+ const getChaosTimeoutMs = () => getConfig('CHAOS_TIMEOUT_MS', 10000, 'number');
8
+ const getStrategy = (options) => {
9
+ if (options.strategy) {
10
+ return options.strategy;
11
+ }
12
+ const isErrorEnabled = getChaosErrorEnabled();
13
+ const isTimeoutEnabled = getChaosTimeoutEnabled();
14
+ if (isErrorEnabled && isTimeoutEnabled) {
15
+ return 'random';
16
+ }
17
+ if (isErrorEnabled) {
18
+ return 'error';
19
+ }
20
+ if (isTimeoutEnabled) {
21
+ return 'timeout';
22
+ }
23
+ return 'random';
24
+ };
25
+ export const withChaos = factory(async (handler, args, options = {}) => {
26
+ const enabled = options.enabled ?? getChaosEnabled();
27
+ const strategy = getStrategy(options);
28
+ await chaos({
29
+ ...options,
30
+ enabled: enabled && (strategy !== 'random' || getChaosErrorEnabled() || getChaosTimeoutEnabled()),
31
+ strategy,
32
+ timeoutMs: options.timeoutMs ?? getChaosTimeoutMs(),
33
+ });
34
+ return handler(...args);
35
+ });
@@ -1,2 +1 @@
1
1
  export declare const withContext: <Event, Result>(options?: undefined) => import("../types.js").Decorator<Event, Result>;
2
- export declare const streamWithContext: <Event>(options?: undefined) => import("../types.js").StreamDecorator<Event>;
@@ -0,0 +1,6 @@
1
+ import { factory, getContext } from '../factory/index.js';
2
+ export const withContext = factory(async (handler, args) => {
3
+ const ctx = getContext(args);
4
+ ctx.callbackWaitsForEmptyEventLoop = false;
5
+ return handler(...args);
6
+ });
@@ -1,4 +1,4 @@
1
- import type { ApiEvent, ApiResult, Decorator, HandlerParams, HttpDecorator, HttpHandlerParams, StreamDecorator, StreamHandlerParams } from '../types.js';
1
+ import type { Decorator, HandlerParams } from '../types.js';
2
2
  export type ErrorHandler<Params extends unknown[]> = (err: unknown, args: Params) => Promise<void> | void;
3
3
  export type ApiErrorHandler<Params extends unknown[], Result> = (err: unknown, args: Params) => Promise<Result> | Result;
4
4
  export type ErrorOptions<Params extends unknown[]> = {
@@ -8,6 +8,3 @@ export type ApiErrorOptions<Params extends unknown[], Result> = {
8
8
  errorHandler?: ApiErrorHandler<Params, Result>;
9
9
  };
10
10
  export declare const withError: <Event, Result>(options?: ErrorOptions<HandlerParams<Event>>) => Decorator<Event, Result>;
11
- export declare const withApiError: (options?: ApiErrorOptions<HandlerParams<ApiEvent>, ApiResult>) => Decorator<ApiEvent, ApiResult>;
12
- export declare const streamWithApiError: (options?: ApiErrorOptions<StreamHandlerParams<ApiEvent>, ApiResult | void>) => StreamDecorator<ApiEvent>;
13
- export declare const httpWithError: (options?: ErrorOptions<HttpHandlerParams>) => HttpDecorator;
@@ -0,0 +1,9 @@
1
+ export const withError = (options = {}) => (handler) => async (event, context) => {
2
+ try {
3
+ return await handler(event, context);
4
+ }
5
+ catch (err) {
6
+ await options.errorHandler?.(err, [event, context]);
7
+ throw err;
8
+ }
9
+ };
@@ -0,0 +1,6 @@
1
+ export * from './chaos.js';
2
+ export * from './context.js';
3
+ export * from './error.js';
4
+ export * from './logger.js';
5
+ export * from './smoke.js';
6
+ export * from './timeout.js';
@@ -0,0 +1,6 @@
1
+ export * from './chaos.js';
2
+ export * from './context.js';
3
+ export * from './error.js';
4
+ export * from './logger.js';
5
+ export * from './smoke.js';
6
+ export * from './timeout.js';
@@ -0,0 +1,4 @@
1
+ export type LoggerOptions = {
2
+ logger?: typeof console;
3
+ };
4
+ export declare const withLogger: <Event, Result>(options?: LoggerOptions | undefined) => import("../types.js").Decorator<Event, Result>;
@@ -0,0 +1,21 @@
1
+ import { createLogger } from '@vyriy/logger';
2
+ import { factory, getContext } from '../factory/index.js';
3
+ export const withLogger = factory(async (handler, args, options = {}) => {
4
+ const { logger = createLogger() } = options;
5
+ const [event] = args;
6
+ const context = getContext(args);
7
+ logger.info('Event:', event);
8
+ logger.info('Context:', context);
9
+ try {
10
+ const result = await handler(...args);
11
+ logger.info('Result:', result);
12
+ return result;
13
+ }
14
+ catch (error) {
15
+ if (error instanceof Error) {
16
+ logger.error('Error:', error.message);
17
+ }
18
+ logger.error(error);
19
+ throw error;
20
+ }
21
+ });
@@ -0,0 +1,2 @@
1
+ import type { ApiResult, Decorator } from '../types.js';
2
+ export declare const withSmoke: <Event, Result extends ApiResult | void = ApiResult>() => Decorator<Event, Result>;
@@ -0,0 +1,5 @@
1
+ import { smoke } from '@vyriy/smoke';
2
+ export const withSmoke = () => (handler) => async (event, context) => {
3
+ const result = smoke(event);
4
+ return (result || (await handler(event, context)));
5
+ };
@@ -1,2 +1 @@
1
1
  export declare const withTimeout: <Event, Result>(options?: undefined) => import("../types.js").Decorator<Event, Result>;
2
- export declare const streamWithTimeout: <Event>(options?: undefined) => import("../types.js").StreamDecorator<Event>;
@@ -0,0 +1,6 @@
1
+ import { timeout as error } from '@vyriy/timeout';
2
+ import { factory, getContext } from '../factory/index.js';
3
+ export const withTimeout = factory(async (handler, args) => Promise.race([
4
+ error(getContext(args).getRemainingTimeInMillis() - 1000),
5
+ handler(...args),
6
+ ]));
package/api.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare const api: import("./types.js").Decorator<import("aws-lambda").APIGatewayProxyEvent, import("aws-lambda").APIGatewayProxyResult>;
2
- export declare const streamApi: import("./types.js").StreamDecorator<import("aws-lambda").APIGatewayProxyEvent>;
3
- export declare const httpApi: import("./types.js").HttpDecorator;
package/api.js DELETED
@@ -1,30 +0,0 @@
1
- import { compose, httpCompose, streamCompose } from './compose.js';
2
- import { httpWithError, streamWithApiError, withApiError } from './wrapper/error.js';
3
- import { httpWithLogger, streamWithLogger, withLogger } from './wrapper/logger.js';
4
- import { streamWithTimeout, withTimeout } from './wrapper/timeout.js';
5
- import { streamWithContext, withContext } from './wrapper/context.js';
6
- import { streamWithSmoke, withSmoke } from './wrapper/smoke.js';
7
- import { httpWithHealthcheck, streamWithHealthcheck, withHealthcheck } from './wrapper/healthcheck.js';
8
- import { httpWithHeaders, streamWithHeaders, withHeaders } from './wrapper/headers.js';
9
- import { httpWithCors, streamWithCors, withCors } from './wrapper/cors.js';
10
- import { streamWithChaos, withChaos } from './wrapper/chaos.js';
11
- export const api = compose(withApiError(), withLogger(), withTimeout(), withContext(), withSmoke(), withHealthcheck(), withHeaders({
12
- 'access-control-allow-origin': '*',
13
- 'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
14
- 'access-control-allow-headers': 'Content-Type, Authorization, X-Requested-With, X-Api-Key, Accept, User-Agent, X-CSRF-Token',
15
- 'content-type': 'application/json',
16
- 'x-robots-tag': 'noindex, nofollow',
17
- }), withCors(), withChaos());
18
- export const streamApi = streamCompose(streamWithApiError(), streamWithLogger(), streamWithTimeout(), streamWithContext(), streamWithSmoke(), streamWithHealthcheck(), streamWithHeaders({
19
- 'access-control-allow-origin': '*',
20
- 'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
21
- 'access-control-allow-headers': 'Content-Type, Authorization, X-Requested-With, X-Api-Key, Accept, User-Agent, X-CSRF-Token',
22
- 'content-type': 'application/json',
23
- 'x-robots-tag': 'noindex, nofollow',
24
- }), streamWithCors(), streamWithChaos());
25
- export const httpApi = httpCompose(httpWithError(), httpWithLogger(), httpWithHealthcheck(), httpWithHeaders({
26
- 'access-control-allow-origin': '*',
27
- 'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
28
- 'access-control-allow-headers': 'Content-Type, Authorization, X-Requested-With, X-Api-Key, Accept, User-Agent, X-CSRF-Token',
29
- 'x-robots-tag': 'noindex, nofollow',
30
- }), httpWithCors());
package/compose.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import type { Compose, HttpCompose, StreamCompose } from './types.js';
2
- export declare const compose: Compose;
3
- export declare const streamCompose: StreamCompose;
4
- export declare const httpCompose: HttpCompose;
package/compose.js DELETED
@@ -1,3 +0,0 @@
1
- export const compose = (...fns) => fns.reduceRight((prevDecorator, nextDecorator) => (handler) => nextDecorator(prevDecorator(handler)));
2
- export const streamCompose = (...fns) => fns.reduceRight((prevDecorator, nextDecorator) => (handler) => nextDecorator(prevDecorator(handler)));
3
- export const httpCompose = (...fns) => fns.reduceRight((prevDecorator, nextDecorator) => (handler) => nextDecorator(prevDecorator(handler)));
package/dynamodb.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { DynamoDBStreamEvent } from 'aws-lambda';
2
- export declare const dynamodb: import("./types.js").Decorator<DynamoDBStreamEvent, void>;
package/dynamodb.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const dynamodb = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/eventBridge.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { EventBridgeEvent } from 'aws-lambda';
2
- export declare const eventBridge: import("./types.js").Decorator<EventBridgeEvent<string, unknown>, void>;
package/eventBridge.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const eventBridge = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/factory.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import type { Context } from 'aws-lambda';
2
- import type { Factory, HandlerParams, HttpFactory, ResponseStream, StreamFactory, StreamHandlerParams } from './types.js';
3
- export declare const getContext: <Event>(args: HandlerParams<Event>) => Context;
4
- export declare const getResponseStream: <Event>(args: StreamHandlerParams<Event>) => ResponseStream;
5
- export declare const getStreamContext: <Event>(args: StreamHandlerParams<Event>) => Context;
6
- export declare const factory: Factory;
7
- export declare const streamFactory: StreamFactory;
8
- export declare const httpFactory: HttpFactory;
package/factory.js DELETED
@@ -1,6 +0,0 @@
1
- export const getContext = (args) => args[1];
2
- export const getResponseStream = (args) => args[1];
3
- export const getStreamContext = (args) => args[2];
4
- export const factory = (wrapper) => (options) => (handler) => async (event, context) => wrapper(handler, [event, context], options);
5
- export const streamFactory = (wrapper) => (options) => (handler) => async (event, responseStream, context) => wrapper(handler, [event, responseStream, context], options);
6
- export const httpFactory = (wrapper) => (options) => (handler) => async (request, response) => wrapper(handler, [request, response], options);
package/s3.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { S3Event } from 'aws-lambda';
2
- export declare const s3: import("./types.js").Decorator<S3Event, void>;
package/s3.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const s3 = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/schedule.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { ScheduledEvent } from 'aws-lambda';
2
- export declare const schedule: import("./types.js").Decorator<ScheduledEvent<any>, void>;
package/schedule.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const schedule = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/ses.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { SESEvent } from 'aws-lambda';
2
- export declare const ses: import("./types.js").Decorator<SESEvent, void>;
package/ses.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const ses = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/sns.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { SNSEvent } from 'aws-lambda';
2
- export declare const sns: import("./types.js").Decorator<SNSEvent, void>;
package/sns.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const sns = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
package/sqs.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { SQSEvent } from 'aws-lambda';
2
- export declare const sqs: import("./types.js").Decorator<SQSEvent, void>;
package/sqs.js DELETED
@@ -1,7 +0,0 @@
1
- import { compose } from './compose.js';
2
- import { withError } from './wrapper/error.js';
3
- import { withLogger } from './wrapper/logger.js';
4
- import { withTimeout } from './wrapper/timeout.js';
5
- import { withContext } from './wrapper/context.js';
6
- import { withSmoke } from './wrapper/smoke.js';
7
- export const sqs = compose(withError(), withLogger(), withTimeout(), withContext(), withSmoke());
@@ -1,11 +0,0 @@
1
- import { factory, getContext, getStreamContext, streamFactory } from '../factory.js';
2
- export const withContext = factory(async (handler, args) => {
3
- const ctx = getContext(args);
4
- ctx.callbackWaitsForEmptyEventLoop = false;
5
- return handler(...args);
6
- });
7
- export const streamWithContext = streamFactory(async (handler, args) => {
8
- const ctx = getStreamContext(args);
9
- ctx.callbackWaitsForEmptyEventLoop = false;
10
- return handler(...args);
11
- });
package/wrapper/cors.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare const withCors: (options?: unknown) => import("../types.js").Decorator<import("aws-lambda").APIGatewayProxyEvent, import("aws-lambda").APIGatewayProxyResult>;
2
- export declare const streamWithCors: (options?: unknown) => import("../types.js").StreamDecorator<import("aws-lambda").APIGatewayProxyEvent>;
3
- export declare const httpWithCors: (options?: undefined) => import("../types.js").HttpDecorator;
package/wrapper/cors.js DELETED
@@ -1,28 +0,0 @@
1
- import { factory, httpFactory, streamFactory } from '../factory.js';
2
- import { responseStream } from './stream.js';
3
- export const withCors = factory(async (handler, args) => {
4
- const [request] = args;
5
- if (request.httpMethod === 'OPTIONS') {
6
- return {
7
- body: '',
8
- statusCode: 204,
9
- };
10
- }
11
- return handler(...args);
12
- });
13
- export const streamWithCors = streamFactory(async (handler, args) => {
14
- const [request, stream] = args;
15
- if (request.httpMethod === 'OPTIONS') {
16
- responseStream(stream, { statusCode: 204 }).end();
17
- return;
18
- }
19
- await handler(...args);
20
- });
21
- export const httpWithCors = httpFactory(async (handler, args) => {
22
- const [request, response] = args;
23
- if (request.method === 'OPTIONS') {
24
- response.writeHead(204).end();
25
- return;
26
- }
27
- await handler(...args);
28
- });
package/wrapper/error.js DELETED
@@ -1,62 +0,0 @@
1
- import { STATUS_CODES } from 'node:http';
2
- import { responseStream } from './stream.js';
3
- const defaultErrorResult = () => ({
4
- statusCode: 500,
5
- headers: {
6
- 'content-type': 'application/json',
7
- },
8
- body: JSON.stringify({
9
- message: STATUS_CODES[500],
10
- }),
11
- });
12
- export const withError = (options = {}) => (handler) => async (event, context) => {
13
- try {
14
- return await handler(event, context);
15
- }
16
- catch (err) {
17
- await options.errorHandler?.(err, [event, context]);
18
- throw err;
19
- }
20
- };
21
- export const withApiError = (options = {}) => (handler) => async (event, context) => {
22
- try {
23
- return await handler(event, context);
24
- }
25
- catch (err) {
26
- return options.errorHandler?.(err, [event, context]) ?? defaultErrorResult();
27
- }
28
- };
29
- export const streamWithApiError = (options = {}) => (handler) => async (event, stream, context) => {
30
- try {
31
- await handler(event, stream, context);
32
- }
33
- catch (err) {
34
- const result = (await options.errorHandler?.(err, [event, stream, context])) ?? defaultErrorResult();
35
- if (result) {
36
- responseStream(stream, {
37
- headers: result.headers,
38
- statusCode: result.statusCode,
39
- }).end(result.body);
40
- }
41
- }
42
- };
43
- export const httpWithError = (options = {}) => (handler) => async (request, response) => {
44
- try {
45
- await handler(request, response);
46
- }
47
- catch (err) {
48
- await options.errorHandler?.(err, [request, response]);
49
- if (response.writableEnded) {
50
- return;
51
- }
52
- if (response.headersSent) {
53
- response.end();
54
- return;
55
- }
56
- response
57
- .writeHead(500, {
58
- 'content-type': 'application/json',
59
- })
60
- .end(JSON.stringify({ message: STATUS_CODES[500] }));
61
- }
62
- };
@@ -1,3 +0,0 @@
1
- export declare const withHeaders: (options?: Record<string, string> | undefined) => import("../types.js").Decorator<import("aws-lambda").APIGatewayProxyEvent, import("aws-lambda").APIGatewayProxyResult>;
2
- export declare const streamWithHeaders: (options?: Record<string, string> | undefined) => import("../types.js").StreamDecorator<import("aws-lambda").APIGatewayProxyEvent>;
3
- export declare const httpWithHeaders: (options?: Record<string, string> | undefined) => import("../types.js").HttpDecorator;