@jaypie/constructs 1.2.5 → 1.2.7

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.
@@ -35,8 +35,10 @@ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionPro
35
35
  */
36
36
  host?: string;
37
37
  /**
38
- * Invoke mode for Lambda Function URLs
39
- * @default InvokeMode.BUFFERED
38
+ * Invoke mode for Lambda Function URLs.
39
+ * If not provided, auto-detects from handler if it has an invokeMode property
40
+ * (e.g., JaypieStreamingLambda).
41
+ * @default InvokeMode.BUFFERED (or auto-detected from handler)
40
42
  */
41
43
  invokeMode?: lambda.InvokeMode;
42
44
  /**
@@ -64,6 +66,7 @@ export declare class JaypieDistribution extends Construct implements cloudfront.
64
66
  private isIOrigin;
65
67
  private isIFunctionUrl;
66
68
  private isIFunction;
69
+ private hasInvokeMode;
67
70
  get env(): {
68
71
  account: string;
69
72
  region: string;
@@ -21,7 +21,7 @@ export interface JaypieLambdaProps {
21
21
  /**
22
22
  * DynamoDB tables to grant read/write access to the Lambda function.
23
23
  * Each table is granted read/write access and if exactly one table is provided,
24
- * the CDK_ENV_DYNAMO_TABLE environment variable is set to the table name.
24
+ * the DYNAMODB_TABLE_NAME environment variable is set to the table name.
25
25
  */
26
26
  tables?: dynamodb.ITable[];
27
27
  /**
@@ -23,7 +23,7 @@ export interface JaypieNextjsProps {
23
23
  /**
24
24
  * DynamoDB tables to grant read/write access to the Next.js server function.
25
25
  * Each table is granted read/write access and if exactly one table is provided,
26
- * the CDK_ENV_DYNAMO_TABLE environment variable is set to the table name.
26
+ * the DYNAMODB_TABLE_NAME environment variable is set to the table name.
27
27
  */
28
28
  tables?: dynamodb.ITable[];
29
29
  /**
@@ -0,0 +1,44 @@
1
+ import { Construct } from "constructs";
2
+ import * as lambda from "aws-cdk-lib/aws-lambda";
3
+ import { JaypieLambda, JaypieLambdaProps } from "./JaypieLambda.js";
4
+ export interface JaypieStreamingLambdaProps extends JaypieLambdaProps {
5
+ /**
6
+ * The port your application listens on.
7
+ * @default 8000
8
+ */
9
+ port?: number;
10
+ /**
11
+ * Enable response streaming mode.
12
+ * When true, uses RESPONSE_STREAM invoke mode.
13
+ * When false, uses BUFFERED invoke mode.
14
+ * @default false
15
+ */
16
+ streaming?: boolean;
17
+ }
18
+ /**
19
+ * A Lambda construct that uses AWS Lambda Web Adapter for streaming support.
20
+ * This allows running web applications (Express, Fastify, etc.) with streaming responses.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const streamingLambda = new JaypieStreamingLambda(this, "StreamingApi", {
25
+ * code: "dist/api",
26
+ * handler: "run.sh",
27
+ * streaming: true,
28
+ * });
29
+ *
30
+ * // Use with JaypieDistribution
31
+ * new JaypieDistribution(this, "Distribution", {
32
+ * handler: streamingLambda,
33
+ * invokeMode: streamingLambda.invokeMode,
34
+ * });
35
+ * ```
36
+ */
37
+ export declare class JaypieStreamingLambda extends JaypieLambda {
38
+ /**
39
+ * The invoke mode for this Lambda function.
40
+ * Use this when configuring JaypieDistribution.
41
+ */
42
+ readonly invokeMode: lambda.InvokeMode;
43
+ constructor(scope: Construct, id: string, props: JaypieStreamingLambdaProps);
44
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,17 @@
1
+ export declare const LAMBDA_WEB_ADAPTER: {
2
+ ACCOUNT: string;
3
+ DEFAULT_PORT: number;
4
+ EXEC_WRAPPER: string;
5
+ INVOKE_MODE: {
6
+ BUFFERED: string;
7
+ RESPONSE_STREAM: string;
8
+ };
9
+ LAYER: {
10
+ ARM64: string;
11
+ X86: string;
12
+ };
13
+ VERSION: number;
14
+ };
1
15
  export declare const CDK: {
2
16
  ACCOUNT: {
3
17
  DEVELOPMENT: string;
@@ -63,6 +63,20 @@ var origins__namespace = /*#__PURE__*/_interopNamespaceDefault(origins);
63
63
  var dynamodb__namespace = /*#__PURE__*/_interopNamespaceDefault(dynamodb);
64
64
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
65
65
 
66
+ const LAMBDA_WEB_ADAPTER = {
67
+ ACCOUNT: "753240598075",
68
+ DEFAULT_PORT: 8000,
69
+ EXEC_WRAPPER: "/opt/bootstrap",
70
+ INVOKE_MODE: {
71
+ BUFFERED: "BUFFERED",
72
+ RESPONSE_STREAM: "RESPONSE_STREAM",
73
+ },
74
+ LAYER: {
75
+ ARM64: "LambdaAdapterLayerArm64",
76
+ X86: "LambdaAdapterLayerX86",
77
+ },
78
+ VERSION: 25,
79
+ };
66
80
  const CDK$2 = {
67
81
  ACCOUNT: {
68
82
  DEVELOPMENT: "development",
@@ -1307,7 +1321,7 @@ class JaypieLambda extends constructs.Construct {
1307
1321
  });
1308
1322
  // Add table name to environment if there's exactly one table
1309
1323
  if (tables.length === 1) {
1310
- this._lambda.addEnvironment("CDK_ENV_DYNAMO_TABLE", tables[0].tableName);
1324
+ this._lambda.addEnvironment("DYNAMODB_TABLE_NAME", tables[0].tableName);
1311
1325
  }
1312
1326
  // Configure provisioned concurrency if specified
1313
1327
  if (provisionedConcurrentExecutions !== undefined) {
@@ -1994,6 +2008,18 @@ class JaypieDatadogForwarder extends constructs.Construct {
1994
2008
  }
1995
2009
  }
1996
2010
 
2011
+ class JaypieDatadogSecret extends JaypieEnvSecret {
2012
+ constructor(scope, id = "MongoConnectionString", props) {
2013
+ const defaultProps = {
2014
+ envKey: "DATADOG_API_KEY",
2015
+ roleTag: CDK$2.ROLE.MONITORING,
2016
+ vendorTag: CDK$2.VENDOR.DATADOG,
2017
+ ...props,
2018
+ };
2019
+ super(scope, id, defaultProps);
2020
+ }
2021
+ }
2022
+
1997
2023
  class JaypieDistribution extends constructs.Construct {
1998
2024
  constructor(scope, id, props) {
1999
2025
  super(scope, id);
@@ -2039,12 +2065,19 @@ class JaypieDistribution extends constructs.Construct {
2039
2065
  // IFunction before IFunctionUrl (IFunction doesn't have functionUrlId)
2040
2066
  let origin;
2041
2067
  if (handler) {
2068
+ // Auto-detect invoke mode from handler (e.g., JaypieStreamingLambda)
2069
+ // Explicit invokeMode prop takes precedence over auto-detection
2070
+ const resolvedInvokeMode = invokeMode !== lambda__namespace.InvokeMode.BUFFERED
2071
+ ? invokeMode // Explicit non-default value, use it
2072
+ : this.hasInvokeMode(handler)
2073
+ ? handler.invokeMode // Auto-detect from handler
2074
+ : invokeMode; // Use default BUFFERED
2042
2075
  if (this.isIFunction(handler)) {
2043
2076
  // Create FunctionUrl for the Lambda function
2044
2077
  const functionUrl = new lambda__namespace.FunctionUrl(this, "FunctionUrl", {
2045
2078
  function: handler,
2046
2079
  authType: lambda__namespace.FunctionUrlAuthType.NONE,
2047
- invokeMode,
2080
+ invokeMode: resolvedInvokeMode,
2048
2081
  });
2049
2082
  this.functionUrl = functionUrl;
2050
2083
  origin = new origins__namespace.FunctionUrlOrigin(functionUrl);
@@ -2181,6 +2214,13 @@ class JaypieDistribution extends constructs.Construct {
2181
2214
  "functionName" in handler &&
2182
2215
  !("url" in handler));
2183
2216
  }
2217
+ hasInvokeMode(handler) {
2218
+ // Check if handler has an invokeMode property (e.g., JaypieStreamingLambda)
2219
+ return (typeof handler === "object" &&
2220
+ handler !== null &&
2221
+ "invokeMode" in handler &&
2222
+ typeof handler.invokeMode === "string");
2223
+ }
2184
2224
  // Implement IDistribution interface
2185
2225
  get env() {
2186
2226
  return {
@@ -2207,18 +2247,6 @@ class JaypieDistribution extends constructs.Construct {
2207
2247
  }
2208
2248
  }
2209
2249
 
2210
- class JaypieDatadogSecret extends JaypieEnvSecret {
2211
- constructor(scope, id = "MongoConnectionString", props) {
2212
- const defaultProps = {
2213
- envKey: "DATADOG_API_KEY",
2214
- roleTag: CDK$2.ROLE.MONITORING,
2215
- vendorTag: CDK$2.VENDOR.DATADOG,
2216
- ...props,
2217
- };
2218
- super(scope, id, defaultProps);
2219
- }
2220
- }
2221
-
2222
2250
  class JaypieDnsRecord extends constructs.Construct {
2223
2251
  constructor(scope, id, props) {
2224
2252
  super(scope, id);
@@ -2618,6 +2646,16 @@ class JaypieEventsRule extends constructs.Construct {
2618
2646
  }
2619
2647
  }
2620
2648
 
2649
+ class JaypieExpressLambda extends JaypieLambda {
2650
+ constructor(scope, id, props) {
2651
+ super(scope, id, {
2652
+ timeout: cdk.Duration.seconds(CDK$2.DURATION.EXPRESS_API),
2653
+ roleTag: CDK$2.ROLE.API,
2654
+ ...props,
2655
+ });
2656
+ }
2657
+ }
2658
+
2621
2659
  class JaypieGitHubDeployRole extends constructs.Construct {
2622
2660
  constructor(scope, id = "GitHubDeployRole", props = {}) {
2623
2661
  super(scope, id);
@@ -2700,16 +2738,6 @@ class JaypieGitHubDeployRole extends constructs.Construct {
2700
2738
  }
2701
2739
  }
2702
2740
 
2703
- class JaypieExpressLambda extends JaypieLambda {
2704
- constructor(scope, id, props) {
2705
- super(scope, id, {
2706
- timeout: cdk.Duration.seconds(CDK$2.DURATION.EXPRESS_API),
2707
- roleTag: CDK$2.ROLE.API,
2708
- ...props,
2709
- });
2710
- }
2711
- }
2712
-
2713
2741
  const SERVICE = {
2714
2742
  ROUTE53: "route53.amazonaws.com",
2715
2743
  };
@@ -2949,7 +2977,7 @@ class JaypieNextJs extends constructs.Construct {
2949
2977
  });
2950
2978
  // Add table name to environment if there's exactly one table
2951
2979
  if (tables.length === 1) {
2952
- nextjs.serverFunction.lambdaFunction.addEnvironment("CDK_ENV_DYNAMO_TABLE", tables[0].tableName);
2980
+ nextjs.serverFunction.lambdaFunction.addEnvironment("DYNAMODB_TABLE_NAME", tables[0].tableName);
2953
2981
  }
2954
2982
  // Store reference to nextjs for property exposure
2955
2983
  this._nextjs = nextjs;
@@ -3754,6 +3782,75 @@ class JaypieStaticWebBucket extends JaypieWebDeploymentBucket {
3754
3782
  }
3755
3783
  }
3756
3784
 
3785
+ /**
3786
+ * A Lambda construct that uses AWS Lambda Web Adapter for streaming support.
3787
+ * This allows running web applications (Express, Fastify, etc.) with streaming responses.
3788
+ *
3789
+ * @example
3790
+ * ```typescript
3791
+ * const streamingLambda = new JaypieStreamingLambda(this, "StreamingApi", {
3792
+ * code: "dist/api",
3793
+ * handler: "run.sh",
3794
+ * streaming: true,
3795
+ * });
3796
+ *
3797
+ * // Use with JaypieDistribution
3798
+ * new JaypieDistribution(this, "Distribution", {
3799
+ * handler: streamingLambda,
3800
+ * invokeMode: streamingLambda.invokeMode,
3801
+ * });
3802
+ * ```
3803
+ */
3804
+ class JaypieStreamingLambda extends JaypieLambda {
3805
+ constructor(scope, id, props) {
3806
+ const { architecture = lambda__namespace.Architecture.X86_64, environment: propsEnvironment, layers: propsLayers = [], port = LAMBDA_WEB_ADAPTER.DEFAULT_PORT, streaming = false, ...restProps } = props;
3807
+ // Determine the Lambda Web Adapter layer ARN based on architecture
3808
+ const region = cdk.Stack.of(scope).region;
3809
+ const layerArn = architecture === lambda__namespace.Architecture.ARM_64
3810
+ ? `arn:aws:lambda:${region}:${LAMBDA_WEB_ADAPTER.ACCOUNT}:layer:${LAMBDA_WEB_ADAPTER.LAYER.ARM64}:${LAMBDA_WEB_ADAPTER.VERSION}`
3811
+ : `arn:aws:lambda:${region}:${LAMBDA_WEB_ADAPTER.ACCOUNT}:layer:${LAMBDA_WEB_ADAPTER.LAYER.X86}:${LAMBDA_WEB_ADAPTER.VERSION}`;
3812
+ // Create the Lambda Web Adapter layer
3813
+ const webAdapterLayer = lambda__namespace.LayerVersion.fromLayerVersionArn(scope, `${id}WebAdapterLayer`, layerArn);
3814
+ // Build environment variables with Lambda Web Adapter configuration
3815
+ const lwaInvokeMode = streaming
3816
+ ? LAMBDA_WEB_ADAPTER.INVOKE_MODE.RESPONSE_STREAM
3817
+ : LAMBDA_WEB_ADAPTER.INVOKE_MODE.BUFFERED;
3818
+ const webAdapterEnvironment = {
3819
+ AWS_LAMBDA_EXEC_WRAPPER: LAMBDA_WEB_ADAPTER.EXEC_WRAPPER,
3820
+ AWS_LWA_INVOKE_MODE: lwaInvokeMode,
3821
+ PORT: String(port),
3822
+ };
3823
+ // Merge environment variables - props environment takes precedence
3824
+ let mergedEnvironment;
3825
+ if (Array.isArray(propsEnvironment)) {
3826
+ // Array syntax: prepend our object to the array
3827
+ mergedEnvironment = [webAdapterEnvironment, ...propsEnvironment];
3828
+ }
3829
+ else if (propsEnvironment && typeof propsEnvironment === "object") {
3830
+ // Object syntax: merge objects
3831
+ mergedEnvironment = {
3832
+ ...webAdapterEnvironment,
3833
+ ...propsEnvironment,
3834
+ };
3835
+ }
3836
+ else {
3837
+ mergedEnvironment = webAdapterEnvironment;
3838
+ }
3839
+ super(scope, id, {
3840
+ architecture,
3841
+ environment: mergedEnvironment,
3842
+ layers: [webAdapterLayer, ...propsLayers],
3843
+ roleTag: CDK$2.ROLE.API,
3844
+ timeout: cdk.Duration.seconds(CDK$2.DURATION.EXPRESS_API),
3845
+ ...restProps,
3846
+ });
3847
+ // Set invoke mode for use with JaypieDistribution
3848
+ this.invokeMode = streaming
3849
+ ? lambda__namespace.InvokeMode.RESPONSE_STREAM
3850
+ : lambda__namespace.InvokeMode.BUFFERED;
3851
+ }
3852
+ }
3853
+
3757
3854
  class JaypieTraceSigningKeySecret extends JaypieEnvSecret {
3758
3855
  constructor(scope, id = "TraceSigningKey", props) {
3759
3856
  const defaultProps = {
@@ -3793,8 +3890,10 @@ exports.JaypieSsoPermissions = JaypieSsoPermissions;
3793
3890
  exports.JaypieSsoSyncApplication = JaypieSsoSyncApplication;
3794
3891
  exports.JaypieStack = JaypieStack;
3795
3892
  exports.JaypieStaticWebBucket = JaypieStaticWebBucket;
3893
+ exports.JaypieStreamingLambda = JaypieStreamingLambda;
3796
3894
  exports.JaypieTraceSigningKeySecret = JaypieTraceSigningKeySecret;
3797
3895
  exports.JaypieWebDeploymentBucket = JaypieWebDeploymentBucket;
3896
+ exports.LAMBDA_WEB_ADAPTER = LAMBDA_WEB_ADAPTER;
3798
3897
  exports.addDatadogLayers = addDatadogLayers;
3799
3898
  exports.clearAllSecretsCaches = clearAllSecretsCaches;
3800
3899
  exports.clearSecretsCache = clearSecretsCache;