@ashishpandeyone/cdk-lambda-web-function 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -9745,7 +9745,7 @@
9745
9745
  },
9746
9746
  "name": "@ashishpandeyone/cdk-lambda-web-function",
9747
9747
  "readme": {
9748
- "markdown": "# CDK constructs for AWS Lambda Web Functions\n\n<!--BEGIN STABILITY BANNER-->\n\n---\n\n![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)\n\n> The APIs of higher level constructs in this module are experimental and under active development.\n> They are subject to non-backward compatible changes or removal in any future version. These are\n> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be\n> announced in the release notes. This means that while you may use them, you may need to update\n> your source code when upgrading to a newer version of this package.\n\n---\n\n<!--END STABILITY BANNER-->\n\n[AWS Lambda Web Functions](https://aws.amazon.com/lambda/) run an ordinary Node.js HTTP server (Express, Fastify, Hono, `node:http`) on Lambda and give it an HTTPS endpoint, optionally served from several regions. `WebFunction` deploys one, following the conventions of `aws-cdk-lib/aws-lambda` where the two services overlap.\n\n```ts fixture=bare\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport { WebFunction, WebFunctionAuthType, WebFunctionEndpointType } from '@ashishpandeyone/cdk-lambda-web-function';\n\nconst fn = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n endpointType: WebFunctionEndpointType.MULTI_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n },\n});\n\nnew CfnOutput(this, 'Url', { value: fn.endpoint.url }); // https://<id>.lambda-web.global.on.aws\n```\n\nThe stack's region is the function's **home region**. Multi-region endpoints need a stack with an explicit `env.region`.\n\n## Writing the server\n\n1. Listen on the host and port in **`AWS_LAMBDA_HTTP_ENDPOINT`** (`0.0.0.0:3000` today). `PORT` is not set.\n2. Start listening within **about 9 seconds**, or initialisation fails with `Application.TimeoutListenError`.\n3. Put the entry file at the root of your bundle as **`index.js`**, or set `entrypoint`.\n4. The runtime has **no AWS SDK**: bundle the clients you import.\n5. Code runs on **arm64**.\n\n```js\nconst express = require('express');\n\nconst app = express();\napp.get('/', (req, res) => res.json({ hello: 'world', region: process.env.AWS_REGION }));\n\nconst [host, port] = process.env.AWS_LAMBDA_HTTP_ENDPOINT.split(':');\napp.listen(Number(port), host);\n```\n\nRequests carry `lambda-web-request-id` and `lambda-web-endpoint-name` headers.\n\n## Regions and endpoints\n\nEach `WebFunction` has a default endpoint, `fn.endpoint`, configured with the `endpoint` property. [Add more](#more-endpoints) with `fn.addEndpoint()`.\n\n| `endpointType` | URL | Routing |\n|---|---|---|\n| `HOME_REGION` (default) | `https://<id>.<cell>.lambda-web.<home>.on.aws` | home region only |\n| `MULTI_REGION` | one global `https://<id>.lambda-web.global.on.aws` | nearest region |\n| `PER_REGION` | one URL per region, from `fn.endpoint.regionalUrl(region)` | the region in the hostname |\n\n```ts\nconst perRegion = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n endpointType: WebFunctionEndpointType.PER_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n },\n});\n\nnew CfnOutput(this, 'UsEast1Url', { value: perRegion.endpoint.regionalUrl('us-east-1') });\n// perRegion.endpoint.regions is ['<home region>', 'eu-west-1', 'us-east-1']\n```\n\n- `MULTI_REGION` and `PER_REGION` need at least one region besides the home region; `HOME_REGION` takes none.\n- A MultiRegion endpoint takes about a minute to create.\n- Lambda routes a `MULTI_REGION` endpoint by latency, not by health: it doesn't fail over when a region has problems.\n\n### More endpoints\n\nA function can have up to 10 endpoints, each with its own URL, authentication, regions and limits. For example, a public endpoint next to an IAM-only global one:\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.NONE, // the default endpoint is public\n endpoint: { rateLimit: 1000 }, // requests per second\n});\n\nconst internal = api.addEndpoint('Internal', {\n authType: WebFunctionAuthType.AWS_IAM,\n endpointType: WebFunctionEndpointType.MULTI_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n description: 'Service-to-service traffic',\n maxEnvironments: 50,\n});\ninternal.grantInvoke(consumerRole);\nnew CfnOutput(this, 'InternalUrl', { value: internal.url });\n```\n\n- `rateLimit` takes 0 (blocks all traffic), 100–1,000 in steps of 100, or 2,000–10,000 in steps of 1,000; excess requests get HTTP 429. `maxEnvironments` takes 2–10,000.\n- **Both limits apply separately in each region** an endpoint serves from: a 3-region endpoint with `rateLimit: 1000` accepts up to 1,000 requests per second in each region.\n- Endpoints can serve the same regions. The construct owns one `.local` log group per region, whichever endpoints serve it.\n\n### Changing regions or the endpoint type\n\nAn endpoint's type and regions can't change in place: a change creates a **new endpoint with a new URL**, and the old one is deleted once the new one is live. Two endpoints of one function can't share a name, so:\n\n| `endpointName` | Physical name | Changing `regions` or `endpointType` |\n|---|---|---|\n| omitted (recommended) | `default-<hash>` for `fn.endpoint`, `<id>-<hash>` for added endpoints; the hash covers the type and regions | works: new endpoint, new URL |\n| set, e.g. `'live'` | `live` | also change the name in the same deployment, or it fails with *The endpoint live already exists* (the stack rolls back and the old endpoint keeps serving) |\n\nThe construct warns at synth time when `endpointName` is set.\n\n## Authentication and invoking\n\n| `authType` | Meaning |\n|---|---|\n| `AWS_IAM` | Callers sign requests (SigV4 or SigV4a, signing name `lambda`) and need `lambda:InvokeWebFunctionEndpoint` |\n| `NONE` | **Public**: Lambda does no authentication; your application does (JWT, sessions). The `Authorization` header reaches your application untouched. The construct warns at synth time |\n\n```ts\nfn.grants.invoke(consumerRole); // or fn.grantInvoke(consumerRole), as on lambda.Function\n```\n\nThe grant is on the endpoint's home-region ARN, which IAM evaluates in every region the endpoint serves from, including the global URL. `fn.grants` covers the default endpoint only; grant other endpoints with their own `grantInvoke()` or `grants.invoke()`.\n\n| Endpoint | How to sign |\n|---|---|\n| `HOME_REGION` | SigV4 for the home region |\n| `PER_REGION` | SigV4 for the hostname's region, or SigV4a |\n| `MULTI_REGION` | **SigV4a with region set `*`**: you can't know which region will serve the request |\n\n```js\nimport { SignatureV4a } from '@smithy/signature-v4a';\nimport { Sha256 } from '@aws-crypto/sha256-js';\nimport { fromNodeProviderChain } from '@aws-sdk/credential-providers';\n\nconst signer = new SignatureV4a({ service: 'lambda', region: '*', sha256: Sha256, credentials: fromNodeProviderChain() });\nconst signed = await signer.sign(\n { method: 'GET', protocol: 'https:', hostname: host, path: '/', headers: { host } },\n { signingRegion: '*' },\n);\nconst response = await fetch(`https://${host}/`, { headers: signed.headers });\n```\n\n### Functions defined elsewhere\n\nImport a Web Function defined in another stack or app to grant access to it, read its metrics, or reference its revisions:\n\n```ts\nconst orders = WebFunction.fromWebFunctionArn(this, 'Orders', 'arn:aws:lambda:us-east-1:111122223333:web-function/orders');\norders.grantInvoke(consumerRole); // every endpoint of the function\n\nconst live = WebFunction.fromWebFunctionAttributes(this, 'Live', {\n webFunctionName: 'orders', // in this stack's account and region\n endpointName: 'live', // grantInvoke allows this endpoint only\n});\nlive.metricConcurrentRequests().createAlarm(this, 'Busy', { threshold: 60, evaluationPeriods: 3 });\n```\n\nAn imported function's metrics default to its own region. Its endpoints, revisions and log groups stay with the stack that defines it.\n\n`grantInvoke` adds to the caller's IAM policy, which is all a caller in the function's account needs. A caller in another account also needs the function's resource policy to allow it, which this library doesn't manage yet.\n\n## Configuration\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('build'),\n authType: WebFunctionAuthType.AWS_IAM,\n entrypoint: 'server.js', // default index.js\n webFunctionName: 'orders-api', // default: generated from the construct path\n description: 'Orders HTTP API',\n environment: { TABLE_NAME: table.tableName },\n timeout: Duration.seconds(60), // per request: 3 seconds to 15 minutes, default 30 seconds\n maxConcurrencyPerEnvironment: 32, // requests per environment at once: 1-128, default 64\n});\n\napi.addEnvironment('FEATURE_FLAG', 'on');\ntable.grantReadWriteData(api); // the default role trusts lambda.amazonaws.com\n```\n\n- Requests handled by one environment share module-level state, so keep handlers concurrency-safe.\n- Environment variable names starting with `AWS_` are reserved.\n- **Renaming the function replaces it and changes its URL.** A generated name depends on the construct path, so moving the construct renames it too.\n\n### Bundling TypeScript with `NodejsWebFunction`\n\n`NodejsWebFunction` is a `WebFunction` that bundles your server from a TypeScript or JavaScript entry file with esbuild, like `NodejsFunction` does for Lambda functions:\n\n```ts\nnew NodejsWebFunction(this, 'Api', {\n entry: 'src/server.ts',\n authType: WebFunctionAuthType.AWS_IAM,\n bundling: {\n minify: true, // default true\n sourceMap: true, // default true\n format: lambdaNodejs.OutputFormat.ESM, // default ESM (index.mjs); CJS gives index.js\n externalModules: [], // default: bundle everything you import\n },\n});\n```\n\n- **Defaults:** `runtime` is `NODEJS_24_X`, and the esbuild target follows the runtime (`node24`). The project root is the directory of the nearest lock file above `entry` (override it with `depsLockFilePath` or `projectRoot`).\n- **It also sets what a `lambda.Code` can't:** the entry point that matches the bundle, and `NODE_OPTIONS=--enable-source-maps` when source maps are on, appended to any `NODE_OPTIONS` you set, so stack traces point at your `.ts` files (e.g. `/var/task/src/server.ts:22:12`). Source map paths are relative to the project root, so no build-machine paths are deployed.\n- **ESM bundles include a `require` shim**, so CommonJS dependencies that load Node.js built-ins (Express, for example) work.\n- **The AWS SDK is bundled like any other dependency**, since the runtime has none. Only the clients you import are included.\n- **Bundling runs locally** when esbuild is installed in your project, and otherwise in Docker (an arm64 AWS SAM build image; set `forceDockerBundling` to always use Docker).\n- **Not yet supported:** installing native modules next to the bundle (`nodeModules`) and command hooks. For native dependencies, use `WebFunction` with `Code.fromAsset(..., { bundling: { image, command } })`.\n\n### Code\n\n`code` takes any `lambda.Code` that produces a zip in S3: `fromAsset`, `fromBucket`/`fromBucketV2`, `fromCustomCommand`, `fromDockerBuild`. Inline code and container images fail at synth time.\n\nLambda Web Functions download code as the `lambda.amazonaws.com` service principal, from a **versioned** bucket, and the CDK bootstrap bucket allows neither. So each stack gets a small code bucket, and the code is copied into it on deploy. The bucket is emptied and deleted with the stack.\n\nCode copies, log groups in other regions, revision cleanup and the bucket's emptying run in one custom resource Lambda per stack. Its logs go to a log group the stack owns, kept for a month and deleted with the stack.\n\n## Revisions\n\nAny change to code or configuration creates a new **revision** (`fn.currentRevision`), and endpoints switch to it once it's ready. A failed deployment rolls back to the previous revision. If nothing changed, nothing is deployed.\n\nEarlier revisions are kept, so you can roll back or route traffic to them. After each deployment, the construct deletes the oldest beyond `revisionRetention` (default 20, up to 50). It never deletes a revision an endpoint routes to, or one the previous deployment used, which a rollback returns to.\n\n```ts\nnew WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n revisionRetention: 5,\n});\n```\n\n### Routing to earlier revisions\n\nReference an earlier revision by its ID (for example from a `CfnOutput` of `fn.currentRevision.revisionId`, or `aws lambda-web list-web-function-revisions`). Then pin an endpoint to it, or split traffic between two revisions:\n\n```ts\nconst previous = WebFunctionRevision.fromRevisionAttributes(this, 'Previous', {\n webFunction: fn,\n revisionId: 'rev-a1b2c',\n});\n\n// Keep the default endpoint on the previous revision, and send 10% to the new one:\nfn.endpoint.routeTraffic(previous, [{ revision: fn.currentRevision, weight: 0.1 }]);\n\n// Or a second endpoint that stays on the previous revision while fn.endpoint moves on:\nfn.addEndpoint('Stable', { authType: WebFunctionAuthType.AWS_IAM, revision: previous });\n```\n\n- An endpoint routes to at most two revisions. The additional revision's `weight` is a whole percentage, from 0.01 to 0.99.\n- To promote, remove `routeTraffic` (or `revision`) and deploy: the endpoint serves the current revision again.\n- Lambda Web Function metrics have no revision dimension. To compare a split's revisions, log a version you control (for example an environment variable) from your application.\n\n### Canary and linear deployments\n\nBy default an endpoint moves all its traffic to a new revision at once. With `deployment`, it moves in steps instead, watching CloudWatch alarms: if one goes into ALARM, the endpoint goes back to the revision it served before and the deployment fails, so CloudFormation rolls the stack back.\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n // 10% of the traffic for 10 minutes, then all of it; back if more than 2% of requests get a 5XX.\n deployment: WebFunctionDeployment.canary({ percent: 10, bake: Duration.minutes(10), rollbackOn: { serverErrorRate: 2 } }),\n },\n});\n\n// 25% more every 5 minutes, watching an alarm of your own. Each endpoint has its own deployment.\n// errorRate: any cloudwatch.IAlarm, e.g. on a metric your application publishes.\napi.addEndpoint('Public', {\n authType: WebFunctionAuthType.NONE,\n deployment: WebFunctionDeployment.linear({ percent: 25, interval: Duration.minutes(5), alarms: [errorRate] }),\n});\n```\n\n| | Steps | Limits |\n|---|---|---|\n| `allAtOnce()` (default) | 100% | |\n| `canary({ percent, bake })` | `percent`, then 100% after `bake` | `percent` 1–99, `bake` 1–45 minutes |\n| `linear({ percent, interval })` | `percent` more every `interval` | `percent` 5–50, `interval` from 1 minute, at most 45 minutes in all |\n\nHow it works:\n\n- Each deployment that creates a revision (code or configuration) moves the traffic from the revision the endpoint serves at that moment, which is also what it goes back to. If someone switched the endpoint outside CloudFormation, the deployment starts from there.\n- Each step waits until every region of a `MULTI_REGION` or `PER_REGION` endpoint has applied it (usually about 15 seconds), and if a region fails to update, the endpoint goes back as for an alarm. The bake or interval counts from the start of the step.\n- Alarms are checked before the first step (an alarm already in ALARM stops the deployment before any traffic moves), throughout every step, and once the new revision has all the traffic. They can be in any region, and composite alarms work. `INSUFFICIENT_DATA` doesn't stop a deployment.\n- A rollback of the stack, for any reason, moves the traffic back at once, without waiting or checking alarms.\n- A stack's first deployment, and a new endpoint (including one renamed by a region change), serve the revision at once: there's nothing to move from.\n- A deployment can take up to an hour: CloudFormation waits for it before it updates the endpoint. Deployments of different endpoints run in parallel.\n- A canary or linear endpoint always moves to the current revision, so it can't also use `revision`, `additionalRevisions` or `routeTraffic()`. Use `allAtOnce()` to deploy a fix immediately, for example while an alarm is in ALARM.\n\n#### Rollback alarms\n\n`rollbackOn` makes the endpoint create alarms on its own error rates, and the deployment watches them alongside any `alarms` you pass:\n\n| `rollbackOn` | Default | |\n|---|---|---|\n| `serverErrorRate` | none | roll back when more than this % of requests get a 5XX |\n| `clientErrorRate` | none | the same for 4XX (including 429s from `rateLimit` and `maxEnvironments`) |\n| `minimumRequests` | 10 | periods with fewer requests don't count, so one failed request out of two doesn't roll back |\n| `period`, `evaluationPeriods` | 1 minute, 2 | consecutive periods over the threshold before rolling back |\n\n- **One alarm per threshold in every region the endpoint serves from.** Metrics are published in the region that served the request, and an alarm can only watch metrics in its own region. The home region's alarm is a normal CloudFormation alarm; the others are created and deleted with the endpoint by a custom resource, and named `LambdaWeb-<function>-<endpoint>-5xx-rate` (or `-4xx-rate`). `endpoint.rollbackAlarms` lists them all, e.g. to add notifications to the home region's.\n- **The alarms see the whole endpoint.** Lambda Web Function metrics have no revision dimension, so at 10% a new revision's errors are about a tenth of the endpoint's: set the threshold low enough to notice that, or alarm on metrics your application publishes with its version.\n- **5XX includes the platform's 503s** while the endpoint scales up for a sudden burst, not only your application's errors.\n- **A step should outlast the alarm.** CloudWatch needs `period` × `evaluationPeriods`, plus a couple of minutes of delay, to fire; the construct warns when a canary's bake or a linear interval is shorter.\n\nThe deployment runs in a few resources per stack, created on first use: two Lambda functions, a Step Functions state machine that calls them every 15 seconds, and a log group.\n\n## Metrics\n\nEndpoints and functions have helpers for their CloudWatch metrics (namespace `AWS/Lambda/Web`), like `lambda.Function`'s:\n\n```ts\nfn.endpoint.metricServerErrorRate().createAlarm(this, 'ErrorRate', { threshold: 1, evaluationPeriods: 3 });\nfn.endpoint.metricRequestThrottles().createAlarm(this, 'Throttled', { threshold: 10, evaluationPeriods: 3 });\nfn.metricConcurrentRequests().createAlarm(this, 'Saturated', { threshold: 60, evaluationPeriods: 3 });\n```\n\n| Endpoint | Metric |\n|---|---|\n| `metricRequests()` | `ExecutedRequests` (there's no separate 2XX count) |\n| `metricClientErrors()`, `metricServerErrors()` | `HTTPResponseStatusClass4XX`, `HTTPResponseStatusClass5XX` |\n| `metricClientErrorRate()`, `metricServerErrorRate()` | 4XX or 5XX as a % of requests (math expression) |\n| `metricActiveEnvironments()` | `EndpointActiveEnvironments`, to compare with `maxEnvironments` |\n| `metricRequestThrottles()`, `metricEnvironmentThrottles()` | 429s from `rateLimit` and from `maxEnvironments` |\n\n| Function | Metric |\n|---|---|\n| `metricConcurrentRequests()` | `EnvironmentConcurrentRequests` (maximum), to compare with `maxConcurrencyPerEnvironment` |\n| `metricMaxMemoryUsage()` | `EnvironmentMaxMemoryUsage` (maximum) |\n| `metricActiveTime()`, `metricCpuTime()`, `metricResponseBytes()` | `EnvironmentActiveTime`, `EnvironmentCPUTime`, `ResponseBytes` |\n\n- **Metrics stay in the region that served the request**; unlike logs, they aren't copied to the home region. Every helper takes `region`. Dashboards can show any region, but an alarm can only use metrics from its own stack's region.\n- 4XX, 5XX and the throttle metrics only exist once they're non-zero: alarm on them with `treatMissingData: NOT_BREACHING`. The rate helpers count missing errors as 0.\n- There's no latency metric. Publish one from your application (e.g. with the CloudWatch embedded metric format).\n\n## Logs in every region\n\nWeb Functions log in two tiers:\n\n```text\n every serving region home region\n ┌──────────────────┐ ┌──────────────────────────────────────────┐\n │ <group>.local │── copied ───►│ <group> every region's logs │\n │ (that region's │ (seconds) │ streams …[rev]<instance>-<acct>-<region> │\n │ environments) │ │ <group>.local (home-region traffic) │\n └──────────────────┘ └──────────────────────────────────────────┘\n```\n\n**Query `fn.logGroup`**, the home-region group that receives every region's logs. The service would create missing groups without retention and never delete them, so the construct creates and owns all of them: both home-region groups, and `<group>.local` in every other region of the endpoint.\n\n```ts\nnew WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n logRetention: logs.RetentionDays.THREE_MONTHS, // default ONE_MONTH, every group in every region\n logRemovalPolicy: RemovalPolicy.DESTROY, // default RETAIN\n applicationLogLevelV2: lambda.ApplicationLogLevel.WARN,\n systemLogLevelV2: lambda.SystemLogLevel.INFO, // DEBUG, INFO or WARN\n});\n```\n\n- The default group is `/aws/lambda/web/<function name>`. Log lines are JSON; application lines carry `requestId`, `endpointName` and `region`.\n- Every event is stored twice (`.local` plus the home-region copy), so expect about double log ingestion, plus cross-region transfer.\n- With `DESTROY`, deletion waits about a minute after the function is gone, because environments flush their last lines late.\n- Subscribe only to `fn.logGroup`: subscribing to the `.local` groups as well delivers every event twice.\n\n## Limitations\n\n- Not yet supported: VPC access (network connectors), resource-policy permissions, KMS encryption, tracing, and a CloudFront origin.\n- `cdk deploy --hotswap` and `cdk watch` don't support Web Functions.\n- Quotas: 10 endpoints and about 50 revisions per function (Lambda cleans up older revisions automatically), and 10,000 requests per second per endpoint. Per account and region: 100,000 requests per second and 2,000 Arm64 vCPUs (each execution environment uses 2). The account quotas are adjustable, and new accounts start lower. See [Lambda quotas](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html).\n\n## Development\n\nTooling is pinned in `mise.toml` (Node 24, AWS CDK CLI). Personal settings, such as the AWS profile for the live end-to-end tests, go in a git-ignored `mise.local.toml`.\n\n```bash\nmise install\nnpx projen build # compile, unit tests, lint, API docs\nnpx projen e2e # deploy, verify and destroy real stacks in three regions (needs AWS credentials)\n```\n"
9748
+ "markdown": "# CDK constructs for AWS Lambda Web Functions\n\n<!--BEGIN STABILITY BANNER-->\n\n---\n\n![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)\n\n> The APIs of higher level constructs in this module are experimental and under active development.\n> They are subject to non-backward compatible changes or removal in any future version. These are\n> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be\n> announced in the release notes. This means that while you may use them, you may need to update\n> your source code when upgrading to a newer version of this package.\n\n---\n\n<!--END STABILITY BANNER-->\n\n[AWS Lambda Web Functions](https://docs.aws.amazon.com/lambda/latest/dg/web-functions.html) run an ordinary Node.js HTTP server (Express, Fastify, Hono, `node:http`) on Lambda and give it an HTTPS endpoint, optionally served from several regions. `WebFunction` deploys one, following the conventions of `aws-cdk-lib/aws-lambda` where the two services overlap.\n\n```ts fixture=bare\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport { WebFunction, WebFunctionAuthType, WebFunctionEndpointType } from '@ashishpandeyone/cdk-lambda-web-function';\n\nconst fn = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n endpointType: WebFunctionEndpointType.MULTI_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n },\n});\n\nnew CfnOutput(this, 'Url', { value: fn.endpoint.url }); // https://<id>.lambda-web.global.on.aws\n```\n\nThe stack's region is the function's **home region**. Multi-region endpoints need a stack with an explicit `env.region`.\n\n## Installation\n\n```bash\nnpm install @ashishpandeyone/cdk-lambda-web-function\n```\n\nIt needs `aws-cdk-lib` 2.273.0 or later and `constructs` 10.5.1 or later (peer dependencies), and Node.js 22 or later. The package is published for TypeScript and JavaScript only.\n\n## Writing the server\n\n1. Listen on the host and port in **`AWS_LAMBDA_HTTP_ENDPOINT`** (`0.0.0.0:3000` today). `PORT` is not set.\n2. Start listening within **10 seconds**, or initialisation fails with `Application.TimeoutListenError`.\n3. Put the entry file at the root of your bundle as **`index.js`**, or set `entrypoint`.\n4. The runtime has **no AWS SDK**: bundle the clients you import.\n5. Code runs on **arm64**.\n\n```js\nconst express = require('express');\n\nconst app = express();\napp.get('/', (req, res) => res.json({ hello: 'world', region: process.env.AWS_REGION }));\n\nconst [host, port] = process.env.AWS_LAMBDA_HTTP_ENDPOINT.split(':');\napp.listen(Number(port), host);\n```\n\nRequests carry `lambda-web-request-id` and `lambda-web-endpoint-name` headers.\n\n## Regions and endpoints\n\nEach `WebFunction` has a default endpoint, `fn.endpoint`, configured with the `endpoint` property. [Add more](#more-endpoints) with `fn.addEndpoint()`.\n\n| `endpointType` | URL | Routing |\n|---|---|---|\n| `HOME_REGION` (default) | `https://<id>.<cell>.lambda-web.<home>.on.aws` | home region only |\n| `MULTI_REGION` | one global `https://<id>.lambda-web.global.on.aws` | nearest region |\n| `PER_REGION` | one URL per region, from `fn.endpoint.regionalUrl(region)` | the region in the hostname |\n\n```ts\nconst perRegion = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n endpointType: WebFunctionEndpointType.PER_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n },\n});\n\nnew CfnOutput(this, 'UsEast1Url', { value: perRegion.endpoint.regionalUrl('us-east-1') });\n// perRegion.endpoint.regions is ['<home region>', 'eu-west-1', 'us-east-1']\n```\n\n- `MULTI_REGION` and `PER_REGION` need at least one region besides the home region; `HOME_REGION` takes none.\n- A MultiRegion endpoint takes about a minute to create.\n- Lambda routes a `MULTI_REGION` endpoint by latency, not by health: it doesn't fail over when a region has problems.\n\n### More endpoints\n\nA function can have up to 10 endpoints, each with its own URL, authentication, regions and limits. For example, a public endpoint next to an IAM-only global one:\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.NONE, // the default endpoint is public\n endpoint: { rateLimit: 1000 }, // requests per second\n});\n\nconst internal = api.addEndpoint('Internal', {\n authType: WebFunctionAuthType.AWS_IAM,\n endpointType: WebFunctionEndpointType.MULTI_REGION,\n regions: ['us-east-1', 'eu-west-1'],\n description: 'Service-to-service traffic',\n maxEnvironments: 50,\n});\ninternal.grantInvoke(consumerRole);\nnew CfnOutput(this, 'InternalUrl', { value: internal.url });\n```\n\n- `rateLimit` takes 0 (blocks all traffic), 100–1,000 in steps of 100, or 2,000–10,000 in steps of 1,000; excess requests get HTTP 429. `maxEnvironments` takes 2–10,000.\n- **Both limits apply separately in each region** an endpoint serves from: a 3-region endpoint with `rateLimit: 1000` accepts up to 1,000 requests per second in each region.\n- Endpoints can serve the same regions. The construct owns one `.local` log group per region, whichever endpoints serve it.\n\n### Changing regions or the endpoint type\n\nAn endpoint's type and regions can't change in place: a change creates a **new endpoint with a new URL**, and the old one is deleted once the new one is live. Two endpoints of one function can't share a name, so:\n\n| `endpointName` | Physical name | Changing `regions` or `endpointType` |\n|---|---|---|\n| omitted (recommended) | `default-<hash>` for `fn.endpoint`, `<id>-<hash>` for added endpoints; the hash covers the type and regions | works: new endpoint, new URL |\n| set, e.g. `'live'` | `live` | also change the name in the same deployment, or it fails with *The endpoint live already exists* (the stack rolls back and the old endpoint keeps serving) |\n\nThe construct warns at synth time when `endpointName` is set.\n\n## Authentication and invoking\n\n| `authType` | Meaning |\n|---|---|\n| `AWS_IAM` | Callers sign requests (SigV4 or SigV4a, signing name `lambda`) and need `lambda:InvokeWebFunctionEndpoint` |\n| `NONE` | **Public**: Lambda does no authentication; your application does (JWT, sessions). The `Authorization` header reaches your application untouched. The construct warns at synth time |\n\n```ts\nfn.grants.invoke(consumerRole); // or fn.grantInvoke(consumerRole), as on lambda.Function\n```\n\nThe grant is on the endpoint's home-region ARN, which IAM evaluates in every region the endpoint serves from, including the global URL. `fn.grants` covers the default endpoint only; grant other endpoints with their own `grantInvoke()` or `grants.invoke()`.\n\n| Endpoint | How to sign |\n|---|---|\n| `HOME_REGION` | SigV4 for the home region |\n| `PER_REGION` | SigV4 for the hostname's region, or SigV4a |\n| `MULTI_REGION` | **SigV4a with region set `*`**: you can't know which region will serve the request |\n\n```js\nimport { SignatureV4a } from '@smithy/signature-v4a';\nimport { Sha256 } from '@aws-crypto/sha256-js';\nimport { fromNodeProviderChain } from '@aws-sdk/credential-providers';\n\nconst host = new URL(url).hostname; // url: the endpoint's URL\nconst signer = new SignatureV4a({ service: 'lambda', region: '*', sha256: Sha256, credentials: fromNodeProviderChain() });\nconst signed = await signer.sign(\n { method: 'GET', protocol: 'https:', hostname: host, path: '/', headers: { host } },\n { signingRegion: '*' },\n);\nconst response = await fetch(`https://${host}/`, { headers: signed.headers });\n```\n\n### Other accounts and AWS services\n\nA caller in another account needs permission twice: in its own IAM policy, and in the function's **resource policy**. `grantInvoke` handles the function's side: a role in the function's account only gets an IAM policy statement, while a principal in another account or an AWS service also gets a statement in the resource policy.\n\n```ts\nfn.grantInvoke(iam.Role.fromRoleArn(this, 'Partner', 'arn:aws:iam::444455556666:role/caller'));\n```\n\nFor principals you can't grant to (a whole account, an organization, an AWS service with conditions), use `addPermission`. The `id` becomes the statement's `Sid`:\n\n```ts\nfn.addPermission('PartnerAccount', { principal: new iam.AccountPrincipal('444455556666') });\nfn.addPermission('MyOrg', { principal: new iam.OrganizationPrincipal('o-a1b2c3d4e5'), endpoint: fn.endpoint });\nfn.addPermission('Cdn', {\n principal: new iam.ServicePrincipal('cloudfront.amazonaws.com'),\n sourceArn: `arn:aws:cloudfront::${this.account}:distribution/EDFDVBD6EXAMPLE`,\n});\n```\n\n`addPermission` allows calling every endpoint unless you pass `endpoint`. For other actions, such as letting another account create revisions, use `fn.addToResourcePolicy(statement)`. Statements use the endpoint ARN for invoking and the function ARN for actions on the function.\n\n- **One resource policy per function, written by the function's stack.** The construct creates it (`AWS::Lambda::ResourcePolicy`) with the first statement. CloudFormation can't attach a second one: another stack, or a `CfnResourcePolicy` of your own on the function, fails at change-set validation with \"already exists\". If you attached one yourself, move its statements into `addPermission` or `addToResourcePolicy`. Each update of the policy replaces any statements added outside CloudFormation.\n- **Public policies are rejected.** Lambda refuses a policy that lets anyone call the function, and the construct fails synthesis first. A `*` principal is only accepted with a condition that pins the caller, such as `aws:PrincipalOrgID` (`iam.OrganizationPrincipal`) or `aws:SourceAccount`. For a public endpoint, use `authType: NONE`.\n- **Scope AWS services to your resource.** Lambda accepts a service principal with no condition, which would let that service call the endpoint on behalf of any account. The construct warns unless you give `sourceArn` or `sourceAccount` (or an `aws:SourceArn`, `aws:SourceAccount`, `aws:SourceOrgID` or `aws:SourceOrgPaths` condition).\n- Lambda copies the policy to every region the function's endpoints serve from. The copy is eventually consistent, and in tests changes applied in every region within seconds.\n\n### Functions defined elsewhere\n\nImport a Web Function defined in another stack or app to grant access to it, read its metrics, or reference its revisions:\n\n```ts\nconst orders = WebFunction.fromWebFunctionArn(this, 'Orders', 'arn:aws:lambda:us-east-1:111122223333:web-function/orders');\norders.grantInvoke(consumerRole); // every endpoint of the function\n\nconst live = WebFunction.fromWebFunctionAttributes(this, 'Live', {\n webFunctionName: 'orders', // in this stack's account and region\n endpointName: 'live', // grantInvoke allows this endpoint only\n});\nlive.metricConcurrentRequests().createAlarm(this, 'Busy', { threshold: 60, evaluationPeriods: 3 });\n```\n\nAn imported function's metrics default to its own region. Its endpoints, revisions and log groups stay with the stack that defines it.\n\nAn imported function's `grantInvoke` adds to the caller's IAM policy only, which is all a caller in the function's account needs. A caller in another account also needs the function's resource policy to allow it, which only the function's own stack can change: `addToResourcePolicy` on an imported function adds nothing and warns.\n\n## Configuration\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('build'),\n authType: WebFunctionAuthType.AWS_IAM,\n entrypoint: 'server.js', // default index.js\n webFunctionName: 'orders-api', // default: generated from the construct path\n description: 'Orders HTTP API',\n environment: { TABLE_NAME: table.tableName },\n timeout: Duration.seconds(60), // per request: 3 seconds to 15 minutes, default 30 seconds\n maxConcurrencyPerEnvironment: 32, // requests per environment at once: 1-128, default 64\n});\n\napi.addEnvironment('FEATURE_FLAG', 'on');\ntable.grantReadWriteData(api); // the default role trusts lambda.amazonaws.com\n```\n\n- **Each execution environment has 2 vCPUs and 2 GB of memory.** There's no memory setting as on Lambda functions; scale with `maxConcurrencyPerEnvironment` and more environments instead.\n- Requests handled by one environment share module-level state, so keep handlers concurrency-safe.\n- Environment variable names starting with `AWS_` are reserved.\n- **Renaming the function replaces it and changes its URL.** A generated name depends on the construct path, so moving the construct renames it too.\n\n### Bundling TypeScript with `NodejsWebFunction`\n\n`NodejsWebFunction` is a `WebFunction` that bundles your server from a TypeScript or JavaScript entry file with esbuild, like `NodejsFunction` does for Lambda functions:\n\n```ts\nnew NodejsWebFunction(this, 'Api', {\n entry: 'src/server.ts',\n authType: WebFunctionAuthType.AWS_IAM,\n bundling: {\n minify: true, // default true\n sourceMap: true, // default true\n format: lambdaNodejs.OutputFormat.ESM, // default ESM (index.mjs); CJS gives index.js\n externalModules: [], // default: bundle everything you import\n },\n});\n```\n\n- **Defaults:** `runtime` is `NODEJS_24_X`, and the esbuild target follows the runtime (`node24`). The project root is the directory of the nearest lock file above `entry` (override it with `depsLockFilePath` or `projectRoot`).\n- **It also sets what a `lambda.Code` can't:** the entry point that matches the bundle, and `NODE_OPTIONS=--enable-source-maps` when source maps are on, appended to any `NODE_OPTIONS` you set, so stack traces point at your `.ts` files (e.g. `/var/task/src/server.ts:22:12`). Source map paths are relative to the project root, so no build-machine paths are deployed.\n- **ESM bundles include a `require` shim**, so CommonJS dependencies that load Node.js built-ins (Express, for example) work.\n- **The AWS SDK is bundled like any other dependency**, since the runtime has none. Only the clients you import are included.\n- **Bundling runs locally** when esbuild is installed in your project, and otherwise in Docker (an arm64 AWS SAM build image; set `forceDockerBundling` to always use Docker).\n- **Not yet supported:** installing native modules next to the bundle (`nodeModules`) and command hooks. For native dependencies, use `WebFunction` with `Code.fromAsset(..., { bundling: { image, command } })`.\n\n### Code\n\n`code` takes any `lambda.Code` that produces a zip in S3: `fromAsset`, `fromBucket`/`fromBucketV2`, `fromCustomCommand`, `fromDockerBuild`. Inline code and container images fail at synth time.\n\nLambda Web Functions download code as the `lambda.amazonaws.com` service principal, from a **versioned** bucket, and the CDK bootstrap bucket allows neither. So each stack gets a small code bucket, and the code is copied into it on deploy. The bucket is emptied and deleted with the stack.\n\nCopying code, managing the function's log groups in every region, looking up regional URLs, cleaning up old revisions, creating rollback alarms in other regions and emptying the code bucket all run in one custom resource Lambda per stack. Its logs go to a log group the stack owns, kept for a month and deleted with the stack.\n\n## Revisions\n\nAny change to code or configuration creates a new **revision** (`fn.currentRevision`), and endpoints switch to it once it's ready. A failed deployment rolls back to the previous revision. If nothing changed, nothing is deployed.\n\nEarlier revisions are kept, so you can roll back or route traffic to them. After each deployment, the construct deletes the oldest beyond `revisionRetention` (default 20, up to 50). It never deletes a revision an endpoint routes to, or one the previous deployment used, which a rollback returns to.\n\n```ts\nnew WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n revisionRetention: 5,\n});\n```\n\n### Routing to earlier revisions\n\nReference an earlier revision by its ID (for example from a `CfnOutput` of `fn.currentRevision.revisionId`, or `aws lambda-web list-web-function-revisions`). Then pin an endpoint to it, or split traffic between two revisions:\n\n```ts\nconst previous = WebFunctionRevision.fromRevisionAttributes(this, 'Previous', {\n webFunction: fn,\n revisionId: 'rev-a1b2c',\n});\n\n// Keep the default endpoint on the previous revision, and send 10% to the new one:\nfn.endpoint.routeTraffic(previous, [{ revision: fn.currentRevision, weight: 0.1 }]);\n\n// Or a second endpoint that stays on the previous revision while fn.endpoint moves on:\nfn.addEndpoint('Stable', { authType: WebFunctionAuthType.AWS_IAM, revision: previous });\n```\n\n- An endpoint routes to at most two revisions. The additional revision's `weight` is a whole percentage, from 0.01 to 0.99.\n- To promote, remove `routeTraffic` (or `revision`) and deploy: the endpoint serves the current revision again.\n- Lambda Web Function metrics have no revision dimension. To compare a split's revisions, log a version you control (for example an environment variable) from your application.\n\n### Canary and linear deployments\n\nBy default an endpoint moves all its traffic to a new revision at once. With `deployment`, it moves in steps instead, watching CloudWatch alarms: if one goes into ALARM, the endpoint goes back to the revision it served before and the deployment fails, so CloudFormation rolls the stack back.\n\n```ts\nconst api = new WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n endpoint: {\n // 10% of the traffic for 10 minutes, then all of it; back if more than 2% of requests get a 5XX.\n deployment: WebFunctionDeployment.canary({ percent: 10, bake: Duration.minutes(10), rollbackOn: { serverErrorRate: 2 } }),\n },\n});\n\n// 25% more every 5 minutes, watching an alarm of your own. Each endpoint has its own deployment.\n// errorRate: any cloudwatch.IAlarm, e.g. on a metric your application publishes.\napi.addEndpoint('Public', {\n authType: WebFunctionAuthType.NONE,\n deployment: WebFunctionDeployment.linear({ percent: 25, interval: Duration.minutes(5), alarms: [errorRate] }),\n});\n```\n\n| | Steps | Limits |\n|---|---|---|\n| `allAtOnce()` (default) | 100% | |\n| `canary({ percent, bake })` | `percent`, then 100% after `bake` | `percent` 1–99, `bake` 1–45 minutes |\n| `linear({ percent, interval })` | `percent` more every `interval` | `percent` 5–50, `interval` from 1 minute, at most 45 minutes in all |\n\nHow it works:\n\n- Each deployment that creates a revision (code or configuration) moves the traffic from the revision the endpoint serves at that moment, which is also what it goes back to. If someone switched the endpoint outside CloudFormation, the deployment starts from there.\n- Each step waits until every region of a `MULTI_REGION` or `PER_REGION` endpoint has applied it (usually about 15 seconds), and if a region fails to update, the endpoint goes back as for an alarm. The bake or interval counts from the start of the step.\n- Alarms are checked before the first step (an alarm already in ALARM stops the deployment before any traffic moves), throughout every step, and once the new revision has all the traffic. They can be in any region, and composite alarms work. `INSUFFICIENT_DATA` doesn't stop a deployment.\n- A rollback of the stack, for any reason, moves the traffic back at once, without waiting or checking alarms.\n- A stack's first deployment, and a new endpoint (including one renamed by a region change), serve the revision at once: there's nothing to move from.\n- A deployment can take up to an hour: CloudFormation waits for it before it updates the endpoint. Deployments of different endpoints run in parallel.\n- A canary or linear endpoint always moves to the current revision, so it can't also use `revision`, `additionalRevisions` or `routeTraffic()`. Use `allAtOnce()` to deploy a fix immediately, for example while an alarm is in ALARM.\n\n#### Rollback alarms\n\n`rollbackOn` makes the endpoint create alarms on its own error rates, and the deployment watches them alongside any `alarms` you pass:\n\n| `rollbackOn` | Default | |\n|---|---|---|\n| `serverErrorRate` | none | roll back when more than this % of requests get a 5XX |\n| `clientErrorRate` | none | the same for 4XX (including 429s from `rateLimit` and `maxEnvironments`) |\n| `minimumRequests` | 10 | periods with fewer requests don't count, so one failed request out of two doesn't roll back |\n| `period`, `evaluationPeriods` | 1 minute, 2 | consecutive periods over the threshold before rolling back |\n\n- **One alarm per threshold in every region the endpoint serves from.** Metrics are published in the region that served the request, and an alarm can only watch metrics in its own region. The home region's alarm is a normal CloudFormation alarm; the others are created and deleted with the endpoint by a custom resource, and named `LambdaWeb-<function>-<endpoint>-5xx-rate` (or `-4xx-rate`). `endpoint.rollbackAlarms` lists them all, e.g. to add notifications to the home region's.\n- **The alarms see the whole endpoint.** Lambda Web Function metrics have no revision dimension, so at 10% a new revision's errors are about a tenth of the endpoint's: set the threshold low enough to notice that, or alarm on metrics your application publishes with its version.\n- **5XX includes the platform's 503s** while the endpoint scales up for a sudden burst, not only your application's errors.\n- **A step should outlast the alarm.** CloudWatch needs `period` × `evaluationPeriods`, plus a couple of minutes of delay, to fire; the construct warns when a canary's bake or a linear interval is shorter.\n\nThe deployment runs in a few resources per stack, created on first use: two Lambda functions, a Step Functions state machine that calls them every 15 seconds, and a log group.\n\n## Metrics\n\nEndpoints and functions have helpers for their CloudWatch metrics (namespace `AWS/Lambda/Web`), like `lambda.Function`'s:\n\n```ts\nfn.endpoint.metricServerErrorRate().createAlarm(this, 'ErrorRate', { threshold: 1, evaluationPeriods: 3 });\nfn.endpoint.metricRequestThrottles().createAlarm(this, 'Throttled', { threshold: 10, evaluationPeriods: 3 });\nfn.metricConcurrentRequests().createAlarm(this, 'Saturated', { threshold: 60, evaluationPeriods: 3 });\n```\n\n| Endpoint | Metric |\n|---|---|\n| `metricRequests()` | `ExecutedRequests` (there's no separate 2XX count) |\n| `metricClientErrors()`, `metricServerErrors()` | `HTTPResponseStatusClass4XX`, `HTTPResponseStatusClass5XX` |\n| `metricClientErrorRate()`, `metricServerErrorRate()` | 4XX or 5XX as a % of requests (math expression) |\n| `metricActiveEnvironments()` | `EndpointActiveEnvironments`, to compare with `maxEnvironments` |\n| `metricRequestThrottles()`, `metricEnvironmentThrottles()` | 429s from `rateLimit` and from `maxEnvironments` |\n\n| Function | Metric |\n|---|---|\n| `metricConcurrentRequests()` | `EnvironmentConcurrentRequests` (maximum), to compare with `maxConcurrencyPerEnvironment` |\n| `metricMaxMemoryUsage()` | `EnvironmentMaxMemoryUsage` (maximum) |\n| `metricActiveTime()`, `metricCpuTime()`, `metricResponseBytes()` | `EnvironmentActiveTime`, `EnvironmentCPUTime`, `ResponseBytes` |\n\n- **Metrics stay in the region that served the request**; unlike logs, they aren't copied to the home region. Every helper takes `region`. Dashboards can show any region, but an alarm can only use metrics from its own stack's region.\n- 4XX, 5XX and the throttle metrics only exist once they're non-zero: alarm on them with `treatMissingData: NOT_BREACHING`. The rate helpers count missing errors as 0.\n- There's no latency metric. Publish one from your application (e.g. with the CloudWatch embedded metric format).\n\n## Logs in every region\n\nWeb Functions log in two tiers:\n\n```text\n every serving region home region\n ┌──────────────────┐ ┌──────────────────────────────────────────┐\n │ <group>.local │── copied ───►│ <group> every region's logs │\n │ (that region's │ (seconds) │ streams …[rev]<instance>-<acct>-<region> │\n │ environments) │ │ <group>.local (home-region traffic) │\n └──────────────────┘ └──────────────────────────────────────────┘\n```\n\n**Query `fn.logGroup`**, the home-region group that receives every region's logs. The service would create missing groups without retention and never delete them, so the construct creates and owns all of them: both home-region groups, and `<group>.local` in every other region any of its endpoints serves from.\n\n```ts\nnew WebFunction(this, 'Api', {\n runtime: lambda.Runtime.NODEJS_24_X,\n code: lambda.Code.fromAsset('dist'),\n authType: WebFunctionAuthType.AWS_IAM,\n logRetention: logs.RetentionDays.THREE_MONTHS, // default ONE_MONTH, every group in every region\n logRemovalPolicy: RemovalPolicy.DESTROY, // default RETAIN\n applicationLogLevelV2: lambda.ApplicationLogLevel.WARN,\n systemLogLevelV2: lambda.SystemLogLevel.INFO, // DEBUG, INFO or WARN\n});\n```\n\n- The default group is `/aws/lambda/web/<function name>`. Log lines are JSON; application lines carry `requestId`, `endpointName` and `region`.\n- Every event is stored twice (`.local` plus the home-region copy), so expect about double log ingestion, plus cross-region transfer.\n- With `DESTROY`, deletion waits about a minute after the function is gone, because environments flush their last lines late.\n- Subscribe only to `fn.logGroup`: subscribing to the `.local` groups as well delivers every event twice.\n\n## Limitations\n\n- Not yet supported: VPC access (network connectors), KMS encryption, tracing, and a CloudFront origin.\n- **Hotswap skips Web Functions without a warning.** `cdk deploy --hotswap` and `cdk watch`, which hotswaps by default, report `(no changes)` for a code or configuration change and the endpoint keeps serving the old revision. Use `cdk watch --hotswap-fallback` (or `cdk deploy --hotswap-fallback`): it deploys Web Function changes through CloudFormation, in about 40 seconds for a home-region endpoint.\n- Fixed limits: 512 MB of code (unzipped) and 32 KB of environment variables per revision, 512 MB of `/tmp` per execution environment, and 128 KiB of headers per request.\n- Quotas: 10 endpoints and about 50 revisions per function (Lambda cleans up older revisions automatically), and 10,000 requests per second per endpoint. Per account and region: 100,000 requests per second and 2,000 Arm64 vCPUs (each execution environment uses 2). The account quotas are adjustable, and new accounts start lower. See [Lambda quotas](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html).\n\n## Development\n\nTooling is pinned in `mise.toml` (Node 24, AWS CDK CLI). Personal settings, such as the AWS profile for the live end-to-end tests, go in a git-ignored `mise.local.toml`.\n\n```bash\nmise install\nnpx projen build # compile, unit tests, lint, API docs\nnpx projen e2e # deploy, verify and destroy real stacks in three regions (needs AWS credentials)\n```\n"
9749
9749
  },
9750
9750
  "repository": {
9751
9751
  "type": "git",
@@ -9840,30 +9840,32 @@
9840
9840
  "@ashishpandeyone/cdk-lambda-web-function.IWebFunction": {
9841
9841
  "assembly": "@ashishpandeyone/cdk-lambda-web-function",
9842
9842
  "docs": {
9843
+ "remarks": "`addToResourcePolicy` adds to the function's resource policy (who else may call or manage it). A `WebFunction` has\none, created by its stack on the first statement. An imported function's policy belongs to the stack that created\nit, so the statement isn't added (`statementAdded: false`).",
9843
9844
  "stability": "experimental",
9844
9845
  "summary": "A Lambda Web Function, created in this app (`WebFunction`) or imported (`WebFunction.fromWebFunctionArn`)."
9845
9846
  },
9846
9847
  "fqn": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
9847
9848
  "interfaces": [
9848
9849
  "aws-cdk-lib.IResource",
9849
- "aws-cdk-lib.interfaces.aws_lambda.IWebFunctionRef"
9850
+ "aws-cdk-lib.interfaces.aws_lambda.IWebFunctionRef",
9851
+ "aws-cdk-lib.aws_iam.IResourceWithPolicy"
9850
9852
  ],
9851
9853
  "kind": "interface",
9852
9854
  "locationInModule": {
9853
9855
  "filename": "src/web-function.ts",
9854
- "line": 155
9856
+ "line": 160
9855
9857
  },
9856
9858
  "methods": [
9857
9859
  {
9858
9860
  "abstract": true,
9859
9861
  "docs": {
9860
- "remarks": "for an imported function, the endpoint named in its attributes, or every endpoint.\n\nThis adds to the grantee's IAM policy. For a function in another account, its resource policy must also allow the grantee.\n[disable-awslint:no-grants]",
9862
+ "remarks": "for an imported function, the endpoint named in its attributes, or every endpoint.\n\nFor a `WebFunction`, a grantee in this account gets an IAM policy statement; another account or an AWS service\nalso gets a statement in the function's resource policy. For an imported function, only the grantee's IAM policy\nchanges: across accounts, the function's own resource policy must also allow the grantee.\n[disable-awslint:no-grants]",
9861
9863
  "stability": "experimental",
9862
9864
  "summary": "Allows `grantee` to call the function's endpoint (`lambda:InvokeWebFunctionEndpoint`): the default endpoint of a `WebFunction`;"
9863
9865
  },
9864
9866
  "locationInModule": {
9865
9867
  "filename": "src/web-function.ts",
9866
- "line": 177
9868
+ "line": 184
9867
9869
  },
9868
9870
  "name": "grantInvoke",
9869
9871
  "parameters": [
@@ -9888,7 +9890,7 @@
9888
9890
  },
9889
9891
  "locationInModule": {
9890
9892
  "filename": "src/web-function.ts",
9891
- "line": 182
9893
+ "line": 189
9892
9894
  },
9893
9895
  "name": "metric",
9894
9896
  "parameters": [
@@ -9920,7 +9922,7 @@
9920
9922
  },
9921
9923
  "locationInModule": {
9922
9924
  "filename": "src/web-function.ts",
9923
- "line": 185
9925
+ "line": 192
9924
9926
  },
9925
9927
  "name": "metricActiveTime",
9926
9928
  "parameters": [
@@ -9946,7 +9948,7 @@
9946
9948
  },
9947
9949
  "locationInModule": {
9948
9950
  "filename": "src/web-function.ts",
9949
- "line": 191
9951
+ "line": 198
9950
9952
  },
9951
9953
  "name": "metricConcurrentRequests",
9952
9954
  "parameters": [
@@ -9972,7 +9974,7 @@
9972
9974
  },
9973
9975
  "locationInModule": {
9974
9976
  "filename": "src/web-function.ts",
9975
- "line": 188
9977
+ "line": 195
9976
9978
  },
9977
9979
  "name": "metricCpuTime",
9978
9980
  "parameters": [
@@ -9998,7 +10000,7 @@
9998
10000
  },
9999
10001
  "locationInModule": {
10000
10002
  "filename": "src/web-function.ts",
10001
- "line": 194
10003
+ "line": 201
10002
10004
  },
10003
10005
  "name": "metricMaxMemoryUsage",
10004
10006
  "parameters": [
@@ -10024,7 +10026,7 @@
10024
10026
  },
10025
10027
  "locationInModule": {
10026
10028
  "filename": "src/web-function.ts",
10027
- "line": 197
10029
+ "line": 204
10028
10030
  },
10029
10031
  "name": "metricResponseBytes",
10030
10032
  "parameters": [
@@ -10057,7 +10059,7 @@
10057
10059
  "immutable": true,
10058
10060
  "locationInModule": {
10059
10061
  "filename": "src/web-function.ts",
10060
- "line": 168
10062
+ "line": 173
10061
10063
  },
10062
10064
  "name": "webFunctionArn",
10063
10065
  "type": {
@@ -10076,7 +10078,7 @@
10076
10078
  "immutable": true,
10077
10079
  "locationInModule": {
10078
10080
  "filename": "src/web-function.ts",
10079
- "line": 161
10081
+ "line": 166
10080
10082
  },
10081
10083
  "name": "webFunctionName",
10082
10084
  "type": {
@@ -10653,7 +10655,7 @@
10653
10655
  },
10654
10656
  "locationInModule": {
10655
10657
  "filename": "src/web-function.ts",
10656
- "line": 371
10658
+ "line": 420
10657
10659
  },
10658
10660
  "parameters": [
10659
10661
  {
@@ -10682,7 +10684,7 @@
10682
10684
  "kind": "class",
10683
10685
  "locationInModule": {
10684
10686
  "filename": "src/web-function.ts",
10685
- "line": 314
10687
+ "line": 361
10686
10688
  },
10687
10689
  "methods": [
10688
10690
  {
@@ -10692,7 +10694,7 @@
10692
10694
  },
10693
10695
  "locationInModule": {
10694
10696
  "filename": "src/web-function.ts",
10695
- "line": 318
10697
+ "line": 365
10696
10698
  },
10697
10699
  "name": "fromWebFunctionArn",
10698
10700
  "parameters": [
@@ -10729,7 +10731,7 @@
10729
10731
  },
10730
10732
  "locationInModule": {
10731
10733
  "filename": "src/web-function.ts",
10732
- "line": 332
10734
+ "line": 379
10733
10735
  },
10734
10736
  "name": "fromWebFunctionAttributes",
10735
10737
  "parameters": [
@@ -10766,7 +10768,7 @@
10766
10768
  },
10767
10769
  "locationInModule": {
10768
10770
  "filename": "src/web-function.ts",
10769
- "line": 325
10771
+ "line": 372
10770
10772
  },
10771
10773
  "name": "fromWebFunctionName",
10772
10774
  "parameters": [
@@ -10803,7 +10805,7 @@
10803
10805
  },
10804
10806
  "locationInModule": {
10805
10807
  "filename": "src/web-function.ts",
10806
- "line": 473
10808
+ "line": 522
10807
10809
  },
10808
10810
  "name": "addEndpoint",
10809
10811
  "parameters": [
@@ -10837,7 +10839,7 @@
10837
10839
  },
10838
10840
  "locationInModule": {
10839
10841
  "filename": "src/web-function.ts",
10840
- "line": 481
10842
+ "line": 530
10841
10843
  },
10842
10844
  "name": "addEnvironment",
10843
10845
  "parameters": [
@@ -10860,6 +10862,61 @@
10860
10862
  }
10861
10863
  }
10862
10864
  },
10865
+ {
10866
+ "docs": {
10867
+ "remarks": "For a role in this account, use `grantInvoke`.",
10868
+ "stability": "experimental",
10869
+ "summary": "Allows a principal in another account, an AWS service or an organization to call the function's endpoints, through the function's resource policy."
10870
+ },
10871
+ "locationInModule": {
10872
+ "filename": "src/web-function.ts",
10873
+ "line": 559
10874
+ },
10875
+ "name": "addPermission",
10876
+ "parameters": [
10877
+ {
10878
+ "docs": {
10879
+ "summary": "the statement ID (`Sid`): letters and digits, unique within the function."
10880
+ },
10881
+ "name": "id",
10882
+ "type": {
10883
+ "primitive": "string"
10884
+ }
10885
+ },
10886
+ {
10887
+ "name": "permission",
10888
+ "type": {
10889
+ "fqn": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionPermission"
10890
+ }
10891
+ }
10892
+ ]
10893
+ },
10894
+ {
10895
+ "docs": {
10896
+ "remarks": "The function has one resource policy (`AWS::Lambda::ResourcePolicy`), created on the first statement. This stack\nis its only writer: another stack or template can't also attach one, and changes made outside CloudFormation\nare overwritten by the next update of the policy.",
10897
+ "stability": "experimental",
10898
+ "summary": "Adds a statement to the function's resource policy, e.g. to let another account manage the function. For invoking, prefer `addPermission` or `grantInvoke`."
10899
+ },
10900
+ "locationInModule": {
10901
+ "filename": "src/web-function.ts",
10902
+ "line": 590
10903
+ },
10904
+ "name": "addToResourcePolicy",
10905
+ "overrides": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionBase",
10906
+ "parameters": [
10907
+ {
10908
+ "name": "statement",
10909
+ "type": {
10910
+ "fqn": "aws-cdk-lib.aws_iam.PolicyStatement"
10911
+ }
10912
+ }
10913
+ ],
10914
+ "returns": {
10915
+ "type": {
10916
+ "fqn": "aws-cdk-lib.aws_iam.AddToResourcePolicyResult"
10917
+ }
10918
+ }
10919
+ },
10863
10920
  {
10864
10921
  "docs": {
10865
10922
  "stability": "experimental",
@@ -10867,7 +10924,7 @@
10867
10924
  },
10868
10925
  "locationInModule": {
10869
10926
  "filename": "src/web-function.ts",
10870
- "line": 492
10927
+ "line": 541
10871
10928
  },
10872
10929
  "name": "addToRolePolicy",
10873
10930
  "parameters": [
@@ -10887,7 +10944,7 @@
10887
10944
  },
10888
10945
  "locationInModule": {
10889
10946
  "filename": "src/web-function.ts",
10890
- "line": 500
10947
+ "line": 549
10891
10948
  },
10892
10949
  "name": "grantInvoke",
10893
10950
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionBase",
@@ -10916,7 +10973,7 @@
10916
10973
  "immutable": true,
10917
10974
  "locationInModule": {
10918
10975
  "filename": "src/web-function.ts",
10919
- "line": 343
10976
+ "line": 390
10920
10977
  },
10921
10978
  "name": "currentRevision",
10922
10979
  "type": {
@@ -10932,7 +10989,7 @@
10932
10989
  "immutable": true,
10933
10990
  "locationInModule": {
10934
10991
  "filename": "src/web-function.ts",
10935
- "line": 346
10992
+ "line": 393
10936
10993
  },
10937
10994
  "name": "endpoint",
10938
10995
  "type": {
@@ -10947,7 +11004,7 @@
10947
11004
  "immutable": true,
10948
11005
  "locationInModule": {
10949
11006
  "filename": "src/web-function.ts",
10950
- "line": 355
11007
+ "line": 402
10951
11008
  },
10952
11009
  "name": "grantPrincipal",
10953
11010
  "overrides": "aws-cdk-lib.aws_iam.IGrantable",
@@ -10963,7 +11020,7 @@
10963
11020
  "immutable": true,
10964
11021
  "locationInModule": {
10965
11022
  "filename": "src/web-function.ts",
10966
- "line": 349
11023
+ "line": 396
10967
11024
  },
10968
11025
  "name": "grants",
10969
11026
  "type": {
@@ -10979,7 +11036,7 @@
10979
11036
  "immutable": true,
10980
11037
  "locationInModule": {
10981
11038
  "filename": "src/web-function.ts",
10982
- "line": 361
11039
+ "line": 408
10983
11040
  },
10984
11041
  "name": "logGroup",
10985
11042
  "type": {
@@ -10995,7 +11052,7 @@
10995
11052
  "immutable": true,
10996
11053
  "locationInModule": {
10997
11054
  "filename": "src/web-function.ts",
10998
- "line": 340
11055
+ "line": 387
10999
11056
  },
11000
11057
  "name": "revisionId",
11001
11058
  "type": {
@@ -11010,7 +11067,7 @@
11010
11067
  "immutable": true,
11011
11068
  "locationInModule": {
11012
11069
  "filename": "src/web-function.ts",
11013
- "line": 352
11070
+ "line": 399
11014
11071
  },
11015
11072
  "name": "role",
11016
11073
  "type": {
@@ -11025,7 +11082,7 @@
11025
11082
  "immutable": true,
11026
11083
  "locationInModule": {
11027
11084
  "filename": "src/web-function.ts",
11028
- "line": 337
11085
+ "line": 384
11029
11086
  },
11030
11087
  "name": "webFunctionArn",
11031
11088
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionBase",
@@ -11041,7 +11098,7 @@
11041
11098
  "immutable": true,
11042
11099
  "locationInModule": {
11043
11100
  "filename": "src/web-function.ts",
11044
- "line": 336
11101
+ "line": 383
11045
11102
  },
11046
11103
  "name": "webFunctionName",
11047
11104
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionBase",
@@ -11064,7 +11121,7 @@
11064
11121
  "kind": "interface",
11065
11122
  "locationInModule": {
11066
11123
  "filename": "src/web-function.ts",
11067
- "line": 203
11124
+ "line": 210
11068
11125
  },
11069
11126
  "name": "WebFunctionAttributes",
11070
11127
  "properties": [
@@ -11078,7 +11135,7 @@
11078
11135
  "immutable": true,
11079
11136
  "locationInModule": {
11080
11137
  "filename": "src/web-function.ts",
11081
- "line": 224
11138
+ "line": 231
11082
11139
  },
11083
11140
  "name": "endpointName",
11084
11141
  "optional": true,
@@ -11096,7 +11153,7 @@
11096
11153
  "immutable": true,
11097
11154
  "locationInModule": {
11098
11155
  "filename": "src/web-function.ts",
11099
- "line": 210
11156
+ "line": 217
11100
11157
  },
11101
11158
  "name": "webFunctionArn",
11102
11159
  "optional": true,
@@ -11114,7 +11171,7 @@
11114
11171
  "immutable": true,
11115
11172
  "locationInModule": {
11116
11173
  "filename": "src/web-function.ts",
11117
- "line": 217
11174
+ "line": 224
11118
11175
  },
11119
11176
  "name": "webFunctionName",
11120
11177
  "optional": true,
@@ -11202,9 +11259,35 @@
11202
11259
  "kind": "class",
11203
11260
  "locationInModule": {
11204
11261
  "filename": "src/web-function.ts",
11205
- "line": 230
11262
+ "line": 272
11206
11263
  },
11207
11264
  "methods": [
11265
+ {
11266
+ "abstract": true,
11267
+ "docs": {
11268
+ "stability": "experimental",
11269
+ "summary": "Adds a statement to the function's resource policy (not added for an imported function)."
11270
+ },
11271
+ "locationInModule": {
11272
+ "filename": "src/web-function.ts",
11273
+ "line": 290
11274
+ },
11275
+ "name": "addToResourcePolicy",
11276
+ "overrides": "aws-cdk-lib.aws_iam.IResourceWithPolicyV2",
11277
+ "parameters": [
11278
+ {
11279
+ "name": "statement",
11280
+ "type": {
11281
+ "fqn": "aws-cdk-lib.aws_iam.PolicyStatement"
11282
+ }
11283
+ }
11284
+ ],
11285
+ "returns": {
11286
+ "type": {
11287
+ "fqn": "aws-cdk-lib.aws_iam.AddToResourcePolicyResult"
11288
+ }
11289
+ }
11290
+ },
11208
11291
  {
11209
11292
  "abstract": true,
11210
11293
  "docs": {
@@ -11214,7 +11297,7 @@
11214
11297
  },
11215
11298
  "locationInModule": {
11216
11299
  "filename": "src/web-function.ts",
11217
- "line": 243
11300
+ "line": 285
11218
11301
  },
11219
11302
  "name": "grantInvoke",
11220
11303
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11241,7 +11324,7 @@
11241
11324
  },
11242
11325
  "locationInModule": {
11243
11326
  "filename": "src/web-function.ts",
11244
- "line": 254
11327
+ "line": 301
11245
11328
  },
11246
11329
  "name": "metric",
11247
11330
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11273,7 +11356,7 @@
11273
11356
  },
11274
11357
  "locationInModule": {
11275
11358
  "filename": "src/web-function.ts",
11276
- "line": 269
11359
+ "line": 316
11277
11360
  },
11278
11361
  "name": "metricActiveTime",
11279
11362
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11300,7 +11383,7 @@
11300
11383
  },
11301
11384
  "locationInModule": {
11302
11385
  "filename": "src/web-function.ts",
11303
- "line": 284
11386
+ "line": 331
11304
11387
  },
11305
11388
  "name": "metricConcurrentRequests",
11306
11389
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11326,7 +11409,7 @@
11326
11409
  },
11327
11410
  "locationInModule": {
11328
11411
  "filename": "src/web-function.ts",
11329
- "line": 274
11412
+ "line": 321
11330
11413
  },
11331
11414
  "name": "metricCpuTime",
11332
11415
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11354,7 +11437,7 @@
11354
11437
  },
11355
11438
  "locationInModule": {
11356
11439
  "filename": "src/web-function.ts",
11357
- "line": 293
11440
+ "line": 340
11358
11441
  },
11359
11442
  "name": "metricMaxMemoryUsage",
11360
11443
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11380,7 +11463,7 @@
11380
11463
  },
11381
11464
  "locationInModule": {
11382
11465
  "filename": "src/web-function.ts",
11383
- "line": 298
11466
+ "line": 345
11384
11467
  },
11385
11468
  "name": "metricResponseBytes",
11386
11469
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11411,7 +11494,7 @@
11411
11494
  "immutable": true,
11412
11495
  "locationInModule": {
11413
11496
  "filename": "src/web-function.ts",
11414
- "line": 232
11497
+ "line": 274
11415
11498
  },
11416
11499
  "name": "webFunctionArn",
11417
11500
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11428,7 +11511,7 @@
11428
11511
  "immutable": true,
11429
11512
  "locationInModule": {
11430
11513
  "filename": "src/web-function.ts",
11431
- "line": 231
11514
+ "line": 273
11432
11515
  },
11433
11516
  "name": "webFunctionName",
11434
11517
  "overrides": "@ashishpandeyone/cdk-lambda-web-function.IWebFunction",
@@ -11444,7 +11527,7 @@
11444
11527
  "immutable": true,
11445
11528
  "locationInModule": {
11446
11529
  "filename": "src/web-function.ts",
11447
- "line": 235
11530
+ "line": 277
11448
11531
  },
11449
11532
  "name": "webFunctionRef",
11450
11533
  "overrides": "aws-cdk-lib.interfaces.aws_lambda.IWebFunctionRef",
@@ -12327,18 +12410,18 @@
12327
12410
  "kind": "class",
12328
12411
  "locationInModule": {
12329
12412
  "filename": "src/web-function-grants.ts",
12330
- "line": 7
12413
+ "line": 8
12331
12414
  },
12332
12415
  "methods": [
12333
12416
  {
12334
12417
  "docs": {
12335
- "remarks": "The grant is on the endpoint's home-region ARN, which IAM evaluates for every region the\nendpoint serves from, including a MULTI_REGION global URL.",
12418
+ "remarks": "The grant is on the endpoint's home-region ARN, which IAM evaluates for every region the\nendpoint serves from, including a MULTI_REGION global URL.\n\nA grantee in the function's account gets an IAM policy statement. Another account or an AWS service also gets\na statement in the function's resource policy (not for an imported function's endpoints).",
12336
12419
  "stability": "experimental",
12337
12420
  "summary": "Allows `grantee` to call the endpoint (`lambda:InvokeWebFunctionEndpoint`)."
12338
12421
  },
12339
12422
  "locationInModule": {
12340
12423
  "filename": "src/web-function-grants.ts",
12341
- "line": 32
12424
+ "line": 36
12342
12425
  },
12343
12426
  "name": "invoke",
12344
12427
  "parameters": [
@@ -12463,7 +12546,7 @@
12463
12546
  "kind": "interface",
12464
12547
  "locationInModule": {
12465
12548
  "filename": "src/web-function.ts",
12466
- "line": 23
12549
+ "line": 24
12467
12550
  },
12468
12551
  "name": "WebFunctionOptions",
12469
12552
  "properties": [
@@ -12476,7 +12559,7 @@
12476
12559
  "immutable": true,
12477
12560
  "locationInModule": {
12478
12561
  "filename": "src/web-function.ts",
12479
- "line": 27
12562
+ "line": 28
12480
12563
  },
12481
12564
  "name": "authType",
12482
12565
  "type": {
@@ -12493,7 +12576,7 @@
12493
12576
  "immutable": true,
12494
12577
  "locationInModule": {
12495
12578
  "filename": "src/web-function.ts",
12496
- "line": 116
12579
+ "line": 117
12497
12580
  },
12498
12581
  "name": "applicationLogLevelV2",
12499
12582
  "optional": true,
@@ -12511,7 +12594,7 @@
12511
12594
  "immutable": true,
12512
12595
  "locationInModule": {
12513
12596
  "filename": "src/web-function.ts",
12514
- "line": 62
12597
+ "line": 63
12515
12598
  },
12516
12599
  "name": "description",
12517
12600
  "optional": true,
@@ -12529,7 +12612,7 @@
12529
12612
  "immutable": true,
12530
12613
  "locationInModule": {
12531
12614
  "filename": "src/web-function.ts",
12532
- "line": 36
12615
+ "line": 37
12533
12616
  },
12534
12617
  "name": "endpoint",
12535
12618
  "optional": true,
@@ -12548,7 +12631,7 @@
12548
12631
  "immutable": true,
12549
12632
  "locationInModule": {
12550
12633
  "filename": "src/web-function.ts",
12551
- "line": 79
12634
+ "line": 80
12552
12635
  },
12553
12636
  "name": "environment",
12554
12637
  "optional": true,
@@ -12572,7 +12655,7 @@
12572
12655
  "immutable": true,
12573
12656
  "locationInModule": {
12574
12657
  "filename": "src/web-function.ts",
12575
- "line": 109
12658
+ "line": 110
12576
12659
  },
12577
12660
  "name": "logRemovalPolicy",
12578
12661
  "optional": true,
@@ -12590,7 +12673,7 @@
12590
12673
  "immutable": true,
12591
12674
  "locationInModule": {
12592
12675
  "filename": "src/web-function.ts",
12593
- "line": 101
12676
+ "line": 102
12594
12677
  },
12595
12678
  "name": "logRetention",
12596
12679
  "optional": true,
@@ -12609,7 +12692,7 @@
12609
12692
  "immutable": true,
12610
12693
  "locationInModule": {
12611
12694
  "filename": "src/web-function.ts",
12612
- "line": 94
12695
+ "line": 95
12613
12696
  },
12614
12697
  "name": "maxConcurrencyPerEnvironment",
12615
12698
  "optional": true,
@@ -12628,7 +12711,7 @@
12628
12711
  "immutable": true,
12629
12712
  "locationInModule": {
12630
12713
  "filename": "src/web-function.ts",
12631
- "line": 48
12714
+ "line": 49
12632
12715
  },
12633
12716
  "name": "revisionRetention",
12634
12717
  "optional": true,
@@ -12647,7 +12730,7 @@
12647
12730
  "immutable": true,
12648
12731
  "locationInModule": {
12649
12732
  "filename": "src/web-function.ts",
12650
- "line": 72
12733
+ "line": 73
12651
12734
  },
12652
12735
  "name": "role",
12653
12736
  "optional": true,
@@ -12665,7 +12748,7 @@
12665
12748
  "immutable": true,
12666
12749
  "locationInModule": {
12667
12750
  "filename": "src/web-function.ts",
12668
- "line": 123
12751
+ "line": 124
12669
12752
  },
12670
12753
  "name": "systemLogLevelV2",
12671
12754
  "optional": true,
@@ -12683,7 +12766,7 @@
12683
12766
  "immutable": true,
12684
12767
  "locationInModule": {
12685
12768
  "filename": "src/web-function.ts",
12686
- "line": 86
12769
+ "line": 87
12687
12770
  },
12688
12771
  "name": "timeout",
12689
12772
  "optional": true,
@@ -12702,7 +12785,7 @@
12702
12785
  "immutable": true,
12703
12786
  "locationInModule": {
12704
12787
  "filename": "src/web-function.ts",
12705
- "line": 55
12788
+ "line": 56
12706
12789
  },
12707
12790
  "name": "webFunctionName",
12708
12791
  "optional": true,
@@ -12713,6 +12796,96 @@
12713
12796
  ],
12714
12797
  "symbolId": "src/web-function:WebFunctionOptions"
12715
12798
  },
12799
+ "@ashishpandeyone/cdk-lambda-web-function.WebFunctionPermission": {
12800
+ "assembly": "@ashishpandeyone/cdk-lambda-web-function",
12801
+ "datatype": true,
12802
+ "docs": {
12803
+ "stability": "experimental",
12804
+ "summary": "Permission for a principal outside this account, an AWS service or an organization to call a function's endpoints."
12805
+ },
12806
+ "fqn": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionPermission",
12807
+ "kind": "interface",
12808
+ "locationInModule": {
12809
+ "filename": "src/web-function.ts",
12810
+ "line": 237
12811
+ },
12812
+ "name": "WebFunctionPermission",
12813
+ "properties": [
12814
+ {
12815
+ "abstract": true,
12816
+ "docs": {
12817
+ "remarks": "A principal in another account also needs `lambda:InvokeWebFunctionEndpoint` in its own IAM policy.",
12818
+ "stability": "experimental",
12819
+ "summary": "Who may call: an account (`iam.AccountPrincipal`), a role or user (`iam.ArnPrincipal`), an AWS service (`iam.ServicePrincipal`, with `sourceArn` or `sourceAccount`) or an organization (`iam.OrganizationPrincipal`)."
12820
+ },
12821
+ "immutable": true,
12822
+ "locationInModule": {
12823
+ "filename": "src/web-function.ts",
12824
+ "line": 244
12825
+ },
12826
+ "name": "principal",
12827
+ "type": {
12828
+ "fqn": "aws-cdk-lib.aws_iam.IPrincipal"
12829
+ }
12830
+ },
12831
+ {
12832
+ "abstract": true,
12833
+ "docs": {
12834
+ "default": "- every endpoint of the function, including ones added later",
12835
+ "remarks": "It must belong to this function.",
12836
+ "stability": "experimental",
12837
+ "summary": "The endpoint the principal may call."
12838
+ },
12839
+ "immutable": true,
12840
+ "locationInModule": {
12841
+ "filename": "src/web-function.ts",
12842
+ "line": 251
12843
+ },
12844
+ "name": "endpoint",
12845
+ "optional": true,
12846
+ "type": {
12847
+ "fqn": "@ashishpandeyone/cdk-lambda-web-function.WebFunctionEndpoint"
12848
+ }
12849
+ },
12850
+ {
12851
+ "abstract": true,
12852
+ "docs": {
12853
+ "default": "- no condition",
12854
+ "stability": "experimental",
12855
+ "summary": "For an AWS service: the account that owns the resource calling on its behalf (condition `aws:SourceAccount`)."
12856
+ },
12857
+ "immutable": true,
12858
+ "locationInModule": {
12859
+ "filename": "src/web-function.ts",
12860
+ "line": 266
12861
+ },
12862
+ "name": "sourceAccount",
12863
+ "optional": true,
12864
+ "type": {
12865
+ "primitive": "string"
12866
+ }
12867
+ },
12868
+ {
12869
+ "abstract": true,
12870
+ "docs": {
12871
+ "default": "- no condition",
12872
+ "stability": "experimental",
12873
+ "summary": "For an AWS service: the ARN of the resource calling on its behalf (condition `aws:SourceArn`, `ArnLike`), e.g. a CloudFront distribution. Without it or `sourceAccount`, any account's use of the service could call the endpoint."
12874
+ },
12875
+ "immutable": true,
12876
+ "locationInModule": {
12877
+ "filename": "src/web-function.ts",
12878
+ "line": 259
12879
+ },
12880
+ "name": "sourceArn",
12881
+ "optional": true,
12882
+ "type": {
12883
+ "primitive": "string"
12884
+ }
12885
+ }
12886
+ ],
12887
+ "symbolId": "src/web-function:WebFunctionPermission"
12888
+ },
12716
12889
  "@ashishpandeyone/cdk-lambda-web-function.WebFunctionProps": {
12717
12890
  "assembly": "@ashishpandeyone/cdk-lambda-web-function",
12718
12891
  "datatype": true,
@@ -12727,7 +12900,7 @@
12727
12900
  "kind": "interface",
12728
12901
  "locationInModule": {
12729
12902
  "filename": "src/web-function.ts",
12730
- "line": 129
12903
+ "line": 130
12731
12904
  },
12732
12905
  "name": "WebFunctionProps",
12733
12906
  "properties": [
@@ -12741,7 +12914,7 @@
12741
12914
  "immutable": true,
12742
12915
  "locationInModule": {
12743
12916
  "filename": "src/web-function.ts",
12744
- "line": 141
12917
+ "line": 142
12745
12918
  },
12746
12919
  "name": "code",
12747
12920
  "type": {
@@ -12757,7 +12930,7 @@
12757
12930
  "immutable": true,
12758
12931
  "locationInModule": {
12759
12932
  "filename": "src/web-function.ts",
12760
- "line": 133
12933
+ "line": 134
12761
12934
  },
12762
12935
  "name": "runtime",
12763
12936
  "type": {
@@ -12774,7 +12947,7 @@
12774
12947
  "immutable": true,
12775
12948
  "locationInModule": {
12776
12949
  "filename": "src/web-function.ts",
12777
- "line": 148
12950
+ "line": 149
12778
12951
  },
12779
12952
  "name": "entrypoint",
12780
12953
  "optional": true,
@@ -13106,6 +13279,6 @@
13106
13279
  "symbolId": "src/web-function-deployment:WebFunctionRollbackOptions"
13107
13280
  }
13108
13281
  },
13109
- "version": "0.1.4",
13110
- "fingerprint": "jD4b9T+QRqWU7bgpwm773YKwDrQpiy3PKVU2Zby8LP8="
13282
+ "version": "0.1.5",
13283
+ "fingerprint": "Tr7QOU1oeRBvqTeXCFZ6IGobUlmK9K3kgz1HNsWILN4="
13111
13284
  }