@pwrdrvr/microapps-cdk 0.3.2 → 0.3.3-alpha.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.
- package/.jsii +80 -60
- package/API.md +18 -9
- package/README.md +2 -0
- package/changelog.md +1 -1
- package/lib/MicroApps.d.ts +5 -0
- package/lib/MicroApps.d.ts.map +1 -1
- package/lib/MicroApps.js +10 -3
- package/lib/MicroAppsAPIGwy.js +1 -1
- package/lib/MicroAppsCF.d.ts +3 -3
- package/lib/MicroAppsCF.d.ts.map +1 -1
- package/lib/MicroAppsCF.js +6 -6
- package/lib/MicroAppsEdgeToOrigin.js +1 -1
- package/lib/MicroAppsS3.js +1 -1
- package/lib/MicroAppsSvcs.js +1 -1
- package/lib/MicroAppsTable.js +1 -1
- package/lib/microapps-deployer/index.js +61 -235
- package/lib/microapps-deployer/index.js.map +3 -3
- package/package.json +1 -1
- package/releasetag.txt +1 -1
- package/version.txt +1 -1
package/.jsii
CHANGED
|
@@ -3100,7 +3100,7 @@
|
|
|
3100
3100
|
},
|
|
3101
3101
|
"name": "@pwrdrvr/microapps-cdk",
|
|
3102
3102
|
"readme": {
|
|
3103
|
-
"markdown": "  \n\n# Overview\n\nThe MicroApps project enables rapidly deploying many web apps to AWS on a single shared host name, fronted by a CloudFront Distribution, serving static assets from an S3 Bucket, and routing application requests via API Gateway. MicroApps is delivered as a CDK Construct for deployment, although alternative deployment methods can be used if desired and implemented.\n\nMicroApps allows many versions of an application to be deployed either as ephemeral deploys (e.g. for pull request builds) or as semi-permanent deploys. The `microapps-router` Lambda function handled routing requests to apps to the current version targeted for a particular application start request using rules as complex as one is interested in implementing (e.g. A/B testing integration, canary releases, per-user rules for logged in users, per-group, per-deparment, and default rules).\n\nUsers start applications via a URL such as `[/{prefix}]/{appname}/`, which hits the `microapps-router` that looks up the version of the application to be run, then renders a transparent `iframe` with a link to that version. The URL seen by the user in the browser (and available for bookmarking) has no version in it, so subsequent launches (e.g. the next day or just in another tab) will lookup the version again. All relative URL API requests (e.g. `some/api/path`) will go to the corresponding API version that matches the version of the loaded static files, eliminating issues of incompatibility between static files and API deployments.\n\nFor development / testing purposes only, each version of an applicaton can be accessed directly via a URL of the pattern `[/{prefix}]/{appname}/{semver}/`. These \"versioned\" URLs are not intended to be advertised to end users as they would cause a user to be stuck on a particular version of the app if the URL was bookmarked. Note that the system does not limit access to particular versions of an application, as of 2022-01-26, but that can be added as a feature.\n\n# Table of Contents <!-- omit in toc -->\n\n- [Overview](#overview)\n- [Video Preview of the Deploying CDK Construct](#video-preview-of-the-deploying-cdk-construct)\n- [Installation / CDK Constructs](#installation--cdk-constructs)\n- [Tutorial - Bootstrapping a Deploy](#tutorial---bootstrapping-a-deploy)\n- [Why MicroApps](#why-microapps)\n- [Limitations / Future Development](#limitations--future-development)\n- [Related Projects / Components](#related-projects--components)\n- [Architecure Diagram](#architecure-diagram)\n- [Project Layout](#project-layout)\n- [Creating a MicroApp Using Zip Lambda Functions](#creating-a-microapp-using-zip-lambda-functions)\n- [Creating a MicroApp Using Docker Lambda Functions](#creating-a-microapp-using-docker-lambda-functions)\n - [Next.js Apps](#nextjs-apps)\n - [Modify package.json](#modify-packagejson)\n - [Install Dependencies](#install-dependencies)\n - [Dockerfile](#dockerfile)\n - [next.config.js](#nextconfigjs)\n - [deploy.json](#deployjson)\n - [serverless.yaml](#serverlessyaml)\n- [Troubleshooting](#troubleshooting)\n - [CloudFront Requests to API Gateway are Rejected with 403 Forbidden](#cloudfront-requests-to-api-gateway-are-rejected-with-403-forbidden)\n - [SignatureV4 Headers](#signaturev4-headers)\n\n# Video Preview of the Deploying CDK Construct\n\n\n\n# Installation / CDK Constructs\n\n- `npm i --save-dev @pwrdrvr/microapps-cdk`\n- Add `MicroApps` construct to your stack\n- The `MicroApps` construct does a \"turn-key\" deployment complete with the Release app\n- [Construct Hub](https://constructs.dev/packages/@pwrdrvr/microapps-cdk/)\n - CDK API docs\n - Python, DotNet, Java, JS/TS installation instructions\n\n# Tutorial - Bootstrapping a Deploy\n\n- `git clone https://github.com/pwrdrvr/microapps-core.git`\n - Note: the repo is only being for the example CDK Stack, it is not necessary to clone the repo when used in a custom CDK Stack\n- `cd microapps-core`\n- `npm i -g aws-cdk`\n - Install AWS CDK v2 CLI\n- `asp [my-sso-profile-name]`\n - Using the `aws` plugin from `oh-my-zsh` for AWS SSO\n - Of course, there are other methods of setting env vars\n- `aws sso login`\n - Establish an AWS SSO session\n- `cdk-sso-sync`\n - Using `npm i -g cdk-sso-sync`\n - Sets AWS SSO credentials in a way that CDK can use them\n - Not necessary if not using AWS SSO\n- `export AWS_REGION=us-east-2`\n - Region needs to be set for the Lambda invoke - This can be done other ways in `~/.aws/config` as well\n- `./deploy.sh`\n - Deploys the CDK Stack\n - Essentially runs two commands along with extraction of outputs:\n - `npx cdk deploy --context @pwrdrvr/microapps:deployReleaseApp=true microapps-basic`\n - `npx microapps-publish publish -a release -n ${RELEASE_APP_PACKAGE_VERSION} -d ${DEPLOYER_LAMBDA_NAME} -l ${RELEASE_APP_LAMBDA_NAME} -s node_modules/@pwrdrvr/microapps-app-release-cdk/lib/.static_files/release/${RELEASE_APP_PACKAGE_VERSION}/ --overwrite --noCache`\n - URL will be printed as last output\n\n# Why MicroApps\n\nMicroApps are like micro services, but for Web UIs. A MicroApp allows a single functional site to be developed by many independent teams within an organization. Teams must coordinate deployments and agree upon one implementation technology and framework when building a monolithic, or even a monorepo, web application.\n\nTeams using MicroApps can deploy independently of each other with coordination being required only at points of intentional integration (e.g. adding a feature to pass context from one MicroApp to another or coordination of a major feature release to users) and sharing UI styles, if desired (it is possible to build styles that look the same across many different UI frameworks).\n\nMicroApps also allow each team to use a UI framework and backend language that is most appropriate for their solving their business problem. Not every app has to use React or Next.js or even Node on the backend, but instead they can use whatever framework they want and Java, Go, C#, Python, etc. for UI API calls.\n\nFor internal sites, or logged-in-customer sites, different tools or products can be hosted in entirely independent MicroApps. A menuing system / toolbar application can be created as a MicroApp and that menu app can open the apps in the system within a transparent iframe. For externally facing sites, such as for an e-commerce site, it is possible to have a MicroApp serving `/product/...`, another serving `/search/...`, another serving `/`, etc.\n\n# Limitations / Future Development\n\n- `iframes`\n - Yeah, yeah: `iframes` are not framesets and most of the hate about iframes is probably better directed at framesets\n - The iframe serves a purpose but it stinks that it is there, primarily because it will cause issues with search bot indexing (SEO)\n - There are other options available to implement that have their own drabacks:\n - Using the `microapps-router` to proxy the \"app start\" request to a particular version of an app that then renders all of it's API resource requests to versioned URLs\n - Works only with frameworks that support hashing filenams for each deploy to unique names\n - This page would need to be marked as non-cachable\n - This may work well with Next.js which wants to know the explicit path that it will be running at (it writes that path into all resource and API requests)\n - Possible issue: the app would need to work ok being displayed at `[/{prefix}]/{appname}` when it may think that it's being displayed at `[/{prefix}]/{appname}/{semver}`\n - Disadvantage: requires some level of UI framework features (e.g. writing the absolute resource paths) to work correctly - may not work as easily for all UI frameworks\n - HTML5 added features to allow setting the relative path of all subsequent requests to be different than that displayed in the address bar\n - Gotta see if this works in modern browsers\n - Option to ditch the multiple-versions feature\n - Works only with frameworks that support hashing filenams for each deploy to unique names\n - Allows usage of the deploy and routing tooling without advantages and disadvantages of multiple-versions support\n- AWS Only\n - For the time being this has only been implemented for AWS technologies and APIs\n - It is possible that Azure and GCP have sufficient support to enable porting the framework\n - CDK would have to be replaced as well (unless it's made available for Azure and GCP in the near future)\n- `microapps-publish` only supports Lambda function apps\n - There is no technical reason for the apps to only run as Lambda functions\n - Web apps could just as easily run on EC2, Kubernetes, EKS, ECS, etc\n - Anything that API Gateway can route to can work for serving a MicroApp\n - The publish tool needs to provide additional options for setting up the API Gateway route to the app\n- Authentication\n - Authentication requires rolling your own API Gateway and CloudFront deployment at the moment\n - The \"turn key\" CDK Construct should provide options to show an example of how authentication can be integrated\n- Release Rules\n - Currently only a Default rule is supported\n - Need to evaluate if a generic implementation can be made, possibly allowing plugins or webhooks to support arbitrary rules\n - If not possible to make it perfectly generic, consider providing a more complete reference implementation of examples\n\n# Related Projects / Components\n\n- Release App\n - The Release app is an initial, rudimentary, release control console for setting the default version of an application\n - Built with Next.js\n - [pwrdrvr/microapps-app-release](https://github.com/pwrdrvr/microapps-app-release)\n- Next.js Demo App\n - The Next.js Tutorial application deployed as a MicroApp\n - [pwrdrvr/serverless-nextjs-demo](https://github.com/pwrdrvr/serverless-nextjs-demo)\n- Serverless Next.js Router\n - [pwrdrvr/serverless-nextjs-router](https://github.com/pwrdrvr/serverless-nextjs-router)\n - Complementary to [@sls-next/serverless-component](https://github.com/serverless-nextjs/serverless-next.js)\n - Allows Next.js apps to run as Lambda @ Origin for speed and cost improvements vs Lambda@Edge\n - Essentially the router translates CloudFront Lambda events to API Gateway Lambda events and vice versa for responses\n - The `serverless-nextjs` project allows Next.js apps to run as Lambda functions without Express, but there was a design change to make the Lambda functions run at Edge (note: need to recheck if this changed after early 2021)\n - Lambda@Edge is _at least_ 3x more expensive than Lambda at the origin:\n - In US East 1, the price per GB-Second is $0.00005001 for Lambda@Edge vs $0.0000166667 for Lambda at the origin\n - Additionally, any DB or services calls from Lambda@Edge back to the origin will pay that 3x higher per GB-Second cost for any time spent waiting to send the request and get a response. Example:\n - Lambda@Edge\n - 0.250s Round Trip Time (RTT) for EU-zone edge request to hit US-East 1 Origin\n - 0.200s DB lookup time\n - 0.050s CPU usage to process the DB response\n - 0.500s total billed time @ $0.00005001 @ 128 MB\n - $0.000003125625 total charge\n - Lambda at Origin\n - RTT does not apply (it's effectively 1-2 ms to hit a DB in the same region)\n - 0.200s DB lookup time\n - 0.050s CPU usage to process the DB response\n - 0.250s total billed time @ $0.0000166667 @ 128 MB\n - Half the billed time of running on Lambda@Edge\n - 1/6th the cost of running on Lambda@Edge:\n - $0.000000520834375 total charge (assuming no CPU time to process the response)\n - $0.000003125625 / $0.000000520834375 = 6x more expensive in Lambda@Edge\n\n# Architecure Diagram\n\n\n\n# Project Layout\n\n- [packages/cdk](https://github.com/pwrdrvr/microapps-core/tree/main/packages/cdk)\n - Example CDK Stack\n - Deploys MicroApps CDK stack for the GitHub Workflows\n - Can be used as an example of how to use the MicroApps CDK Construct\n- [packages/demo-app](https://github.com/pwrdrvr/microapps-core/tree/main/packages/demo-app)\n - Example app with static resources and a Lambda function\n - Does not use any Web UI framework at all\n- [packages/microapps-cdk](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-cdk)\n - MicroApps\n - \"Turn key\" CDK Construct that creates all assets needed for a working MicroApps deployment\n - MicroAppsAPIGwy\n - Create APIGateway HTTP API\n - Creates domain names to point to the edge (Cloudfront) and origin (API Gateway)\n - MicroAppsCF\n - Creates Cloudfront distribution\n - MicroAppsS3\n - Creates S3 buckets\n - MicroAppsSvcs\n - Create DynamoDB table\n - Create Deployer Lambda function\n - Create Router Lambda function\n- [packages/microapps-datalib](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-datalib)\n - Installed from `npm`:\n - `npm i -g @pwrdrvr/microapps-datalib`\n - APIs for access to the DynamoDB Table used by `microapps-publish`, `microapps-deployer`, and `@pwrdrvr/microapps-app-release-cdk`\n- [packages/microapps-deployer](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-deployer)\n - Lambda service invoked by `microapps-publish` to record new app/version in the DynamoDB table, create API Gateway integrations, copy S3 assets from staging to prod bucket, etc.\n - Returns a temporary S3 token with restricted access to the staging S3 bucket for upload of the static files for one app/semver\n- [packages/microapps-publish](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-publish)\n - Installed from `npm`:\n - `npm i -g @pwrdrvr/microapps-publish`\n - Node executable that updates versions in config files, deploys static assets to the S3 staging bucket, optionally compiles and deploys a new Lambda function version, and invokes `microapps-deployer`\n - AWS IAM permissions required:\n - `lambda:InvokeFunction`\n- [packages/microapps-router](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-router)\n - Lambda function that determines which version of an app to point a user to on a particular invocation\n\n# Creating a MicroApp Using Zip Lambda Functions\n\n[TBC]\n\n# Creating a MicroApp Using Docker Lambda Functions\n\nNote: semi-deprecated as of 2022-01-27. Zip Lambda functions are better supported.\n\n## Next.js Apps\n\nCreate a Next.js app then follow the steps in this section to set it up for publishing to AWS Lambda @ Origin as a MicroApp. To publish new versions of the app use `npx microapps-publish --new-version x.y.z` when logged in to the target AWS account.\n\n### Modify package.json\n\nReplace the version with `0.0.0` so it can be modified by the `microapps-publish` tool.\n\n### Install Dependencies\n\n```\nnpm i --save-dev @sls-next/serverless-component@1.19.0 @pwrdrvr/serverless-nextjs-router @pwrdrvr/microapps-publish\n```\n\n### Dockerfile\n\nAdd this file to the root of the app.\n\n```Dockerfile\nFROM node:15-slim as base\n\nWORKDIR /app\n\n# Download the sharp libs once to save time\n# Do this before copying anything else in\nRUN mkdir -p image-lambda-npms && \\\n cd image-lambda-npms && npm i sharp && \\\n rm -rf node_modules/sharp/vendor/*/include/\n\n# Copy in the build output from `npx serverless`\nCOPY .serverless_nextjs .\nCOPY config.json .\n\n# Move the sharp libs into place\nRUN rm -rf image-lambda/node_modules/ && \\\n mv image-lambda-npms/node_modules image-labmda/ && \\\n rm -rf image-lambda-npms\n\nFROM public.ecr.aws/lambda/nodejs:14 AS final\n\n# Copy in the munged code\nCOPY --from=base /app .\n\nCMD [ \"./index.handler\" ]\n```\n\n### next.config.js\n\nAdd this file to the root of the app.\n\nReplace `appname` with your URL path-compatible application name.\n\n```js\nconst appRoot = '/appname/0.0.0';\n\n// eslint-disable-next-line no-undef\nmodule.exports = {\n target: 'serverless',\n webpack: (config, _options) => {\n return config;\n },\n basePath: appRoot,\n publicRuntimeConfig: {\n // Will be available on both server and client\n staticFolder: appRoot,\n },\n};\n```\n\n### deploy.json\n\nAdd this file to the root of the app.\n\nReplace `appname` with your URL path-compatible application name.\n\n```json\n{\n \"AppName\": \"appname\",\n \"SemVer\": \"0.0.0\",\n \"DefaultFile\": \"\",\n \"StaticAssetsPath\": \"./.serverless_nextjs/assets/appname/0.0.0/\",\n \"LambdaARN\": \"arn:aws:lambda:us-east-1:123456789012:function:appname:v0_0_0\",\n \"AWSAccountID\": \"123456789012\",\n \"AWSRegion\": \"us-east-2\",\n \"ServerlessNextRouterPath\": \"./node_modules/@pwrdrvr/serverless-nextjs-router/dist/index.js\"\n}\n```\n\n### serverless.yaml\n\nAdd this file to the root of the app.\n\n```yaml\nnextApp:\n component: './node_modules/@sls-next/serverless-component'\n inputs:\n deploy: false\n uploadStaticAssetsFromBuild: false\n```\n\n# Troubleshooting\n\n## CloudFront Requests to API Gateway are Rejected with 403 Forbidden\n\nRequests to the API Gateway origin can be rejected with a 403 Forbidden error if the signed request headers are not sent to the origin by CloudFront.\n\nThe error in the API Gateway CloudWatch logs will show up as:\n\n```log\n\"authorizerError\": \"The request for the IAM Authorizer doesn't match the format that API Gateway expects.\"\n```\n\nThis can be simulated by simply running `curl [api-gateway-url]`, with no headers.\n\nTo confirm that API Gateway is allowing signed requests when the IAM Authorizer is configured, establish credentials as a user that is allowed to execute the API Gateay, install `awscurl` with `pip3 install awscurl`, then then use `awscurl --service execute-api --region [api-gateway-region] [api-gateway-url]`.\n\nSignature headers will not be sent from CloudFront to API Gateway unless the `OriginRequestPolicy` is set to specifically include those headers on requests to the origin, or the `headersBehavior` is set to `cfront.OriginRequestHeaderBehavior.all()`.\n\nSimilarly, if `presign` is used, the `OriginRequestPolicy` must be set to `cfront.OriginRequestQueryStringBehavior.all()` or to specifically forward the query string parameters used by the presigned URL.\n\n### SignatureV4 Headers\n- `authorization`\n- `x-amz-date`\n- `x-amz-security-token`\n- `x-amz-content-sha256`"
|
|
3103
|
+
"markdown": "  \n\n# Overview\n\nThe MicroApps project enables rapidly deploying many web apps to AWS on a single shared host name, fronted by a CloudFront Distribution, serving static assets from an S3 Bucket, and routing application requests via API Gateway. MicroApps is delivered as a CDK Construct for deployment, although alternative deployment methods can be used if desired and implemented.\n\nMicroApps allows many versions of an application to be deployed either as ephemeral deploys (e.g. for pull request builds) or as semi-permanent deploys. The `microapps-router` Lambda function handled routing requests to apps to the current version targeted for a particular application start request using rules as complex as one is interested in implementing (e.g. A/B testing integration, canary releases, per-user rules for logged in users, per-group, per-deparment, and default rules).\n\n2023-01-01 NOTE: The next paragraph is dated as the `iframe` is no longer required for frameworks that write absolute URLs for their static resources and API requests.\n\nUsers start applications via a URL such as `[/{prefix}]/{appname}/`, which hits the `microapps-router` that looks up the version of the application to be run, then renders a transparent `iframe` with a link to that version. The URL seen by the user in the browser (and available for bookmarking) has no version in it, so subsequent launches (e.g. the next day or just in another tab) will lookup the version again. All relative URL API requests (e.g. `some/api/path`) will go to the corresponding API version that matches the version of the loaded static files, eliminating issues of incompatibility between static files and API deployments.\n\nFor development / testing purposes only, each version of an applicaton can be accessed directly via a URL of the pattern `[/{prefix}]/{appname}/{semver}/`. These \"versioned\" URLs are not intended to be advertised to end users as they would cause a user to be stuck on a particular version of the app if the URL was bookmarked. Note that the system does not limit access to particular versions of an application, as of 2022-01-26, but that can be added as a feature.\n\n# Table of Contents <!-- omit in toc -->\n\n- [Overview](#overview)\n- [Video Preview of the Deploying CDK Construct](#video-preview-of-the-deploying-cdk-construct)\n- [Installation / CDK Constructs](#installation--cdk-constructs)\n- [Tutorial - Bootstrapping a Deploy](#tutorial---bootstrapping-a-deploy)\n- [Why MicroApps](#why-microapps)\n- [Limitations / Future Development](#limitations--future-development)\n- [Related Projects / Components](#related-projects--components)\n- [Architecure Diagram](#architecure-diagram)\n- [Project Layout](#project-layout)\n- [Creating a MicroApp Using Zip Lambda Functions](#creating-a-microapp-using-zip-lambda-functions)\n- [Creating a MicroApp Using Docker Lambda Functions](#creating-a-microapp-using-docker-lambda-functions)\n - [Next.js Apps](#nextjs-apps)\n - [Modify package.json](#modify-packagejson)\n - [Install Dependencies](#install-dependencies)\n - [Dockerfile](#dockerfile)\n - [next.config.js](#nextconfigjs)\n - [deploy.json](#deployjson)\n - [serverless.yaml](#serverlessyaml)\n- [Troubleshooting](#troubleshooting)\n - [CloudFront Requests to API Gateway are Rejected with 403 Forbidden](#cloudfront-requests-to-api-gateway-are-rejected-with-403-forbidden)\n - [SignatureV4 Headers](#signaturev4-headers)\n\n# Video Preview of the Deploying CDK Construct\n\n\n\n# Installation / CDK Constructs\n\n- `npm i --save-dev @pwrdrvr/microapps-cdk`\n- Add `MicroApps` construct to your stack\n- The `MicroApps` construct does a \"turn-key\" deployment complete with the Release app\n- [Construct Hub](https://constructs.dev/packages/@pwrdrvr/microapps-cdk/)\n - CDK API docs\n - Python, DotNet, Java, JS/TS installation instructions\n\n# Tutorial - Bootstrapping a Deploy\n\n- `git clone https://github.com/pwrdrvr/microapps-core.git`\n - Note: the repo is only being for the example CDK Stack, it is not necessary to clone the repo when used in a custom CDK Stack\n- `cd microapps-core`\n- `npm i -g aws-cdk`\n - Install AWS CDK v2 CLI\n- `asp [my-sso-profile-name]`\n - Using the `aws` plugin from `oh-my-zsh` for AWS SSO\n - Of course, there are other methods of setting env vars\n- `aws sso login`\n - Establish an AWS SSO session\n- `cdk-sso-sync`\n - Using `npm i -g cdk-sso-sync`\n - Sets AWS SSO credentials in a way that CDK can use them\n - Not necessary if not using AWS SSO\n- `export AWS_REGION=us-east-2`\n - Region needs to be set for the Lambda invoke - This can be done other ways in `~/.aws/config` as well\n- `./deploy.sh`\n - Deploys the CDK Stack\n - Essentially runs two commands along with extraction of outputs:\n - `npx cdk deploy --context @pwrdrvr/microapps:deployReleaseApp=true microapps-basic`\n - `npx microapps-publish publish -a release -n ${RELEASE_APP_PACKAGE_VERSION} -d ${DEPLOYER_LAMBDA_NAME} -l ${RELEASE_APP_LAMBDA_NAME} -s node_modules/@pwrdrvr/microapps-app-release-cdk/lib/.static_files/release/${RELEASE_APP_PACKAGE_VERSION}/ --overwrite --noCache`\n - URL will be printed as last output\n\n# Why MicroApps\n\nMicroApps are like micro services, but for Web UIs. A MicroApp allows a single functional site to be developed by many independent teams within an organization. Teams must coordinate deployments and agree upon one implementation technology and framework when building a monolithic, or even a monorepo, web application.\n\nTeams using MicroApps can deploy independently of each other with coordination being required only at points of intentional integration (e.g. adding a feature to pass context from one MicroApp to another or coordination of a major feature release to users) and sharing UI styles, if desired (it is possible to build styles that look the same across many different UI frameworks).\n\nMicroApps also allow each team to use a UI framework and backend language that is most appropriate for their solving their business problem. Not every app has to use React or Next.js or even Node on the backend, but instead they can use whatever framework they want and Java, Go, C#, Python, etc. for UI API calls.\n\nFor internal sites, or logged-in-customer sites, different tools or products can be hosted in entirely independent MicroApps. A menuing system / toolbar application can be created as a MicroApp and that menu app can open the apps in the system within a transparent iframe. For externally facing sites, such as for an e-commerce site, it is possible to have a MicroApp serving `/product/...`, another serving `/search/...`, another serving `/`, etc.\n\n# Limitations / Future Development\n\n- `iframes`\n - Yeah, yeah: `iframes` are not framesets and most of the hate about iframes is probably better directed at framesets\n - The iframe serves a purpose but it stinks that it is there, primarily because it will cause issues with search bot indexing (SEO)\n - There are other options available to implement that have their own drabacks:\n - Using the `microapps-router` to proxy the \"app start\" request to a particular version of an app that then renders all of it's API resource requests to versioned URLs\n - Works only with frameworks that support hashing filenams for each deploy to unique names\n - This page would need to be marked as non-cachable\n - This may work well with Next.js which wants to know the explicit path that it will be running at (it writes that path into all resource and API requests)\n - Possible issue: the app would need to work ok being displayed at `[/{prefix}]/{appname}` when it may think that it's being displayed at `[/{prefix}]/{appname}/{semver}`\n - Disadvantage: requires some level of UI framework features (e.g. writing the absolute resource paths) to work correctly - may not work as easily for all UI frameworks\n - HTML5 added features to allow setting the relative path of all subsequent requests to be different than that displayed in the address bar\n - Gotta see if this works in modern browsers\n - Option to ditch the multiple-versions feature\n - Works only with frameworks that support hashing filenams for each deploy to unique names\n - Allows usage of the deploy and routing tooling without advantages and disadvantages of multiple-versions support\n- AWS Only\n - For the time being this has only been implemented for AWS technologies and APIs\n - It is possible that Azure and GCP have sufficient support to enable porting the framework\n - CDK would have to be replaced as well (unless it's made available for Azure and GCP in the near future)\n- `microapps-publish` only supports Lambda function apps\n - There is no technical reason for the apps to only run as Lambda functions\n - Web apps could just as easily run on EC2, Kubernetes, EKS, ECS, etc\n - Anything that API Gateway can route to can work for serving a MicroApp\n - The publish tool needs to provide additional options for setting up the API Gateway route to the app\n- Authentication\n - Authentication requires rolling your own API Gateway and CloudFront deployment at the moment\n - The \"turn key\" CDK Construct should provide options to show an example of how authentication can be integrated\n- Release Rules\n - Currently only a Default rule is supported\n - Need to evaluate if a generic implementation can be made, possibly allowing plugins or webhooks to support arbitrary rules\n - If not possible to make it perfectly generic, consider providing a more complete reference implementation of examples\n\n# Related Projects / Components\n\n- Release App\n - The Release app is an initial, rudimentary, release control console for setting the default version of an application\n - Built with Next.js\n - [pwrdrvr/microapps-app-release](https://github.com/pwrdrvr/microapps-app-release)\n- Next.js Demo App\n - The Next.js Tutorial application deployed as a MicroApp\n - [pwrdrvr/serverless-nextjs-demo](https://github.com/pwrdrvr/serverless-nextjs-demo)\n- Serverless Next.js Router\n - [pwrdrvr/serverless-nextjs-router](https://github.com/pwrdrvr/serverless-nextjs-router)\n - Complementary to [@sls-next/serverless-component](https://github.com/serverless-nextjs/serverless-next.js)\n - Allows Next.js apps to run as Lambda @ Origin for speed and cost improvements vs Lambda@Edge\n - Essentially the router translates CloudFront Lambda events to API Gateway Lambda events and vice versa for responses\n - The `serverless-nextjs` project allows Next.js apps to run as Lambda functions without Express, but there was a design change to make the Lambda functions run at Edge (note: need to recheck if this changed after early 2021)\n - Lambda@Edge is _at least_ 3x more expensive than Lambda at the origin:\n - In US East 1, the price per GB-Second is $0.00005001 for Lambda@Edge vs $0.0000166667 for Lambda at the origin\n - Additionally, any DB or services calls from Lambda@Edge back to the origin will pay that 3x higher per GB-Second cost for any time spent waiting to send the request and get a response. Example:\n - Lambda@Edge\n - 0.250s Round Trip Time (RTT) for EU-zone edge request to hit US-East 1 Origin\n - 0.200s DB lookup time\n - 0.050s CPU usage to process the DB response\n - 0.500s total billed time @ $0.00005001 @ 128 MB\n - $0.000003125625 total charge\n - Lambda at Origin\n - RTT does not apply (it's effectively 1-2 ms to hit a DB in the same region)\n - 0.200s DB lookup time\n - 0.050s CPU usage to process the DB response\n - 0.250s total billed time @ $0.0000166667 @ 128 MB\n - Half the billed time of running on Lambda@Edge\n - 1/6th the cost of running on Lambda@Edge:\n - $0.000000520834375 total charge (assuming no CPU time to process the response)\n - $0.000003125625 / $0.000000520834375 = 6x more expensive in Lambda@Edge\n\n# Architecure Diagram\n\n\n\n# Project Layout\n\n- [packages/cdk](https://github.com/pwrdrvr/microapps-core/tree/main/packages/cdk)\n - Example CDK Stack\n - Deploys MicroApps CDK stack for the GitHub Workflows\n - Can be used as an example of how to use the MicroApps CDK Construct\n- [packages/demo-app](https://github.com/pwrdrvr/microapps-core/tree/main/packages/demo-app)\n - Example app with static resources and a Lambda function\n - Does not use any Web UI framework at all\n- [packages/microapps-cdk](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-cdk)\n - MicroApps\n - \"Turn key\" CDK Construct that creates all assets needed for a working MicroApps deployment\n - MicroAppsAPIGwy\n - Create APIGateway HTTP API\n - Creates domain names to point to the edge (Cloudfront) and origin (API Gateway)\n - MicroAppsCF\n - Creates Cloudfront distribution\n - MicroAppsS3\n - Creates S3 buckets\n - MicroAppsSvcs\n - Create DynamoDB table\n - Create Deployer Lambda function\n - Create Router Lambda function\n- [packages/microapps-datalib](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-datalib)\n - Installed from `npm`:\n - `npm i -g @pwrdrvr/microapps-datalib`\n - APIs for access to the DynamoDB Table used by `microapps-publish`, `microapps-deployer`, and `@pwrdrvr/microapps-app-release-cdk`\n- [packages/microapps-deployer](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-deployer)\n - Lambda service invoked by `microapps-publish` to record new app/version in the DynamoDB table, create API Gateway integrations, copy S3 assets from staging to prod bucket, etc.\n - Returns a temporary S3 token with restricted access to the staging S3 bucket for upload of the static files for one app/semver\n- [packages/microapps-publish](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-publish)\n - Installed from `npm`:\n - `npm i -g @pwrdrvr/microapps-publish`\n - Node executable that updates versions in config files, deploys static assets to the S3 staging bucket, optionally compiles and deploys a new Lambda function version, and invokes `microapps-deployer`\n - AWS IAM permissions required:\n - `lambda:InvokeFunction`\n- [packages/microapps-router](https://github.com/pwrdrvr/microapps-core/tree/main/packages/microapps-router)\n - Lambda function that determines which version of an app to point a user to on a particular invocation\n\n# Creating a MicroApp Using Zip Lambda Functions\n\n[TBC]\n\n# Creating a MicroApp Using Docker Lambda Functions\n\nNote: semi-deprecated as of 2022-01-27. Zip Lambda functions are better supported.\n\n## Next.js Apps\n\nCreate a Next.js app then follow the steps in this section to set it up for publishing to AWS Lambda @ Origin as a MicroApp. To publish new versions of the app use `npx microapps-publish --new-version x.y.z` when logged in to the target AWS account.\n\n### Modify package.json\n\nReplace the version with `0.0.0` so it can be modified by the `microapps-publish` tool.\n\n### Install Dependencies\n\n```\nnpm i --save-dev @sls-next/serverless-component@1.19.0 @pwrdrvr/serverless-nextjs-router @pwrdrvr/microapps-publish\n```\n\n### Dockerfile\n\nAdd this file to the root of the app.\n\n```Dockerfile\nFROM node:15-slim as base\n\nWORKDIR /app\n\n# Download the sharp libs once to save time\n# Do this before copying anything else in\nRUN mkdir -p image-lambda-npms && \\\n cd image-lambda-npms && npm i sharp && \\\n rm -rf node_modules/sharp/vendor/*/include/\n\n# Copy in the build output from `npx serverless`\nCOPY .serverless_nextjs .\nCOPY config.json .\n\n# Move the sharp libs into place\nRUN rm -rf image-lambda/node_modules/ && \\\n mv image-lambda-npms/node_modules image-labmda/ && \\\n rm -rf image-lambda-npms\n\nFROM public.ecr.aws/lambda/nodejs:14 AS final\n\n# Copy in the munged code\nCOPY --from=base /app .\n\nCMD [ \"./index.handler\" ]\n```\n\n### next.config.js\n\nAdd this file to the root of the app.\n\nReplace `appname` with your URL path-compatible application name.\n\n```js\nconst appRoot = '/appname/0.0.0';\n\n// eslint-disable-next-line no-undef\nmodule.exports = {\n target: 'serverless',\n webpack: (config, _options) => {\n return config;\n },\n basePath: appRoot,\n publicRuntimeConfig: {\n // Will be available on both server and client\n staticFolder: appRoot,\n },\n};\n```\n\n### deploy.json\n\nAdd this file to the root of the app.\n\nReplace `appname` with your URL path-compatible application name.\n\n```json\n{\n \"AppName\": \"appname\",\n \"SemVer\": \"0.0.0\",\n \"DefaultFile\": \"\",\n \"StaticAssetsPath\": \"./.serverless_nextjs/assets/appname/0.0.0/\",\n \"LambdaARN\": \"arn:aws:lambda:us-east-1:123456789012:function:appname:v0_0_0\",\n \"AWSAccountID\": \"123456789012\",\n \"AWSRegion\": \"us-east-2\",\n \"ServerlessNextRouterPath\": \"./node_modules/@pwrdrvr/serverless-nextjs-router/dist/index.js\"\n}\n```\n\n### serverless.yaml\n\nAdd this file to the root of the app.\n\n```yaml\nnextApp:\n component: './node_modules/@sls-next/serverless-component'\n inputs:\n deploy: false\n uploadStaticAssetsFromBuild: false\n```\n\n# Troubleshooting\n\n## CloudFront Requests to API Gateway are Rejected with 403 Forbidden\n\nRequests to the API Gateway origin can be rejected with a 403 Forbidden error if the signed request headers are not sent to the origin by CloudFront.\n\nThe error in the API Gateway CloudWatch logs will show up as:\n\n```log\n\"authorizerError\": \"The request for the IAM Authorizer doesn't match the format that API Gateway expects.\"\n```\n\nThis can be simulated by simply running `curl [api-gateway-url]`, with no headers.\n\nTo confirm that API Gateway is allowing signed requests when the IAM Authorizer is configured, establish credentials as a user that is allowed to execute the API Gateay, install `awscurl` with `pip3 install awscurl`, then then use `awscurl --service execute-api --region [api-gateway-region] [api-gateway-url]`.\n\nSignature headers will not be sent from CloudFront to API Gateway unless the `OriginRequestPolicy` is set to specifically include those headers on requests to the origin, or the `headersBehavior` is set to `cfront.OriginRequestHeaderBehavior.all()`.\n\nSimilarly, if `presign` is used, the `OriginRequestPolicy` must be set to `cfront.OriginRequestQueryStringBehavior.all()` or to specifically forward the query string parameters used by the presigned URL.\n\n### SignatureV4 Headers\n- `authorization`\n- `x-amz-date`\n- `x-amz-security-token`\n- `x-amz-content-sha256`"
|
|
3104
3104
|
},
|
|
3105
3105
|
"repository": {
|
|
3106
3106
|
"type": "git",
|
|
@@ -3210,39 +3210,36 @@
|
|
|
3210
3210
|
{
|
|
3211
3211
|
"abstract": true,
|
|
3212
3212
|
"docs": {
|
|
3213
|
+
"default": "true",
|
|
3214
|
+
"remarks": "When false API routes with a period in the path will get routed to S3.\n\nWhen true API routes that contain /api/ in the path will get routed to API Gateway\neven if they have a period in the path.",
|
|
3213
3215
|
"stability": "experimental",
|
|
3214
|
-
"summary": "
|
|
3216
|
+
"summary": "Create an extra Behavior (Route) for /api/ that allows API routes to have a period in them."
|
|
3215
3217
|
},
|
|
3216
3218
|
"immutable": true,
|
|
3217
3219
|
"locationInModule": {
|
|
3218
3220
|
"filename": "src/MicroAppsCF.ts",
|
|
3219
|
-
"line":
|
|
3221
|
+
"line": 206
|
|
3220
3222
|
},
|
|
3221
|
-
"name": "
|
|
3223
|
+
"name": "createAPIPathRoute",
|
|
3222
3224
|
"optional": true,
|
|
3223
3225
|
"type": {
|
|
3224
|
-
"
|
|
3225
|
-
"elementtype": {
|
|
3226
|
-
"fqn": "aws-cdk-lib.aws_cloudfront.EdgeLambda"
|
|
3227
|
-
},
|
|
3228
|
-
"kind": "array"
|
|
3229
|
-
}
|
|
3226
|
+
"primitive": "boolean"
|
|
3230
3227
|
}
|
|
3231
3228
|
},
|
|
3232
3229
|
{
|
|
3233
3230
|
"abstract": true,
|
|
3234
3231
|
"docs": {
|
|
3235
3232
|
"default": "true",
|
|
3236
|
-
"remarks": "When false API routes with a period in the path will get routed to S3.\n\nWhen true API routes that contain /
|
|
3233
|
+
"remarks": "When false API routes with a period in the path will get routed to S3.\n\nWhen true API routes that contain /_next/data/ in the path will get routed to API Gateway\neven if they have a period in the path.",
|
|
3237
3234
|
"stability": "experimental",
|
|
3238
|
-
"summary": "Create an extra Behavior (Route) for /
|
|
3235
|
+
"summary": "Create an extra Behavior (Route) for /_next/data/ This route is used by Next.js to load data from the API Gateway on `getServerSideProps` calls. The requests can end in `.json`, which would cause them to be routed to S3 if this route is not created."
|
|
3239
3236
|
},
|
|
3240
3237
|
"immutable": true,
|
|
3241
3238
|
"locationInModule": {
|
|
3242
3239
|
"filename": "src/MicroAppsCF.ts",
|
|
3243
|
-
"line":
|
|
3240
|
+
"line": 221
|
|
3244
3241
|
},
|
|
3245
|
-
"name": "
|
|
3242
|
+
"name": "createNextDataPathRoute",
|
|
3246
3243
|
"optional": true,
|
|
3247
3244
|
"type": {
|
|
3248
3245
|
"primitive": "boolean"
|
|
@@ -3251,20 +3248,23 @@
|
|
|
3251
3248
|
{
|
|
3252
3249
|
"abstract": true,
|
|
3253
3250
|
"docs": {
|
|
3254
|
-
"default": "true",
|
|
3255
|
-
"remarks": "When false API routes with a period in the path will get routed to S3.\n\nWhen true API routes that contain /_next/data/ in the path will get routed to API Gateway\neven if they have a period in the path.",
|
|
3256
3251
|
"stability": "experimental",
|
|
3257
|
-
"summary": "
|
|
3252
|
+
"summary": "Edge lambdas to associate with the API Gateway routes."
|
|
3258
3253
|
},
|
|
3259
3254
|
"immutable": true,
|
|
3260
3255
|
"locationInModule": {
|
|
3261
3256
|
"filename": "src/MicroAppsCF.ts",
|
|
3262
|
-
"line":
|
|
3257
|
+
"line": 226
|
|
3263
3258
|
},
|
|
3264
|
-
"name": "
|
|
3259
|
+
"name": "edgeLambdas",
|
|
3265
3260
|
"optional": true,
|
|
3266
3261
|
"type": {
|
|
3267
|
-
"
|
|
3262
|
+
"collection": {
|
|
3263
|
+
"elementtype": {
|
|
3264
|
+
"fqn": "aws-cdk-lib.aws_cloudfront.EdgeLambda"
|
|
3265
|
+
},
|
|
3266
|
+
"kind": "array"
|
|
3267
|
+
}
|
|
3268
3268
|
}
|
|
3269
3269
|
},
|
|
3270
3270
|
{
|
|
@@ -3480,7 +3480,7 @@
|
|
|
3480
3480
|
"kind": "interface",
|
|
3481
3481
|
"locationInModule": {
|
|
3482
3482
|
"filename": "src/MicroApps.ts",
|
|
3483
|
-
"line":
|
|
3483
|
+
"line": 271
|
|
3484
3484
|
},
|
|
3485
3485
|
"name": "IMicroApps",
|
|
3486
3486
|
"properties": [
|
|
@@ -3493,7 +3493,7 @@
|
|
|
3493
3493
|
"immutable": true,
|
|
3494
3494
|
"locationInModule": {
|
|
3495
3495
|
"filename": "src/MicroApps.ts",
|
|
3496
|
-
"line":
|
|
3496
|
+
"line": 285
|
|
3497
3497
|
},
|
|
3498
3498
|
"name": "apigwy",
|
|
3499
3499
|
"type": {
|
|
@@ -3509,7 +3509,7 @@
|
|
|
3509
3509
|
"immutable": true,
|
|
3510
3510
|
"locationInModule": {
|
|
3511
3511
|
"filename": "src/MicroApps.ts",
|
|
3512
|
-
"line":
|
|
3512
|
+
"line": 273
|
|
3513
3513
|
},
|
|
3514
3514
|
"name": "cf",
|
|
3515
3515
|
"type": {
|
|
@@ -3525,7 +3525,7 @@
|
|
|
3525
3525
|
"immutable": true,
|
|
3526
3526
|
"locationInModule": {
|
|
3527
3527
|
"filename": "src/MicroApps.ts",
|
|
3528
|
-
"line":
|
|
3528
|
+
"line": 279
|
|
3529
3529
|
},
|
|
3530
3530
|
"name": "s3",
|
|
3531
3531
|
"type": {
|
|
@@ -3541,7 +3541,7 @@
|
|
|
3541
3541
|
"immutable": true,
|
|
3542
3542
|
"locationInModule": {
|
|
3543
3543
|
"filename": "src/MicroApps.ts",
|
|
3544
|
-
"line":
|
|
3544
|
+
"line": 282
|
|
3545
3545
|
},
|
|
3546
3546
|
"name": "svcs",
|
|
3547
3547
|
"type": {
|
|
@@ -3557,7 +3557,7 @@
|
|
|
3557
3557
|
"immutable": true,
|
|
3558
3558
|
"locationInModule": {
|
|
3559
3559
|
"filename": "src/MicroApps.ts",
|
|
3560
|
-
"line":
|
|
3560
|
+
"line": 276
|
|
3561
3561
|
},
|
|
3562
3562
|
"name": "edgeToOrigin",
|
|
3563
3563
|
"optional": true,
|
|
@@ -3929,7 +3929,7 @@
|
|
|
3929
3929
|
},
|
|
3930
3930
|
"locationInModule": {
|
|
3931
3931
|
"filename": "src/MicroApps.ts",
|
|
3932
|
-
"line":
|
|
3932
|
+
"line": 334
|
|
3933
3933
|
},
|
|
3934
3934
|
"parameters": [
|
|
3935
3935
|
{
|
|
@@ -3959,7 +3959,7 @@
|
|
|
3959
3959
|
"kind": "class",
|
|
3960
3960
|
"locationInModule": {
|
|
3961
3961
|
"filename": "src/MicroApps.ts",
|
|
3962
|
-
"line":
|
|
3962
|
+
"line": 308
|
|
3963
3963
|
},
|
|
3964
3964
|
"name": "MicroApps",
|
|
3965
3965
|
"properties": [
|
|
@@ -3971,7 +3971,7 @@
|
|
|
3971
3971
|
"immutable": true,
|
|
3972
3972
|
"locationInModule": {
|
|
3973
3973
|
"filename": "src/MicroApps.ts",
|
|
3974
|
-
"line":
|
|
3974
|
+
"line": 325
|
|
3975
3975
|
},
|
|
3976
3976
|
"name": "apigwy",
|
|
3977
3977
|
"overrides": "@pwrdrvr/microapps-cdk.IMicroApps",
|
|
@@ -3987,7 +3987,7 @@
|
|
|
3987
3987
|
"immutable": true,
|
|
3988
3988
|
"locationInModule": {
|
|
3989
3989
|
"filename": "src/MicroApps.ts",
|
|
3990
|
-
"line":
|
|
3990
|
+
"line": 310
|
|
3991
3991
|
},
|
|
3992
3992
|
"name": "cf",
|
|
3993
3993
|
"overrides": "@pwrdrvr/microapps-cdk.IMicroApps",
|
|
@@ -4003,7 +4003,7 @@
|
|
|
4003
4003
|
"immutable": true,
|
|
4004
4004
|
"locationInModule": {
|
|
4005
4005
|
"filename": "src/MicroApps.ts",
|
|
4006
|
-
"line":
|
|
4006
|
+
"line": 320
|
|
4007
4007
|
},
|
|
4008
4008
|
"name": "s3",
|
|
4009
4009
|
"overrides": "@pwrdrvr/microapps-cdk.IMicroApps",
|
|
@@ -4019,7 +4019,7 @@
|
|
|
4019
4019
|
"immutable": true,
|
|
4020
4020
|
"locationInModule": {
|
|
4021
4021
|
"filename": "src/MicroApps.ts",
|
|
4022
|
-
"line":
|
|
4022
|
+
"line": 330
|
|
4023
4023
|
},
|
|
4024
4024
|
"name": "svcs",
|
|
4025
4025
|
"overrides": "@pwrdrvr/microapps-cdk.IMicroApps",
|
|
@@ -4035,7 +4035,7 @@
|
|
|
4035
4035
|
"immutable": true,
|
|
4036
4036
|
"locationInModule": {
|
|
4037
4037
|
"filename": "src/MicroApps.ts",
|
|
4038
|
-
"line":
|
|
4038
|
+
"line": 315
|
|
4039
4039
|
},
|
|
4040
4040
|
"name": "edgeToOrigin",
|
|
4041
4041
|
"optional": true,
|
|
@@ -4639,9 +4639,7 @@
|
|
|
4639
4639
|
{
|
|
4640
4640
|
"abstract": true,
|
|
4641
4641
|
"docs": {
|
|
4642
|
-
"
|
|
4643
|
-
"defaunt": "- no edge to API Gateway origin functions added"
|
|
4644
|
-
},
|
|
4642
|
+
"default": "- no edge to API Gateway origin functions added",
|
|
4645
4643
|
"stability": "experimental",
|
|
4646
4644
|
"summary": "Configuration of the edge to origin lambda functions."
|
|
4647
4645
|
},
|
|
@@ -4650,7 +4648,7 @@
|
|
|
4650
4648
|
"filename": "src/MicroAppsCF.ts",
|
|
4651
4649
|
"line": 133
|
|
4652
4650
|
},
|
|
4653
|
-
"name": "
|
|
4651
|
+
"name": "edgeLambdas",
|
|
4654
4652
|
"optional": true,
|
|
4655
4653
|
"type": {
|
|
4656
4654
|
"collection": {
|
|
@@ -5040,7 +5038,7 @@
|
|
|
5040
5038
|
"kind": "interface",
|
|
5041
5039
|
"locationInModule": {
|
|
5042
5040
|
"filename": "src/MicroApps.ts",
|
|
5043
|
-
"line":
|
|
5041
|
+
"line": 39
|
|
5044
5042
|
},
|
|
5045
5043
|
"name": "MicroAppsProps",
|
|
5046
5044
|
"properties": [
|
|
@@ -5054,7 +5052,7 @@
|
|
|
5054
5052
|
"immutable": true,
|
|
5055
5053
|
"locationInModule": {
|
|
5056
5054
|
"filename": "src/MicroApps.ts",
|
|
5057
|
-
"line":
|
|
5055
|
+
"line": 54
|
|
5058
5056
|
},
|
|
5059
5057
|
"name": "appEnv",
|
|
5060
5058
|
"type": {
|
|
@@ -5072,7 +5070,7 @@
|
|
|
5072
5070
|
"immutable": true,
|
|
5073
5071
|
"locationInModule": {
|
|
5074
5072
|
"filename": "src/MicroApps.ts",
|
|
5075
|
-
"line":
|
|
5073
|
+
"line": 203
|
|
5076
5074
|
},
|
|
5077
5075
|
"name": "addXForwardedHostHeader",
|
|
5078
5076
|
"optional": true,
|
|
@@ -5091,7 +5089,7 @@
|
|
|
5091
5089
|
"immutable": true,
|
|
5092
5090
|
"locationInModule": {
|
|
5093
5091
|
"filename": "src/MicroApps.ts",
|
|
5094
|
-
"line":
|
|
5092
|
+
"line": 62
|
|
5095
5093
|
},
|
|
5096
5094
|
"name": "assetNameRoot",
|
|
5097
5095
|
"optional": true,
|
|
@@ -5110,7 +5108,7 @@
|
|
|
5110
5108
|
"immutable": true,
|
|
5111
5109
|
"locationInModule": {
|
|
5112
5110
|
"filename": "src/MicroApps.ts",
|
|
5113
|
-
"line":
|
|
5111
|
+
"line": 70
|
|
5114
5112
|
},
|
|
5115
5113
|
"name": "assetNameSuffix",
|
|
5116
5114
|
"optional": true,
|
|
@@ -5127,7 +5125,7 @@
|
|
|
5127
5125
|
"immutable": true,
|
|
5128
5126
|
"locationInModule": {
|
|
5129
5127
|
"filename": "src/MicroApps.ts",
|
|
5130
|
-
"line":
|
|
5128
|
+
"line": 80
|
|
5131
5129
|
},
|
|
5132
5130
|
"name": "certEdge",
|
|
5133
5131
|
"optional": true,
|
|
@@ -5144,7 +5142,7 @@
|
|
|
5144
5142
|
"immutable": true,
|
|
5145
5143
|
"locationInModule": {
|
|
5146
5144
|
"filename": "src/MicroApps.ts",
|
|
5147
|
-
"line":
|
|
5145
|
+
"line": 85
|
|
5148
5146
|
},
|
|
5149
5147
|
"name": "certOrigin",
|
|
5150
5148
|
"optional": true,
|
|
@@ -5163,7 +5161,7 @@
|
|
|
5163
5161
|
"immutable": true,
|
|
5164
5162
|
"locationInModule": {
|
|
5165
5163
|
"filename": "src/MicroApps.ts",
|
|
5166
|
-
"line":
|
|
5164
|
+
"line": 192
|
|
5167
5165
|
},
|
|
5168
5166
|
"name": "createAPIPathRoute",
|
|
5169
5167
|
"optional": true,
|
|
@@ -5182,7 +5180,7 @@
|
|
|
5182
5180
|
"immutable": true,
|
|
5183
5181
|
"locationInModule": {
|
|
5184
5182
|
"filename": "src/MicroApps.ts",
|
|
5185
|
-
"line":
|
|
5183
|
+
"line": 164
|
|
5186
5184
|
},
|
|
5187
5185
|
"name": "domainNameEdge",
|
|
5188
5186
|
"optional": true,
|
|
@@ -5201,7 +5199,7 @@
|
|
|
5201
5199
|
"immutable": true,
|
|
5202
5200
|
"locationInModule": {
|
|
5203
5201
|
"filename": "src/MicroApps.ts",
|
|
5204
|
-
"line":
|
|
5202
|
+
"line": 172
|
|
5205
5203
|
},
|
|
5206
5204
|
"name": "domainNameOrigin",
|
|
5207
5205
|
"optional": true,
|
|
@@ -5209,6 +5207,28 @@
|
|
|
5209
5207
|
"primitive": "string"
|
|
5210
5208
|
}
|
|
5211
5209
|
},
|
|
5210
|
+
{
|
|
5211
|
+
"abstract": true,
|
|
5212
|
+
"docs": {
|
|
5213
|
+
"stability": "experimental",
|
|
5214
|
+
"summary": "Additional edge lambda functions."
|
|
5215
|
+
},
|
|
5216
|
+
"immutable": true,
|
|
5217
|
+
"locationInModule": {
|
|
5218
|
+
"filename": "src/MicroApps.ts",
|
|
5219
|
+
"line": 265
|
|
5220
|
+
},
|
|
5221
|
+
"name": "edgeLambdas",
|
|
5222
|
+
"optional": true,
|
|
5223
|
+
"type": {
|
|
5224
|
+
"collection": {
|
|
5225
|
+
"elementtype": {
|
|
5226
|
+
"fqn": "aws-cdk-lib.aws_cloudfront.EdgeLambda"
|
|
5227
|
+
},
|
|
5228
|
+
"kind": "array"
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
},
|
|
5212
5232
|
{
|
|
5213
5233
|
"abstract": true,
|
|
5214
5234
|
"docs": {
|
|
@@ -5219,7 +5239,7 @@
|
|
|
5219
5239
|
"immutable": true,
|
|
5220
5240
|
"locationInModule": {
|
|
5221
5241
|
"filename": "src/MicroApps.ts",
|
|
5222
|
-
"line":
|
|
5242
|
+
"line": 237
|
|
5223
5243
|
},
|
|
5224
5244
|
"name": "originRegion",
|
|
5225
5245
|
"optional": true,
|
|
@@ -5236,7 +5256,7 @@
|
|
|
5236
5256
|
"immutable": true,
|
|
5237
5257
|
"locationInModule": {
|
|
5238
5258
|
"filename": "src/MicroApps.ts",
|
|
5239
|
-
"line":
|
|
5259
|
+
"line": 75
|
|
5240
5260
|
},
|
|
5241
5261
|
"name": "r53Zone",
|
|
5242
5262
|
"optional": true,
|
|
@@ -5255,7 +5275,7 @@
|
|
|
5255
5275
|
"immutable": true,
|
|
5256
5276
|
"locationInModule": {
|
|
5257
5277
|
"filename": "src/MicroApps.ts",
|
|
5258
|
-
"line":
|
|
5278
|
+
"line": 47
|
|
5259
5279
|
},
|
|
5260
5280
|
"name": "removalPolicy",
|
|
5261
5281
|
"optional": true,
|
|
@@ -5274,7 +5294,7 @@
|
|
|
5274
5294
|
"immutable": true,
|
|
5275
5295
|
"locationInModule": {
|
|
5276
5296
|
"filename": "src/MicroApps.ts",
|
|
5277
|
-
"line":
|
|
5297
|
+
"line": 215
|
|
5278
5298
|
},
|
|
5279
5299
|
"name": "replaceHostHeader",
|
|
5280
5300
|
"optional": true,
|
|
@@ -5292,7 +5312,7 @@
|
|
|
5292
5312
|
"immutable": true,
|
|
5293
5313
|
"locationInModule": {
|
|
5294
5314
|
"filename": "src/MicroApps.ts",
|
|
5295
|
-
"line":
|
|
5315
|
+
"line": 179
|
|
5296
5316
|
},
|
|
5297
5317
|
"name": "rootPathPrefix",
|
|
5298
5318
|
"optional": true,
|
|
@@ -5312,7 +5332,7 @@
|
|
|
5312
5332
|
"immutable": true,
|
|
5313
5333
|
"locationInModule": {
|
|
5314
5334
|
"filename": "src/MicroApps.ts",
|
|
5315
|
-
"line":
|
|
5335
|
+
"line": 156
|
|
5316
5336
|
},
|
|
5317
5337
|
"name": "s3PolicyBypassAROAs",
|
|
5318
5338
|
"optional": true,
|
|
@@ -5337,7 +5357,7 @@
|
|
|
5337
5357
|
"immutable": true,
|
|
5338
5358
|
"locationInModule": {
|
|
5339
5359
|
"filename": "src/MicroApps.ts",
|
|
5340
|
-
"line":
|
|
5360
|
+
"line": 113
|
|
5341
5361
|
},
|
|
5342
5362
|
"name": "s3PolicyBypassPrincipalARNs",
|
|
5343
5363
|
"optional": true,
|
|
@@ -5361,7 +5381,7 @@
|
|
|
5361
5381
|
"immutable": true,
|
|
5362
5382
|
"locationInModule": {
|
|
5363
5383
|
"filename": "src/MicroApps.ts",
|
|
5364
|
-
"line":
|
|
5384
|
+
"line": 97
|
|
5365
5385
|
},
|
|
5366
5386
|
"name": "s3StrictBucketPolicy",
|
|
5367
5387
|
"optional": true,
|
|
@@ -5380,7 +5400,7 @@
|
|
|
5380
5400
|
"immutable": true,
|
|
5381
5401
|
"locationInModule": {
|
|
5382
5402
|
"filename": "src/MicroApps.ts",
|
|
5383
|
-
"line":
|
|
5403
|
+
"line": 228
|
|
5384
5404
|
},
|
|
5385
5405
|
"name": "signingMode",
|
|
5386
5406
|
"optional": true,
|
|
@@ -5401,7 +5421,7 @@
|
|
|
5401
5421
|
"immutable": true,
|
|
5402
5422
|
"locationInModule": {
|
|
5403
5423
|
"filename": "src/MicroApps.ts",
|
|
5404
|
-
"line":
|
|
5424
|
+
"line": 253
|
|
5405
5425
|
},
|
|
5406
5426
|
"name": "table",
|
|
5407
5427
|
"optional": true,
|
|
@@ -5419,7 +5439,7 @@
|
|
|
5419
5439
|
"immutable": true,
|
|
5420
5440
|
"locationInModule": {
|
|
5421
5441
|
"filename": "src/MicroApps.ts",
|
|
5422
|
-
"line":
|
|
5442
|
+
"line": 260
|
|
5423
5443
|
},
|
|
5424
5444
|
"name": "tableNameForEdgeToOrigin",
|
|
5425
5445
|
"optional": true,
|
|
@@ -6218,6 +6238,6 @@
|
|
|
6218
6238
|
"symbolId": "src/MicroAppsTable:MicroAppsTableProps"
|
|
6219
6239
|
}
|
|
6220
6240
|
},
|
|
6221
|
-
"version": "0.3.
|
|
6222
|
-
"fingerprint": "
|
|
6241
|
+
"version": "0.3.3-alpha.1",
|
|
6242
|
+
"fingerprint": "we/Nm4BO2nQKfcx99/H2WR1RlO1CZ+g1sOvwSGNX7Zo="
|
|
6223
6243
|
}
|
package/API.md
CHANGED
|
@@ -530,14 +530,6 @@ CloudFront Distribution to add the Behaviors (Routes) to.
|
|
|
530
530
|
|
|
531
531
|
---
|
|
532
532
|
|
|
533
|
-
##### `apigwyEdgeFunctions`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.AddRoutesOptions.apigwyEdgeFunctions"></a>
|
|
534
|
-
|
|
535
|
-
- *Type:* [`aws-cdk-lib.aws_cloudfront.EdgeLambda`](#aws-cdk-lib.aws_cloudfront.EdgeLambda)[]
|
|
536
|
-
|
|
537
|
-
Edge lambdas to associate with the API Gateway routes.
|
|
538
|
-
|
|
539
|
-
---
|
|
540
|
-
|
|
541
533
|
##### `createAPIPathRoute`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.AddRoutesOptions.createAPIPathRoute"></a>
|
|
542
534
|
|
|
543
535
|
- *Type:* `boolean`
|
|
@@ -566,6 +558,14 @@ even if they have a period in the path.
|
|
|
566
558
|
|
|
567
559
|
---
|
|
568
560
|
|
|
561
|
+
##### `edgeLambdas`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.AddRoutesOptions.edgeLambdas"></a>
|
|
562
|
+
|
|
563
|
+
- *Type:* [`aws-cdk-lib.aws_cloudfront.EdgeLambda`](#aws-cdk-lib.aws_cloudfront.EdgeLambda)[]
|
|
564
|
+
|
|
565
|
+
Edge lambdas to associate with the API Gateway routes.
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
569
|
##### `rootPathPrefix`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.AddRoutesOptions.rootPathPrefix"></a>
|
|
570
570
|
|
|
571
571
|
- *Type:* `string`
|
|
@@ -860,9 +860,10 @@ API Gateway custom origin domain name.
|
|
|
860
860
|
|
|
861
861
|
---
|
|
862
862
|
|
|
863
|
-
##### `
|
|
863
|
+
##### `edgeLambdas`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.MicroAppsCFProps.edgeLambdas"></a>
|
|
864
864
|
|
|
865
865
|
- *Type:* [`aws-cdk-lib.aws_cloudfront.EdgeLambda`](#aws-cdk-lib.aws_cloudfront.EdgeLambda)[]
|
|
866
|
+
- *Default:* no edge to API Gateway origin functions added
|
|
866
867
|
|
|
867
868
|
Configuration of the edge to origin lambda functions.
|
|
868
869
|
|
|
@@ -1111,6 +1112,14 @@ Optional custom domain name for the API Gateway HTTPv2 API.
|
|
|
1111
1112
|
|
|
1112
1113
|
---
|
|
1113
1114
|
|
|
1115
|
+
##### `edgeLambdas`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.MicroAppsProps.edgeLambdas"></a>
|
|
1116
|
+
|
|
1117
|
+
- *Type:* [`aws-cdk-lib.aws_cloudfront.EdgeLambda`](#aws-cdk-lib.aws_cloudfront.EdgeLambda)[]
|
|
1118
|
+
|
|
1119
|
+
Additional edge lambda functions.
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1114
1123
|
##### `originRegion`<sup>Optional</sup> <a name="@pwrdrvr/microapps-cdk.MicroAppsProps.originRegion"></a>
|
|
1115
1124
|
|
|
1116
1125
|
- *Type:* `string`
|
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ The MicroApps project enables rapidly deploying many web apps to AWS on a single
|
|
|
6
6
|
|
|
7
7
|
MicroApps allows many versions of an application to be deployed either as ephemeral deploys (e.g. for pull request builds) or as semi-permanent deploys. The `microapps-router` Lambda function handled routing requests to apps to the current version targeted for a particular application start request using rules as complex as one is interested in implementing (e.g. A/B testing integration, canary releases, per-user rules for logged in users, per-group, per-deparment, and default rules).
|
|
8
8
|
|
|
9
|
+
2023-01-01 NOTE: The next paragraph is dated as the `iframe` is no longer required for frameworks that write absolute URLs for their static resources and API requests.
|
|
10
|
+
|
|
9
11
|
Users start applications via a URL such as `[/{prefix}]/{appname}/`, which hits the `microapps-router` that looks up the version of the application to be run, then renders a transparent `iframe` with a link to that version. The URL seen by the user in the browser (and available for bookmarking) has no version in it, so subsequent launches (e.g. the next day or just in another tab) will lookup the version again. All relative URL API requests (e.g. `some/api/path`) will go to the corresponding API version that matches the version of the loaded static files, eliminating issues of incompatibility between static files and API deployments.
|
|
10
12
|
|
|
11
13
|
For development / testing purposes only, each version of an applicaton can be accessed directly via a URL of the pattern `[/{prefix}]/{appname}/{semver}/`. These "versioned" URLs are not intended to be advertised to end users as they would cause a user to be stuck on a particular version of the app if the URL was bookmarked. Note that the system does not limit access to particular versions of an application, as of 2022-01-26, but that can be added as a feature.
|
package/changelog.md
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
### [0.3.
|
|
2
|
+
### [0.3.3-alpha.1](https://github.com/pwrdrvr/microapps-core/compare/v0.3.2...v0.3.3-alpha.1) (2023-01-02)
|
package/lib/MicroApps.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
2
2
|
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
|
|
3
|
+
import * as cf from 'aws-cdk-lib/aws-cloudfront';
|
|
3
4
|
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
4
5
|
import * as r53 from 'aws-cdk-lib/aws-route53';
|
|
5
6
|
import { Construct } from 'constructs';
|
|
@@ -235,6 +236,10 @@ export interface MicroAppsProps {
|
|
|
235
236
|
* This is required when using v2 routing
|
|
236
237
|
*/
|
|
237
238
|
readonly tableNameForEdgeToOrigin?: string;
|
|
239
|
+
/**
|
|
240
|
+
* Additional edge lambda functions
|
|
241
|
+
*/
|
|
242
|
+
readonly edgeLambdas?: cf.EdgeLambda[];
|
|
238
243
|
}
|
|
239
244
|
/**
|
|
240
245
|
* Represents a MicroApps
|
package/lib/MicroApps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MicroApps.d.ts","sourceRoot":"","sources":["../src/MicroApps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAC1D,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAyB,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IAEvC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC;IAEnC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC;IAEvC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAExC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAEtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;;;;;;OASG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAErC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAEnD;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"MicroApps.d.ts","sourceRoot":"","sources":["../src/MicroApps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAyB,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IAEvC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC;IAEnC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC;IAEvC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAExC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAEtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;;;;;;OASG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAErC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAEnD;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAE1B,2CAA2C;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAE/C,iCAAiC;IACjC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAE1B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAE9B,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAU,SAAQ,SAAU,YAAW,UAAU;IAC5D,OAAO,CAAC,GAAG,CAAc;IACzB,IAAW,EAAE,IAAI,YAAY,CAE5B;IAED,OAAO,CAAC,aAAa,CAAC,CAAwB;IAC9C,IAAW,YAAY,IAAI,sBAAsB,GAAG,SAAS,CAE5D;IAED,OAAO,CAAC,GAAG,CAAc;IACzB,IAAW,EAAE,IAAI,YAAY,CAE5B;IAED,OAAO,CAAC,OAAO,CAAkB;IACjC,IAAW,MAAM,IAAI,gBAAgB,CAEpC;IAED,OAAO,CAAC,KAAK,CAAgB;IAC7B,IAAW,IAAI,IAAI,cAAc,CAEhC;gBAEW,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc;CAwGjE"}
|