├── .eslintrc.json ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ ├── auto-approve.yml │ ├── build.yml │ ├── codeql.yml │ ├── pull-request-lint.yml │ ├── release.yml │ └── upgrade-v5.yml ├── .gitignore ├── .mergify.yml ├── .npmignore ├── .nvmrc ├── .projen ├── deps.json ├── files.json └── tasks.json ├── .projenrc.ts ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── API.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Pipfile ├── Pipfile.lock ├── README.md ├── SECURITY.md ├── VERSIONS.md ├── examples ├── go │ └── lambda │ │ ├── .gitignore │ │ ├── README.md │ │ ├── cdk.json │ │ ├── go.mod │ │ ├── go.sum │ │ ├── lambda-handler │ │ └── index.ts │ │ ├── lambda.go │ │ └── lambda_test.go ├── python │ ├── lambda-esm │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── settings.json │ │ ├── README.md │ │ ├── app.py │ │ ├── cdk.json │ │ ├── data │ │ │ └── affirmations.json │ │ ├── infrastructure │ │ │ ├── __init__.py │ │ │ └── lambda_esm_stack.py │ │ ├── lambda-handler │ │ │ └── index.mts │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ ├── source.bat │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── unit │ │ │ ├── __init__.py │ │ │ └── test_lambda_esm_stack.py │ └── lambda │ │ ├── .gitignore │ │ ├── .vscode │ │ └── settings.json │ │ ├── README.md │ │ ├── app.py │ │ ├── cdk.json │ │ ├── infrastructure │ │ ├── __init__.py │ │ └── lambda_stack.py │ │ ├── lambda-handler │ │ └── index.ts │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ ├── source.bat │ │ └── tests │ │ ├── __init__.py │ │ └── unit │ │ ├── __init__.py │ │ └── test_lambda_stack.py └── typescript │ ├── .gitignore │ ├── esbuild-with-plugins │ ├── .gitignore │ ├── README.md │ ├── app.ts │ ├── build.mjs │ ├── cdk.json │ ├── lambda.test.ts │ ├── lambda.ts │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json │ ├── lambda-esm │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── cdk.json │ ├── infrastructure │ │ ├── app.ts │ │ └── stack.ts │ ├── input.json │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── index.mts │ ├── test │ │ └── lambda-esm.test.ts │ └── tsconfig.json │ ├── lambda │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── cdk.json │ ├── infrastructure │ │ ├── app.ts │ │ └── stack.ts │ ├── input.json │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ └── lambda.test.ts │ └── tsconfig.json │ └── website │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── cdk.json │ ├── infrastructure │ ├── app.ts │ └── stack.ts │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── App.tsx │ ├── canary.ts │ └── index.tsx │ ├── static │ └── index.html │ ├── test │ └── website.test.ts │ └── tsconfig.json ├── go.mod ├── go.sum ├── images ├── logo.png ├── logo.svg ├── wordmark-dark.svg ├── wordmark-dynamic.svg ├── wordmark-light.svg └── wordmark.svg ├── package-lock.json ├── package.json ├── projenrc ├── IntegrationTests.ts ├── Pipenv.ts ├── ReleaseBranches.ts ├── TypeScriptSourceFile.ts ├── VersionsFile.ts ├── WordmarkReadme.ts └── index.ts ├── rosetta └── default.ts-fixture ├── src ├── asset.ts ├── bundler.ts ├── code.ts ├── esbuild-types.ts ├── index.ts ├── inline-code.ts ├── private │ ├── dynamic-package.ts │ ├── esbuild-source.ts │ └── utils.ts ├── provider.ts └── source.ts ├── test ├── bundler.test.ts ├── code.test.ts ├── fixtures │ └── handlers │ │ ├── colors.ts │ │ ├── invalid-handler.js │ │ ├── js-handler.js │ │ ├── ts-handler.ts │ │ └── util.ts ├── inline-code.test.ts ├── integ │ ├── integ-lambda.py │ ├── integ-lambda.py.snapshot │ │ ├── Lambda.assets.json │ │ ├── Lambda.template.json │ │ ├── LambdaFunctionsDefaultTestDeployAssertF6E30484.assets.json │ │ ├── LambdaFunctionsDefaultTestDeployAssertF6E30484.template.json │ │ ├── asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9 │ │ │ └── index.mjs │ │ ├── asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8 │ │ │ ├── colors.js │ │ │ ├── colors.ts │ │ │ ├── invalid-handler.js │ │ │ ├── js-handler.js │ │ │ ├── ts-handler.ts │ │ │ └── util.ts │ │ ├── integ.json │ │ ├── manifest.json │ │ └── tree.json │ ├── integ-website.py │ ├── integ-website.py.snapshot │ │ ├── S3WebsiteDefaultTestDeployAssert3345D10F.assets.json │ │ ├── S3WebsiteDefaultTestDeployAssert3345D10F.template.json │ │ ├── Website.assets.json │ │ ├── Website.template.json │ │ ├── asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b │ │ │ ├── colors.js │ │ │ ├── colors.ts │ │ │ ├── invalid-handler.js │ │ │ ├── js-handler.js │ │ │ ├── ts-handler.ts │ │ │ └── util.ts │ │ ├── asset.9eb41a5505d37607ac419321497a4f8c21cf0ee1f9b4a6b29aa04301aea5c7fd │ │ │ └── index.py │ │ ├── integ.json │ │ ├── manifest.json │ │ └── tree.json │ ├── integ_lambda.go │ └── integ_lambda.go.snapshot │ │ ├── GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets.json │ │ ├── GoLambdaFunctionsDefaultTestDeployAssert141E9B32.template.json │ │ ├── GoLambdaStack.assets.json │ │ ├── GoLambdaStack.template.json │ │ ├── GoLangDefaultTestDeployAssertA629E612.assets.json │ │ ├── GoLangDefaultTestDeployAssertA629E612.template.json │ │ ├── GoLangStack.assets.json │ │ ├── GoLangStack.template.json │ │ ├── asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9 │ │ └── index.mjs │ │ ├── asset.8f0c571812657f9654505faac7869bb410c192d7feba2ed7246fcb86f64e36e0.bundle │ │ └── index.js │ │ ├── asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8 │ │ ├── colors.js │ │ ├── colors.ts │ │ ├── invalid-handler.js │ │ ├── js-handler.js │ │ ├── ts-handler.ts │ │ └── util.ts │ │ ├── integ.json │ │ ├── manifest.json │ │ └── tree.json ├── provider.test.ts └── source.test.ts ├── tsconfig.dev.json └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "env": { 4 | "jest": true, 5 | "node": true 6 | }, 7 | "root": true, 8 | "plugins": [ 9 | "@typescript-eslint", 10 | "import", 11 | "@stylistic" 12 | ], 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaVersion": 2018, 16 | "sourceType": "module", 17 | "project": "./tsconfig.dev.json" 18 | }, 19 | "extends": [ 20 | "plugin:import/typescript" 21 | ], 22 | "settings": { 23 | "import/parsers": { 24 | "@typescript-eslint/parser": [ 25 | ".ts", 26 | ".tsx" 27 | ] 28 | }, 29 | "import/resolver": { 30 | "node": {}, 31 | "typescript": { 32 | "project": "./tsconfig.dev.json", 33 | "alwaysTryTypes": true 34 | } 35 | } 36 | }, 37 | "ignorePatterns": [ 38 | "*.js", 39 | "*.d.ts", 40 | "node_modules/", 41 | "*.generated.ts", 42 | "coverage", 43 | "examples/", 44 | "!.projenrc.ts", 45 | "!projenrc/**/*.ts" 46 | ], 47 | "rules": { 48 | "@stylistic/indent": [ 49 | "error", 50 | 2 51 | ], 52 | "@stylistic/quotes": [ 53 | "error", 54 | "single", 55 | { 56 | "avoidEscape": true 57 | } 58 | ], 59 | "@stylistic/comma-dangle": [ 60 | "error", 61 | "always-multiline" 62 | ], 63 | "@stylistic/comma-spacing": [ 64 | "error", 65 | { 66 | "before": false, 67 | "after": true 68 | } 69 | ], 70 | "@stylistic/no-multi-spaces": [ 71 | "error", 72 | { 73 | "ignoreEOLComments": false 74 | } 75 | ], 76 | "@stylistic/array-bracket-spacing": [ 77 | "error", 78 | "never" 79 | ], 80 | "@stylistic/array-bracket-newline": [ 81 | "error", 82 | "consistent" 83 | ], 84 | "@stylistic/object-curly-spacing": [ 85 | "error", 86 | "always" 87 | ], 88 | "@stylistic/object-curly-newline": [ 89 | "error", 90 | { 91 | "multiline": true, 92 | "consistent": true 93 | } 94 | ], 95 | "@stylistic/object-property-newline": [ 96 | "error", 97 | { 98 | "allowAllPropertiesOnSameLine": true 99 | } 100 | ], 101 | "@stylistic/keyword-spacing": [ 102 | "error" 103 | ], 104 | "@stylistic/brace-style": [ 105 | "error", 106 | "1tbs", 107 | { 108 | "allowSingleLine": true 109 | } 110 | ], 111 | "@stylistic/space-before-blocks": [ 112 | "error" 113 | ], 114 | "@stylistic/member-delimiter-style": [ 115 | "error" 116 | ], 117 | "@stylistic/semi": [ 118 | "error", 119 | "always" 120 | ], 121 | "@stylistic/max-len": [ 122 | "error", 123 | { 124 | "code": 150, 125 | "ignoreUrls": true, 126 | "ignoreStrings": true, 127 | "ignoreTemplateLiterals": true, 128 | "ignoreComments": true, 129 | "ignoreRegExpLiterals": true 130 | } 131 | ], 132 | "@stylistic/quote-props": [ 133 | "error", 134 | "consistent-as-needed" 135 | ], 136 | "@stylistic/key-spacing": [ 137 | "error" 138 | ], 139 | "@stylistic/no-multiple-empty-lines": [ 140 | "error" 141 | ], 142 | "@stylistic/no-trailing-spaces": [ 143 | "error" 144 | ], 145 | "curly": [ 146 | "error", 147 | "multi-line", 148 | "consistent" 149 | ], 150 | "@typescript-eslint/no-require-imports": "error", 151 | "import/no-extraneous-dependencies": [ 152 | "error", 153 | { 154 | "devDependencies": [ 155 | "**/test/**", 156 | "**/build-tools/**", 157 | ".projenrc.ts", 158 | "projenrc/**/*.ts" 159 | ], 160 | "optionalDependencies": false, 161 | "peerDependencies": true 162 | } 163 | ], 164 | "import/no-unresolved": [ 165 | "error" 166 | ], 167 | "import/order": [ 168 | "warn", 169 | { 170 | "groups": [ 171 | "builtin", 172 | "external" 173 | ], 174 | "alphabetize": { 175 | "order": "asc", 176 | "caseInsensitive": true 177 | } 178 | } 179 | ], 180 | "import/no-duplicates": [ 181 | "error" 182 | ], 183 | "no-shadow": [ 184 | "off" 185 | ], 186 | "@typescript-eslint/no-shadow": "error", 187 | "@typescript-eslint/no-floating-promises": "error", 188 | "no-return-await": [ 189 | "off" 190 | ], 191 | "@typescript-eslint/return-await": "error", 192 | "dot-notation": [ 193 | "error" 194 | ], 195 | "no-bitwise": [ 196 | "error" 197 | ], 198 | "@typescript-eslint/member-ordering": "off", 199 | "no-console": "error", 200 | "eol-last": [ 201 | "error", 202 | "always" 203 | ] 204 | }, 205 | "overrides": [ 206 | { 207 | "files": [ 208 | "test/**" 209 | ], 210 | "rules": { 211 | "no-console": "off" 212 | } 213 | }, 214 | { 215 | "files": [ 216 | "src/esbuild-types.ts" 217 | ], 218 | "rules": { 219 | "max-len": [ 220 | "off" 221 | ] 222 | } 223 | }, 224 | { 225 | "files": [ 226 | "src/esbuild-types.ts" 227 | ], 228 | "rules": { 229 | "@stylistic/max-len": "off" 230 | } 231 | }, 232 | { 233 | "files": [ 234 | ".projenrc.ts" 235 | ], 236 | "rules": { 237 | "@typescript-eslint/no-require-imports": "off", 238 | "import/no-extraneous-dependencies": "off" 239 | } 240 | } 241 | ] 242 | } 243 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | * text=auto eol=lf 4 | *.snap linguist-generated 5 | /.eslintrc.json linguist-generated 6 | /.gitattributes linguist-generated 7 | /.github/pull_request_template.md linguist-generated 8 | /.github/workflows/auto-approve.yml linguist-generated 9 | /.github/workflows/build.yml linguist-generated 10 | /.github/workflows/pull-request-lint.yml linguist-generated 11 | /.github/workflows/release.yml linguist-generated 12 | /.github/workflows/upgrade-v5.yml linguist-generated 13 | /.gitignore linguist-generated 14 | /.mergify.yml linguist-generated 15 | /.npmignore linguist-generated 16 | /.projen/** linguist-generated 17 | /.projen/deps.json linguist-generated 18 | /.projen/files.json linguist-generated 19 | /.projen/tasks.json linguist-generated 20 | /.vscode/extensions.json linguist-generated 21 | /.vscode/launch.json linguist-generated 22 | /.vscode/settings.json linguist-generated 23 | /API.md linguist-generated 24 | /LICENSE linguist-generated 25 | /package-lock.json linguist-generated 26 | /package.json linguist-generated 27 | /Pipfile linguist-generated 28 | /src/esbuild-types.ts linguist-generated 29 | /tsconfig.dev.json linguist-generated 30 | /VERSIONS.md linguist-generated -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | #github: [mrgrain] 4 | ko_fi: mrgrain 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Please provide example code or repository. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Versions:** 20 | - CDK: [e.g. 1.123.0] 21 | - Node.js: [e.g. 14.17.0] 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: auto-approve 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | jobs: 13 | approve: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | pull-requests: write 17 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && (github.event.pull_request.user.login == 'projen-builder[bot]' || github.event.pull_request.user.login == 'mergify[bot]' || github.event.pull_request.user.login == 'mrgrain') 18 | steps: 19 | - uses: hmarr/auto-approve-action@v2.2.1 20 | with: 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: ["v5", "v4"] 6 | pull_request: 7 | branches: ["v5", "v4"] 8 | schedule: 9 | - cron: "36 14 * * 3" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze (${{ matrix.language }}) 14 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} 15 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} 16 | permissions: 17 | # required for all workflows 18 | security-events: write 19 | 20 | # required to fetch internal or private CodeQL packs 21 | packages: read 22 | 23 | # only required for workflows in private repositories 24 | actions: read 25 | contents: read 26 | 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | include: 31 | - language: go 32 | build-mode: autobuild 33 | - language: javascript-typescript 34 | build-mode: none 35 | - language: python 36 | build-mode: none 37 | steps: 38 | - name: Checkout repository 39 | uses: actions/checkout@v4 40 | 41 | # Initializes the CodeQL tools for scanning. 42 | - name: Initialize CodeQL 43 | uses: github/codeql-action/init@v3 44 | with: 45 | languages: ${{ matrix.language }} 46 | build-mode: ${{ matrix.build-mode }} 47 | config: | 48 | paths-ignore: 49 | - "test/integ/*.snapshot/**" 50 | - test/fixtures/handlers/invalid-handler.js 51 | 52 | - name: Perform CodeQL Analysis 53 | uses: github/codeql-action/analyze@v3 54 | with: 55 | category: "/language:${{matrix.language}}" 56 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-lint.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: pull-request-lint 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | - edited 13 | merge_group: {} 14 | jobs: 15 | validate: 16 | name: Validate PR title 17 | runs-on: ubuntu-latest 18 | permissions: 19 | pull-requests: write 20 | if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') 21 | steps: 22 | - uses: amannn/action-semantic-pull-request@v5.4.0 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | types: |- 27 | feat 28 | fix 29 | chore 30 | docs 31 | ci 32 | revert 33 | requireScope: false 34 | -------------------------------------------------------------------------------- /.github/workflows/upgrade-v5.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: upgrade-v5 4 | on: 5 | workflow_dispatch: {} 6 | schedule: 7 | - cron: 0 0 * * * 8 | jobs: 9 | upgrade: 10 | name: Upgrade 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | outputs: 15 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: v5 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 18.x 25 | - name: Install dependencies 26 | run: npm ci 27 | - name: Upgrade dependencies 28 | run: npx projen upgrade 29 | - name: Find mutations 30 | id: create_patch 31 | run: |- 32 | git add . 33 | git diff --staged --patch --exit-code > repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT 34 | working-directory: ./ 35 | - name: Upload patch 36 | if: steps.create_patch.outputs.patch_created 37 | uses: actions/upload-artifact@v4.4.0 38 | with: 39 | name: repo.patch 40 | path: repo.patch 41 | overwrite: true 42 | pr: 43 | name: Create Pull Request 44 | needs: upgrade 45 | runs-on: ubuntu-latest 46 | permissions: 47 | contents: read 48 | if: ${{ needs.upgrade.outputs.patch_created }} 49 | steps: 50 | - name: Generate token 51 | id: generate_token 52 | uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 53 | with: 54 | app-id: ${{ secrets.PROJEN_APP_ID }} 55 | private-key: ${{ secrets.PROJEN_APP_PRIVATE_KEY }} 56 | - name: Checkout 57 | uses: actions/checkout@v4 58 | with: 59 | ref: v5 60 | - name: Download patch 61 | uses: actions/download-artifact@v4 62 | with: 63 | name: repo.patch 64 | path: ${{ runner.temp }} 65 | - name: Apply patch 66 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 67 | - name: Set git identity 68 | run: |- 69 | git config user.name "github-actions" 70 | git config user.email "github-actions@github.com" 71 | - name: Create Pull Request 72 | id: create-pr 73 | uses: peter-evans/create-pull-request@v6 74 | with: 75 | token: ${{ steps.generate_token.outputs.token }} 76 | commit-message: |- 77 | chore(deps): upgrade dependencies 78 | 79 | Upgrades project dependencies. See details in [workflow run]. 80 | 81 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 82 | 83 | ------ 84 | 85 | *Automatically created by projen via the "upgrade-v5" workflow* 86 | branch: github-actions/upgrade-v5 87 | title: "chore(deps): upgrade dependencies" 88 | labels: auto-approve 89 | body: |- 90 | Upgrades project dependencies. See details in [workflow run]. 91 | 92 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 93 | 94 | ------ 95 | 96 | *Automatically created by projen via the "upgrade-v5" workflow* 97 | author: github-actions 98 | committer: github-actions 99 | signoff: true 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | !/.gitattributes 3 | !/.projen/tasks.json 4 | !/.projen/deps.json 5 | !/.projen/files.json 6 | !/.github/workflows/pull-request-lint.yml 7 | !/.github/workflows/auto-approve.yml 8 | !/package.json 9 | !/LICENSE 10 | !/.npmignore 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | lib-cov 23 | coverage 24 | *.lcov 25 | .nyc_output 26 | build/Release 27 | node_modules/ 28 | jspm_packages/ 29 | *.tsbuildinfo 30 | .eslintcache 31 | *.tgz 32 | .yarn-integrity 33 | .cache 34 | .npmrc 35 | *.gz 36 | *.zip 37 | cdk.out 38 | .cdk.staging 39 | examples/template 40 | !/examples/** 41 | /test-reports/ 42 | junit.xml 43 | /coverage/ 44 | !/.github/workflows/build.yml 45 | /dist/changelog.md 46 | /dist/version.txt 47 | !/.github/workflows/release.yml 48 | !/.mergify.yml 49 | !/.github/workflows/upgrade-v5.yml 50 | !/.github/pull_request_template.md 51 | !/test/ 52 | !/tsconfig.dev.json 53 | !/src/ 54 | /lib 55 | /dist/ 56 | !/.eslintrc.json 57 | .jsii 58 | tsconfig.json 59 | !/API.md 60 | !/VERSIONS.md 61 | cdk-integ.out.* 62 | !/Pipfile 63 | .jsii.tabl.json 64 | !/.vscode/extensions.json 65 | !/.vscode/settings.json 66 | !/.vscode/launch.json 67 | !/.projenrc.ts 68 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | queue_rules: 4 | - name: default 5 | update_method: merge 6 | conditions: 7 | - "#approved-reviews-by>=1" 8 | - -label~=(do-not-merge) 9 | - status-success=build 10 | - status-success=package-js 11 | - status-success=package-java 12 | - status-success=package-python 13 | - status-success=package-dotnet 14 | - status-success=package-go 15 | - status-success=integ-python 16 | - status-success=integ-go 17 | - status-success=test-latest-versions 18 | merge_method: squash 19 | commit_message_template: |- 20 | {{ title }} (#{{ number }}) 21 | 22 | {{ body }} 23 | pull_request_rules: 24 | - name: Automatic merge on approval and successful build 25 | actions: 26 | delete_head_branch: {} 27 | queue: 28 | name: default 29 | conditions: 30 | - "#approved-reviews-by>=1" 31 | - -label~=(do-not-merge) 32 | - status-success=build 33 | - status-success=package-js 34 | - status-success=package-java 35 | - status-success=package-python 36 | - status-success=package-dotnet 37 | - status-success=package-go 38 | - status-success=integ-python 39 | - status-success=integ-go 40 | - status-success=test-latest-versions 41 | defaults: 42 | actions: 43 | backport: 44 | labels: 45 | - auto-approve 46 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | .npmrc 3 | .nvmrc 4 | .versionrc 5 | .gitattributes 6 | *.tgz 7 | *.gz 8 | *.zip 9 | cdk.out 10 | .cdk.staging 11 | /examples 12 | PUBLISHING.md 13 | .vscode 14 | .projenrc.ts 15 | projenrc 16 | /images 17 | API.md 18 | CHANGELOG.md 19 | CONTRIBUTING.md 20 | SECURITY.md 21 | /.projen/ 22 | /test-reports/ 23 | junit.xml 24 | /coverage/ 25 | permissions-backup.acl 26 | /dist/changelog.md 27 | /dist/version.txt 28 | /.mergify.yml 29 | /test/ 30 | /tsconfig.dev.json 31 | /src/ 32 | !/lib/ 33 | !/lib/**/*.js 34 | !/lib/**/*.d.ts 35 | dist 36 | /tsconfig.json 37 | /.github/ 38 | /.vscode/ 39 | /.idea/ 40 | /.projenrc.js 41 | tsconfig.tsbuildinfo 42 | /.eslintrc.json 43 | !.jsii 44 | Pipfile 45 | Pipfile.lock 46 | go.mod 47 | go.sum 48 | .jsii.tabl.json 49 | /rosetta/ 50 | /.gitattributes 51 | /.projenrc.ts 52 | /projenrc 53 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 -------------------------------------------------------------------------------- /.projen/deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "@aws-cdk/aws-synthetics-alpha", 5 | "version": "2.51.0-alpha.0", 6 | "type": "build" 7 | }, 8 | { 9 | "name": "@aws-cdk/integ-runner", 10 | "version": "latest", 11 | "type": "build" 12 | }, 13 | { 14 | "name": "@stylistic/eslint-plugin", 15 | "version": "^2", 16 | "type": "build" 17 | }, 18 | { 19 | "name": "@types/eslint", 20 | "type": "build" 21 | }, 22 | { 23 | "name": "@types/jest", 24 | "type": "build" 25 | }, 26 | { 27 | "name": "@types/node", 28 | "version": "ts5.8", 29 | "type": "build" 30 | }, 31 | { 32 | "name": "@typescript-eslint/eslint-plugin", 33 | "version": "^8", 34 | "type": "build" 35 | }, 36 | { 37 | "name": "@typescript-eslint/parser", 38 | "version": "^8", 39 | "type": "build" 40 | }, 41 | { 42 | "name": "commit-and-tag-version", 43 | "version": "^12", 44 | "type": "build" 45 | }, 46 | { 47 | "name": "esbuild", 48 | "version": "^0.25.0", 49 | "type": "build" 50 | }, 51 | { 52 | "name": "eslint-import-resolver-typescript", 53 | "type": "build" 54 | }, 55 | { 56 | "name": "eslint-plugin-import", 57 | "type": "build" 58 | }, 59 | { 60 | "name": "eslint", 61 | "version": "^9", 62 | "type": "build" 63 | }, 64 | { 65 | "name": "jest", 66 | "type": "build" 67 | }, 68 | { 69 | "name": "jest-junit", 70 | "version": "^16", 71 | "type": "build" 72 | }, 73 | { 74 | "name": "jest-mock", 75 | "type": "build" 76 | }, 77 | { 78 | "name": "jsii-diff", 79 | "type": "build" 80 | }, 81 | { 82 | "name": "jsii-docgen", 83 | "version": "^10.5.0", 84 | "type": "build" 85 | }, 86 | { 87 | "name": "jsii-pacmak", 88 | "type": "build" 89 | }, 90 | { 91 | "name": "jsii-rosetta", 92 | "version": "5.8.x", 93 | "type": "build" 94 | }, 95 | { 96 | "name": "jsii", 97 | "version": "5.8.x", 98 | "type": "build" 99 | }, 100 | { 101 | "name": "projen", 102 | "type": "build" 103 | }, 104 | { 105 | "name": "ts-jest", 106 | "type": "build" 107 | }, 108 | { 109 | "name": "ts-morph", 110 | "type": "build" 111 | }, 112 | { 113 | "name": "ts-node", 114 | "type": "build" 115 | }, 116 | { 117 | "name": "typescript", 118 | "version": "5.8.x", 119 | "type": "build" 120 | }, 121 | { 122 | "name": "aws-cdk-lib", 123 | "version": "^2.51.0", 124 | "type": "peer" 125 | }, 126 | { 127 | "name": "constructs", 128 | "version": "^10.0.5", 129 | "type": "peer" 130 | } 131 | ], 132 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 133 | } 134 | -------------------------------------------------------------------------------- /.projen/files.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | ".eslintrc.json", 4 | ".gitattributes", 5 | ".github/pull_request_template.md", 6 | ".github/workflows/auto-approve.yml", 7 | ".github/workflows/build.yml", 8 | ".github/workflows/pull-request-lint.yml", 9 | ".github/workflows/release.yml", 10 | ".github/workflows/upgrade-v5.yml", 11 | ".gitignore", 12 | ".mergify.yml", 13 | ".projen/deps.json", 14 | ".projen/files.json", 15 | ".projen/tasks.json", 16 | ".vscode/extensions.json", 17 | ".vscode/launch.json", 18 | ".vscode/settings.json", 19 | "LICENSE", 20 | "Pipfile", 21 | "tsconfig.dev.json", 22 | "VERSIONS.md" 23 | ], 24 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 25 | } 26 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "recommendations": [ 4 | "dbaeumer.vscode-eslint", 5 | "orta.vscode-jest" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "name": "vscode-jest-tests.v2", 7 | "request": "launch", 8 | "internalConsoleOptions": "neverOpen", 9 | "program": "${workspaceFolder}/node_modules/.bin/jest", 10 | "args": [ 11 | "--runInBand", 12 | "--watchAll=false", 13 | "--testNamePattern", 14 | "${jest.testNamePattern}", 15 | "--runTestsByPath", 16 | "${jest.testFile}" 17 | ], 18 | "console": "integratedTerminal", 19 | "disableOptimisticBPs": true, 20 | "cwd": "${workspaceFolder}" 21 | } 22 | ], 23 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "eslint.format.enable": true, 5 | "jest.autoRun": "off", 6 | "jest.jestCommandLine": "./node_modules/.bin/jest", 7 | "svg.preview.background": "dark-transparent", 8 | "python.formatting.provider": "black", 9 | "[javascript]": { 10 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 11 | }, 12 | "[typescript]": { 13 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 14 | }, 15 | "[svg]": { 16 | "editor.defaultFormatter": "jock.svg" 17 | }, 18 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 19 | } 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | ## Getting started 4 | 5 | - Fork the repository on GitHub 6 | - Checkout the fork and create a branch for you to work on 7 | - This project uses [projen](https://github.com/projen/projen) as a management tool 8 | - Run `npm ci` once, then `npm build` 9 | 10 | ## Testing packages for other languages 11 | 12 | Like every Construct, *cdk-esbuild* is a [jsii](https://github.com/aws/jsii) project and a package is published for additional language. 13 | Sometimes it is required to test these generated packages in a real life environment. 14 | All paths in the instructions below, will assume you are testing with one of the examples. 15 | 16 | ### Node.js 17 | 18 | **Option 1:** 19 | 20 | *This is the preferred approach, as it is more consistent and closer to how npm would behave for a real user.* 21 | 22 | - `pj build` 23 | - The Node.js package can be found in `dist/js` 24 | - In your Python app, run `npm install ../../../dist/js/cdk-esbuild@0.0.0.jsii.tgz` (path to the file in dist) 25 | - `npx cdk synth` will use the locally build version 26 | 27 | **Option 2:** 28 | 29 | *This approach allows for faster iterations. However it is not a true representation of what would happen for a real user. There are known issues with CDK version mismatches.* 30 | 31 | - In `package.json` add/change `@mrgrain/cdk-esbuild: '../../..'` (path to your) 32 | - `npx cdk synth` will use the compiled files in `lib` 33 | 34 | ### Python 35 | 36 | - `pj build` 37 | - The Python package can be found in `dist/python` 38 | - In your Python app, run `pip install -I ../../../dist/python/mrgrain.cdk_esbuild-0.0.0-py3-none-any.whl` (path to the .whl file) 39 | - `npx cdk synth` will use the locally build version 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Moritz Kornher 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | [[source]] 4 | url = "https://pypi.org/simple" 5 | verify_ssl = true 6 | name = "pypi" 7 | 8 | [packages] 9 | "aws-cdk-lib" = "==2.84.0" 10 | "aws-cdk.integ-tests-alpha" = "==2.84.0a0" 11 | "constructs" = "<11.0.0,>=10.0.0" 12 | "mrgrain.cdk-esbuild" = {path = "./dist/python/mrgrain_cdk_esbuild-0.0.0-py3-none-any.whl"} 13 | 14 | [dev-packages] 15 | 16 | [requires] 17 | python_version = "3" 18 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Report a vulnerability 4 | 5 | Please use the form located at **Security** > **Report a vulnerability**.\ 6 | See [Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) for detailed instructions. 7 | 8 | ## Response time expectation 9 | 10 | I aim to respond to reported security vulnerabilities within 72h. 11 | However this is an open source project with a single maintainer and life can get in the way. 12 | 13 | ## Supported versions 14 | 15 | Please refer to [VERSIONS.md](./VERSIONS.md) for a complete list of currently supported versions and the support schedule. 16 | -------------------------------------------------------------------------------- /VERSIONS.md: -------------------------------------------------------------------------------- 1 | # Supported Versions 2 | 3 | Only the latest release of each major version is supported. 4 | 5 | | Package version | CDK version | Node.js versions | Support | 6 | | --------------- | ----------- | ---------------- | ------------------------------------------------------------- | 7 | | v5 | ^2.51.0 | >=18 | :white_check_mark: | 8 | | v4 | ^2.12.0 | >=14 | :x: Support ended on 1 December 2024 | 9 | | v3 | ^2.0.0 | >=14 | :x: Support ended on 1 February 2024 | 10 | | v2 | ^1.99.0 | >=14 | :x: Support ended on 1 June 2023 | 11 | | v1 | ^1.99.0 | >=12 | :x: Support ended on 21 November 2021 | 12 | 13 | ## Tags on npm 14 | 15 | | Tag | Description | Major version | Will the version change? | 16 | | ----------- | ---------------------------------------------------- | ------------- | ---------------------------- | 17 | | `latest` | The latest stable release of the package | `v5` | Yes, with new major versions | 18 | | `latest-v*` | The latest stable release of each major version | n/a | No | 19 | | `cdk-v2` | The latest stable release compatible with AWS CDK v2 | `v5` | Yes, with new major versions | 20 | | `cdk-v1` | The latest stable release compatible with AWS CDK v1 | `v2` | No | 21 | -------------------------------------------------------------------------------- /examples/go/lambda/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # go.sum should be committed 15 | !go.sum 16 | 17 | # CDK asset staging directory 18 | .cdk.staging 19 | cdk.out 20 | -------------------------------------------------------------------------------- /examples/go/lambda/README.md: -------------------------------------------------------------------------------- 1 | # Go Lambda example 2 | 3 | This is an example how to create a Node.js Lambda Function using cdk-esbuild and Go. 4 | 5 | All features are available, but refer to the specific [Go usage instructions](https://github.com/mrgrain/cdk-esbuild#python-net-go) for further details. 6 | 7 | ## Getting started 8 | 9 | Install all dependencies: 10 | 11 | ```console 12 | go mod tidy 13 | ``` 14 | 15 | You can now synth the CDK app: 16 | 17 | ```console 18 | cdk synth 19 | ``` 20 | 21 | Next you can deploy your app: 22 | 23 | ```console 24 | cdk deploy 25 | ``` 26 | 27 | If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `cdk bootstrap`) and sort out permissions. 28 | Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 29 | 30 | As part of the deployment, the ARN of your function will be displayed. We need this for the next step. 31 | 32 | To test your function, you can use the aws-cli to invoke the function from the command line and response will be printed to the console: 33 | 34 | ```console 35 | aws lambda invoke \ 36 | --cli-binary-format raw-in-base64-out --no-cli-pager --output json \ 37 | --payload '{"color": "purple", "food": "noodles", "season": "summer"}' \ 38 | --function-name "" \ 39 | /dev/stdout 40 | ``` 41 | 42 | Change the payload values to see how the response changes! 43 | 44 | ### Install esbuild locally (optional, but recommended) 45 | 46 | Inside your Go project, run the following command to install a local version of esbuild: 47 | 48 | ```console 49 | npm install esbuild 50 | ``` 51 | 52 | This will create a `package.json` and `package-lock-json` file in your project root. 53 | These files should be committed to version control. 54 | 55 | In automated builds, add `npm ci` as an additional setup step. 56 | 57 | ### Testing your code 58 | 59 | To execute the provided example test, simply run: 60 | 61 | ```console 62 | go test 63 | ``` 64 | 65 | ### Clean-up 66 | 67 | Don't forget to run `cdk destroy` - otherwise you might incur costs. 68 | -------------------------------------------------------------------------------- /examples/go/lambda/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "go mod download && go run lambda.go", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "go.mod", 11 | "go.sum", 12 | "**/*test.go" 13 | ] 14 | }, 15 | "context": { 16 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 17 | "@aws-cdk/core:checkSecretUsage": true, 18 | "@aws-cdk/core:target-partitions": [ 19 | "aws", 20 | "aws-cn" 21 | ], 22 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 23 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 24 | "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, 25 | "@aws-cdk/aws-iam:minimizePolicies": true, 26 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 27 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, 28 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, 29 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, 30 | "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, 31 | "@aws-cdk/core:enablePartitionLiterals": true, 32 | "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, 33 | "@aws-cdk/aws-iam:standardizedServicePrincipals": true, 34 | "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, 35 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/go/lambda/go.mod: -------------------------------------------------------------------------------- 1 | module lambda 2 | 3 | go 1.21.2 4 | 5 | require ( 6 | github.com/aws/aws-cdk-go/awscdk/v2 v2.95.1 7 | github.com/aws/constructs-go/constructs/v10 v10.2.70 8 | github.com/aws/jsii-runtime-go v1.88.0 9 | github.com/mrgrain/cdk-esbuild-go/cdkesbuild/v4 v4.3.0 10 | ) 11 | 12 | require ( 13 | github.com/Masterminds/semver/v3 v3.2.1 // indirect 14 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.200 // indirect 15 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 // indirect 16 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1 // indirect 17 | github.com/fatih/color v1.15.0 // indirect 18 | github.com/mattn/go-colorable v0.1.13 // indirect 19 | github.com/mattn/go-isatty v0.0.19 // indirect 20 | github.com/yuin/goldmark v1.5.3 // indirect 21 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect 22 | golang.org/x/mod v0.12.0 // indirect 23 | golang.org/x/sys v0.11.0 // indirect 24 | golang.org/x/tools v0.12.0 // indirect 25 | ) 26 | -------------------------------------------------------------------------------- /examples/go/lambda/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= 2 | github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= 3 | github.com/aws/aws-cdk-go/awscdk/v2 v2.95.1 h1:XDik50FubLMLvbrRM9IkV3xGyDBDULFYA3QBDgeSZ4g= 4 | github.com/aws/aws-cdk-go/awscdk/v2 v2.95.1/go.mod h1:0HMIUTNhy228wx8J/O5sHPCE+yWP0kiomWjmCctSnRY= 5 | github.com/aws/constructs-go/constructs/v10 v10.2.70 h1:CuKeOwf27CzGUt8XxOZStFSOVZ7An5XpCzxvqUk8zW4= 6 | github.com/aws/constructs-go/constructs/v10 v10.2.70/go.mod h1:Jnh2jtqYQBjifA5+03aJmnIItEcjqAgMBJ8iZpFjNRE= 7 | github.com/aws/jsii-runtime-go v1.88.0 h1:1qJ9Ane+oxTt1c3xkpDE5YIv53MzKDKYcAr70lAxT/Q= 8 | github.com/aws/jsii-runtime-go v1.88.0/go.mod h1:rIisDqmDOviluOfibmnvjr1I9u2EFcbWLWUjOXy9/Ms= 9 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.200 h1:CwkS78cin4h5A3IaDcL69GrBI1HgTEB/xtECTf1luCc= 10 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.200/go.mod h1:sx6+u9s3UHyhm9BGrkGdQgNA0Ni5ekbJ9hW2Gupvoy0= 11 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 h1:k+WD+6cERd59Mao84v0QtRrcdZuuSMfzlEmuIypKnVs= 12 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2/go.mod h1:CvFHBo0qcg8LUkJqIxQtP1rD/sNGv9bX3L2vHT2FUAo= 13 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1 h1:MBBQNKKPJ5GArbctgwpiCy7KmwGjHDjUUH5wEzwIq8w= 14 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1/go.mod h1:/2WiXEft9s8ViJjD01CJqDuyJ8HXBjhBLtK5OvJfdSc= 15 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 16 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= 18 | github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= 19 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 20 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 21 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 22 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 23 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 24 | github.com/mrgrain/cdk-esbuild-go/cdkesbuild/v4 v4.3.0 h1:qmZT2QqlOvDcgl2+IfIdH5OeZOuhYM38etYN3AYof4Q= 25 | github.com/mrgrain/cdk-esbuild-go/cdkesbuild/v4 v4.3.0/go.mod h1:pzpj/ahjZughi26F/UWZNnZliv7I1mqBDLvwIV9WIzM= 26 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 27 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 28 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 29 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 30 | github.com/yuin/goldmark v1.5.3 h1:3HUJmBFbQW9fhQOzMgseU134xfi6hU+mjWywx5Ty+/M= 31 | github.com/yuin/goldmark v1.5.3/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 32 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 33 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 34 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= 35 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 36 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 37 | golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= 38 | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 39 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 40 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 41 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 42 | golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= 43 | golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 44 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 45 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 46 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 47 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 48 | golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= 49 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 50 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 51 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 52 | golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= 53 | golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= 54 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 55 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 56 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 57 | -------------------------------------------------------------------------------- /examples/go/lambda/lambda-handler/index.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | color: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites): Promise => { 8 | return ( 9 | `My favorite color is ${favorites.color}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /examples/go/lambda/lambda.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/aws/aws-cdk-go/awscdk/v2" 5 | "github.com/aws/aws-cdk-go/awscdk/v2/awslambda" 6 | "github.com/aws/constructs-go/constructs/v10" 7 | "github.com/aws/jsii-runtime-go" 8 | "github.com/mrgrain/cdk-esbuild-go/cdkesbuild/v4" 9 | ) 10 | 11 | type LambdaStackProps struct { 12 | awscdk.StackProps 13 | } 14 | 15 | func NewLambdaStack(scope constructs.Construct, id string, props *LambdaStackProps) awscdk.Stack { 16 | var sprops awscdk.StackProps 17 | if props != nil { 18 | sprops = props.StackProps 19 | } 20 | stack := awscdk.NewStack(scope, &id, &sprops) 21 | 22 | lambda := awslambda.NewFunction(stack, jsii.String("Lambda"), &awslambda.FunctionProps{ 23 | Runtime: awslambda.Runtime_NODEJS_18_X(), 24 | Handler: jsii.String("index.handler"), 25 | Code: cdkesbuild.NewTypeScriptCode(jsii.String("./lambda-handler/index.ts"), &cdkesbuild.TypeScriptCodeProps{}), 26 | }) 27 | 28 | awscdk.NewCfnOutput(stack, jsii.String("LambdaArn"), &awscdk.CfnOutputProps{ 29 | Value: lambda.FunctionArn(), 30 | }) 31 | 32 | return stack 33 | } 34 | 35 | func main() { 36 | defer jsii.Close() 37 | 38 | app := awscdk.NewApp(nil) 39 | 40 | NewLambdaStack(app, "GoExample", &LambdaStackProps{}) 41 | 42 | app.Synth(nil) 43 | } 44 | -------------------------------------------------------------------------------- /examples/go/lambda/lambda_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/aws/aws-cdk-go/awscdk/v2" 7 | "github.com/aws/aws-cdk-go/awscdk/v2/assertions" 8 | "github.com/aws/jsii-runtime-go" 9 | ) 10 | 11 | func TestLambdaStack(t *testing.T) { 12 | // GIVEN 13 | app := awscdk.NewApp(nil) 14 | 15 | // WHEN 16 | stack := NewLambdaStack(app, "GoTestStack", nil) 17 | 18 | // THEN 19 | template := assertions.Template_FromStack(stack, &assertions.TemplateParsingOptions{}) 20 | 21 | template.HasResourceProperties(jsii.String("AWS::Lambda::Function"), map[string]interface{}{ 22 | "Handler": "index.handler", 23 | "Runtime": "nodejs18.x", 24 | }) 25 | 26 | template.HasOutput(jsii.String("LambdaArn"), struct{}{}) 27 | } 28 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .venv 6 | *.egg-info 7 | 8 | # CDK asset staging directory 9 | .cdk.staging 10 | cdk.out 11 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } 4 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Python Lambda ESM example 3 | 4 | This is an example how to create a Node.js ESM Lambda Function using cdk-esbuild and Python. 5 | 6 | Refer to the specific [Python usage instructions](https://github.com/mrgrain/cdk-esbuild#python-net-go) for further details. 7 | 8 | Inspired by [this AWS blog post](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/), ESM Lambda functions allow the use of top-level await. 9 | 10 | ## Getting started 11 | 12 | To set up a new virtualenv, run: 13 | 14 | ```console 15 | python3 -m venv .venv 16 | ``` 17 | 18 | Then activate the virtualenv and install all dependencies: 19 | 20 | ```console 21 | source .venv/bin/activate 22 | pip install -r requirements.txt -r requirements-dev.txt 23 | ``` 24 | 25 | You can now synth the CDK app: 26 | 27 | ```console 28 | cdk synth 29 | ``` 30 | 31 | Next you can deploy your app: 32 | 33 | ```console 34 | cdk deploy 35 | ``` 36 | 37 | If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `cdk bootstrap`) and sort out permissions. 38 | Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 39 | 40 | At the end of the deployment, the URL of your function will be displayed. 41 | To test your function, open the URL in a browser. 42 | 43 | While the output changes on every refresh, the data file is only loaded once and kept in memory of the particular function instance. 44 | Have a look at the Lambda code in `./lambda-handler/index.mts`. 45 | Reading the JSON file is done outside the handler function, similar to how dynamic configuration might be retrieved. 46 | See this [blog post](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/) for details. 47 | 48 | ### Install esbuild locally (optional, but recommended) 49 | 50 | Inside the Python package, run the following command to install a local version of esbuild: 51 | 52 | ```console 53 | npm install esbuild 54 | ``` 55 | 56 | This will create a `package.json` and `package-lock-json` file in your project root. 57 | These files should be committed to version control. 58 | 59 | In automated builds, add `npm ci` as an additional setup step. 60 | 61 | ### Testing your code 62 | 63 | To execute the provided example test, simply run: 64 | 65 | ```console 66 | pytest 67 | ``` 68 | 69 | ### Clean-up 70 | 71 | Don't forget to run `cdk destroy` - otherwise you might incur costs. 72 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import aws_cdk as cdk 3 | 4 | from infrastructure.lambda_esm_stack import LambdaEsmStack 5 | 6 | 7 | app = cdk.App() 8 | LambdaEsmStack(app, "LambdaEsmStack") 9 | 10 | app.synth() 11 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "requirements*.txt", 11 | "source.bat", 12 | "**/__init__.py", 13 | "python/__pycache__", 14 | "tests" 15 | ] 16 | }, 17 | "context": { 18 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 19 | "@aws-cdk/core:stackRelativeExports": true, 20 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 21 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 22 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 23 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 24 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 25 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 26 | "@aws-cdk/core:checkSecretUsage": true, 27 | "@aws-cdk/aws-iam:minimizePolicies": true, 28 | "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, 29 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 30 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, 31 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, 32 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, 33 | "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, 34 | "@aws-cdk/core:enablePartitionLiterals": true, 35 | "@aws-cdk/core:target-partitions": [ 36 | "aws", 37 | "aws-cn" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/data/affirmations.json: -------------------------------------------------------------------------------- 1 | [ 2 | "You are a great Python developer.", 3 | "You can do anything you like, including running cdk-esbuild in Python.", 4 | "It's okay if you haven't upgraded your python2 apps yet." 5 | ] 6 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/infrastructure/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda-esm/infrastructure/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda-esm/infrastructure/lambda_esm_stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack, CfnOutput 2 | import aws_cdk.aws_lambda as lambda_ 3 | from constructs import Construct 4 | from mrgrain.cdk_esbuild import TypeScriptCode, BuildOptions 5 | 6 | 7 | class LambdaEsmStack(Stack): 8 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 9 | super().__init__(scope, construct_id, **kwargs) 10 | 11 | lambda_fn = lambda_.Function( 12 | self, 13 | "Lambda", 14 | runtime=lambda_.Runtime.NODEJS_18_X, 15 | handler="index.handler", 16 | code=TypeScriptCode( 17 | "lambda-handler/index.mts", 18 | build_options=BuildOptions(format="esm", outfile="index.mjs"), 19 | copy_dir={"./data": "data"}, 20 | ), 21 | ) 22 | 23 | url = lambda_fn.add_function_url(auth_type=lambda_.FunctionUrlAuthType.NONE) 24 | 25 | CfnOutput(self, "LambdaUrl", value=url.url) 26 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/lambda-handler/index.mts: -------------------------------------------------------------------------------- 1 | import { readFile } from "fs/promises"; 2 | 3 | 4 | const affirmations = JSON.parse((await readFile("data/affirmations.json")).toString('utf-8')) as string[]; 5 | 6 | export const handler = async () => { 7 | return affirmations[Math.floor(Math.random()*affirmations.length)]; 8 | }; 9 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest==6.2.5 2 | black>=22.6.0 3 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/requirements.txt: -------------------------------------------------------------------------------- 1 | aws-cdk-lib==2.95.1 2 | constructs>=10.0.0,<11.0.0 3 | mrgrain.cdk-esbuild>=5.0.0rc0 -------------------------------------------------------------------------------- /examples/python/lambda-esm/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /examples/python/lambda-esm/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda-esm/tests/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda-esm/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda-esm/tests/unit/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda-esm/tests/unit/test_lambda_esm_stack.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as core 2 | import aws_cdk.assertions as assertions 3 | 4 | from infrastructure.lambda_esm_stack import LambdaEsmStack 5 | 6 | 7 | def test_lambda_esm_created(): 8 | app = core.App() 9 | stack = LambdaEsmStack(app, "LambdaEsm") 10 | template = assertions.Template.from_stack(stack) 11 | 12 | template.resource_count_is("AWS::Lambda::Function", 1) 13 | -------------------------------------------------------------------------------- /examples/python/lambda/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .venv 6 | *.egg-info 7 | 8 | # CDK asset staging directory 9 | .cdk.staging 10 | cdk.out 11 | -------------------------------------------------------------------------------- /examples/python/lambda/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } 4 | -------------------------------------------------------------------------------- /examples/python/lambda/README.md: -------------------------------------------------------------------------------- 1 | # Python Lambda example 2 | 3 | This is an example how to create a Node.js Lambda Function using cdk-esbuild and Python. 4 | 5 | All features are available, but refer to the specific [Python usage instructions](https://github.com/mrgrain/cdk-esbuild#python-net-go) for further details. 6 | 7 | ## Getting started 8 | 9 | To set up a new virtualenv, run: 10 | 11 | ```console 12 | python3 -m venv .venv 13 | ``` 14 | 15 | Then activate the virtualenv and install all dependencies: 16 | 17 | ```console 18 | source .venv/bin/activate 19 | pip install -r requirements.txt -r requirements-dev.txt 20 | ``` 21 | 22 | You can now synth the CDK app: 23 | 24 | ```console 25 | cdk synth 26 | ``` 27 | 28 | Next you can deploy your app: 29 | 30 | ```console 31 | cdk deploy 32 | ``` 33 | 34 | If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `cdk bootstrap`) and sort out permissions. 35 | Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 36 | 37 | As part of the deployment, the ARN of your function will be displayed. We need this for the next step. 38 | 39 | To test your function, you can use the aws-cli to invoke the function from the command line and response will be printed to the console: 40 | 41 | ```console 42 | aws lambda invoke \ 43 | --cli-binary-format raw-in-base64-out --no-cli-pager --output json \ 44 | --payload '{"color": "snake green", "food": "mice", "season": "rain season"}' \ 45 | --function-name "" \ 46 | /dev/stdout 47 | ``` 48 | 49 | Change the payload values to see how the response changes! 50 | 51 | ### Install esbuild locally (optional, but recommended) 52 | 53 | Inside the Python package, run the following command to install a local version of esbuild: 54 | 55 | ```console 56 | npm install esbuild 57 | ``` 58 | 59 | This will create a `package.json` and `package-lock-json` file in your project root. 60 | These files should be committed to version control. 61 | 62 | In automated builds, add `npm ci` as an additional setup step. 63 | 64 | ### Testing your code 65 | 66 | To execute the provided example test, simply run: 67 | 68 | ```console 69 | pytest 70 | ``` 71 | 72 | ### Clean-up 73 | 74 | Don't forget to run `cdk destroy` - otherwise you might incur costs. 75 | -------------------------------------------------------------------------------- /examples/python/lambda/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import aws_cdk as cdk 3 | 4 | from infrastructure.lambda_stack import LambdaStack 5 | 6 | 7 | app = cdk.App() 8 | LambdaStack(app, "LambdaStack") 9 | 10 | app.synth() 11 | -------------------------------------------------------------------------------- /examples/python/lambda/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "requirements*.txt", 11 | "source.bat", 12 | "**/__init__.py", 13 | "python/__pycache__", 14 | "tests" 15 | ] 16 | }, 17 | "context": { 18 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 19 | "@aws-cdk/core:stackRelativeExports": true, 20 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 21 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 22 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 23 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 24 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 25 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 26 | "@aws-cdk/core:checkSecretUsage": true, 27 | "@aws-cdk/aws-iam:minimizePolicies": true, 28 | "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, 29 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 30 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, 31 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, 32 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, 33 | "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, 34 | "@aws-cdk/core:enablePartitionLiterals": true, 35 | "@aws-cdk/core:target-partitions": [ 36 | "aws", 37 | "aws-cn" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/python/lambda/infrastructure/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda/infrastructure/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda/infrastructure/lambda_stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import Stack, CfnOutput 2 | import aws_cdk.aws_lambda as lambda_ 3 | from constructs import Construct 4 | from mrgrain.cdk_esbuild import ( 5 | TypeScriptCode, 6 | ) 7 | 8 | 9 | class LambdaStack(Stack): 10 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 11 | super().__init__(scope, construct_id, **kwargs) 12 | 13 | lambda_fn = lambda_.Function( 14 | self, 15 | "Lambda", 16 | runtime=lambda_.Runtime.NODEJS_18_X, 17 | handler="index.handler", 18 | code=TypeScriptCode("lambda-handler/index.ts"), 19 | ) 20 | 21 | CfnOutput(self, "LambdaArn", value=lambda_fn.function_arn) 22 | -------------------------------------------------------------------------------- /examples/python/lambda/lambda-handler/index.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | color: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites): Promise => { 8 | return ( 9 | `My favorite color is ${favorites.color}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /examples/python/lambda/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest==6.2.5 2 | black>=22.6.0 3 | -------------------------------------------------------------------------------- /examples/python/lambda/requirements.txt: -------------------------------------------------------------------------------- 1 | aws-cdk-lib==2.95.1 2 | constructs>=10.0.0,<11.0.0 3 | mrgrain.cdk-esbuild>=5.0.0rc0 -------------------------------------------------------------------------------- /examples/python/lambda/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /examples/python/lambda/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda/tests/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/examples/python/lambda/tests/unit/__init__.py -------------------------------------------------------------------------------- /examples/python/lambda/tests/unit/test_lambda_stack.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as core 2 | import aws_cdk.assertions as assertions 3 | 4 | from infrastructure.lambda_stack import LambdaStack 5 | 6 | 7 | def test_lambda_created(): 8 | app = core.App() 9 | stack = LambdaStack(app, "lambda") 10 | template = assertions.Template.from_stack(stack) 11 | 12 | template.resource_count_is("AWS::Lambda::Function", 1) 13 | -------------------------------------------------------------------------------- /examples/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # Override from top level 2 | !tsconfig.json -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | cdk.out 3 | node_modules 4 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/README.md: -------------------------------------------------------------------------------- 1 | # Using esbuild with plugins 2 | 3 | `@mrgrain/cdk-esbuild` allows users to provide a custom implementation of the _esbuild_ JavaScript API. 4 | This example demonstrates how to utilize the escape hatch to run `esbuild` with plugins. 5 | 6 | ## Demo 7 | 8 | Run `npm ci` to get setup. 9 | 10 | This example has loaded two plugins: 11 | 12 | - `esbuild-plugin-cache` which allows to use `https` in imports (checkout `lambda.ts`), and 13 | - `esbuild-plugin-time` which times the bundler executions. 14 | 15 | Next run `npm run synth` to see them in action. You should see something like this: 16 | 17 | ```console 18 | $ npm run synth 19 | Bundling asset Function/Lambda/TypeScriptCode/Stage... 20 | Build started 21 | Download https://cdn.skypack.dev/lodash.capitalize 22 | Download https://cdn.skypack.dev/-/lodash.capitalize@v4.2.1-Hv486RVr5xfN8llJbFuK/dist=es2019,mode=imports/optimized/lodash.capitalize.js 23 | Build ended: 233ms 24 | ``` 25 | 26 | Run the same command again, and notice how nothing is downloaded this time and how the build time improved. 27 | 28 | ```console 29 | $ npm run synth 30 | Bundling asset Function/Lambda/TypeScriptCode/Stage... 31 | Build started 32 | Build ended: 15ms 33 | ``` 34 | 35 | To clear the cache, run `npm run clean` and the next time you run the synth command, the package will be downloaded again. 36 | 37 | This integration also works with tests, run `npm test` to try it out! 38 | 39 | If you feel like it, inspect the bundled `lambda.js` file inside the asset output directory `cdk.out/asset.????`. You should notice that `lodash.capitalize` was successfully included in the bundle. 40 | 41 | ## How it's working 42 | 43 | AWS CDK [does not support asynchronous asset bundling](https://github.com/aws/aws-cdk/issues/8273). 44 | However esbuild's plugin API is async and we therefore need to use the escape hatch. 45 | 46 | In `app.ts` we pass a custom build provider to our `TypeScriptCode` object: 47 | 48 | ```ts 49 | new TypeScriptCode("./lambda.ts", { 50 | buildProvider: new BuildScriptProvider('build.mjs'), 51 | }); 52 | ``` 53 | 54 | The build provider is defined further up, and mostly consists of one method. 55 | In this method, we spawn an esbuild build-script as new node process. 56 | 57 | ```ts 58 | // Code simplified 59 | class BuildScriptProvider implements IBuildProvider { 60 | constructor(public readonly scriptPath: string) {} 61 | 62 | buildSync(options: ProviderBuildOptions): void { 63 | spawnSync('node', [this.scriptPath, JSON.stringify(options)], { 64 | stdio: "inherit", 65 | }); 66 | } 67 | } 68 | ``` 69 | 70 | This build script is very simple, but written so it can take the usual build options as a command line argument in form of stringified JSON. 71 | Have a look at `build.mjs`. 72 | 73 | First we recover the build options from the cli input: 74 | 75 | ```js 76 | const options = JSON.parse(process.argv.slice(2, 3)); 77 | ``` 78 | 79 | Then we call out the async build function. We pass in our regular options, but can also make any changes or additions we like. For example adding plugins: 80 | 81 | ```js 82 | await esbuild 83 | .build({ 84 | ...options, 85 | plugins: [time(), cache({ directory: ".cache" })], 86 | }) 87 | .catch(() => process.exit(1)); 88 | ``` 89 | 90 | Finally the above statement is `await`'ed. And since we are in a `.mjs` ECMA module file, the top-level await is supported out-of-the-box by recent Node.js versions. 91 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { App, CfnOutput, Stack, StackProps } from "aws-cdk-lib"; 3 | import { Function, Runtime } from "aws-cdk-lib/aws-lambda"; 4 | import { Construct } from "constructs"; 5 | import { IBuildProvider, ProviderBuildOptions, TypeScriptCode } from "@mrgrain/cdk-esbuild"; 6 | import { spawnSync } from "child_process"; 7 | 8 | class BuildScriptProvider implements IBuildProvider { 9 | constructor(public readonly scriptPath: string) { } 10 | 11 | buildSync(options: ProviderBuildOptions): void { 12 | const result = spawnSync('node', [this.scriptPath, JSON.stringify(options)], { 13 | stdio: ['inherit', 'inherit', 'pipe'], 14 | }); 15 | 16 | if (result.stderr.byteLength > 0) { 17 | throw result.stderr.toString(); 18 | } 19 | } 20 | } 21 | 22 | export class LambdaStack extends Stack { 23 | constructor(scope?: Construct, id?: string, props?: StackProps) { 24 | super(scope, id, props); 25 | 26 | const lambda = new Function(this, "Lambda", { 27 | runtime: Runtime.NODEJS_18_X, 28 | handler: "lambda.handler", 29 | code: new TypeScriptCode("./lambda.ts", { 30 | buildProvider: new BuildScriptProvider('build.mjs') 31 | }), 32 | }); 33 | 34 | new CfnOutput(this, "LambdaArn", { 35 | value: lambda.functionArn, 36 | }); 37 | } 38 | } 39 | 40 | const app = new App(); 41 | new LambdaStack(app, "Function"); 42 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/build.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import { cache } from "esbuild-plugin-cache"; 3 | import time from "esbuild-plugin-time"; 4 | 5 | const options = JSON.parse(process.argv.slice(2, 3)); 6 | 7 | await esbuild 8 | .build({ 9 | ...options, 10 | plugins: [time(), cache({ directory: ".cache" })], 11 | }) 12 | .catch((error) => { 13 | console.log(error); 14 | process.exit(1) 15 | }); 16 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts app.ts" 3 | } 4 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/lambda.test.ts: -------------------------------------------------------------------------------- 1 | import "@aws-cdk/assert/jest"; 2 | import { LambdaStack } from "./app"; 3 | 4 | test("Creates a Lambda Function", () => { 5 | // WHEN 6 | const stack = new LambdaStack(); 7 | 8 | // THEN 9 | expect(stack).toHaveResourceLike("AWS::Lambda::Function", { 10 | Handler: "lambda.handler", 11 | Runtime: "nodejs18.x", 12 | }); 13 | 14 | expect(stack).toHaveOutput({ 15 | outputName: "LambdaArn", 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/lambda.ts: -------------------------------------------------------------------------------- 1 | import capitalize from "https://cdn.skypack.dev/lodash.capitalize"; 2 | 3 | export const handler = async (input: { body: string }) => 4 | capitalize(input?.body); 5 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda", 3 | "private": "true", 4 | "version": "0.1.0", 5 | "scripts": { 6 | "clean": "rimraf .cache cdk.out", 7 | "synth": "cdk synth -q", 8 | "test": "jest" 9 | }, 10 | "dependencies": { 11 | "@mrgrain/cdk-esbuild": "5.0.0-rc.0", 12 | "aws-cdk-lib": "^2.95.1", 13 | "esbuild": "^0.19.2", 14 | "esbuild-plugin-cache": "^0.2.10", 15 | "esbuild-plugin-time": "^1.0.0", 16 | "rimraf": "^5.0.1" 17 | }, 18 | "devDependencies": { 19 | "@aws-cdk/assert": "^2.68.0", 20 | "@types/aws-lambda": "^8.10.119", 21 | "@types/jest": "^29.5.4", 22 | "@types/node": "^20.6.0", 23 | "aws-cdk": "^2.95.1", 24 | "jest": "^29.6.4", 25 | "ts-jest": "^29.1.1", 26 | "ts-node": "^10.9.1", 27 | "typescript": "~5.2.2" 28 | }, 29 | "jest": { 30 | "transform": { 31 | "^.+\\.tsx?$": "ts-jest" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/typescript/esbuild-with-plugins/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2020", 5 | }, 6 | "include": ["*.ts"], 7 | "exclude": ["cdk.out", "node_modules"] 8 | } 9 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | 10 | # project specific 11 | response.json 12 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/README.md: -------------------------------------------------------------------------------- 1 | # Lambda ESM Function 2 | 3 | Create a ESM Lambda function that can be invoked using the `aws-cli` or AWS Console. 4 | 5 | Inspired by [this AWS blog post](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/), ESM Lambda functions allow the use of top-level await. 6 | 7 | ## Getting started 8 | 9 | Run `npm ci` to get setup. Next, deploy the app with `npx cdk deploy`. If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `npx cdk bootstrap`) and sort out permissions. Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 10 | 11 | At the end of the deployment, the URL of your function will be displayed. To test your function, open the URL in a browser. 12 | 13 | You'll notice that the affirmation won't always change on refresh. 14 | Have a look at the Lambda code in `./src/index.mts`. 15 | This is because the API call is made outside the handler function, similar to how dynamic configuration might be retrieved. 16 | See this [blog post](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/) for details. 17 | 18 | Don't forget to tear everything down with `npx cdk destroy` - otherwise you will incur costs. 19 | 20 | ## Useful commands 21 | 22 | - `npm install` start with this 23 | - `npm test` perform the jest unit tests 24 | - `npm start` serve the website on localhost 25 | - `npx cdk bootstrap` setup your AWS environment 26 | - `npx cdk deploy` deploy this stack to your default AWS account/region 27 | - `npx cdk destroy` destroy this stack to ensure you don't incur any costs 28 | - `npx cdk diff` compare deployed stack with current state 29 | - `npx cdk synth` emits the synthesized CloudFormation template 30 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts infrastructure/app.ts" 3 | } 4 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/infrastructure/app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from "aws-cdk-lib"; 3 | import { LambdaStack } from "./stack"; 4 | 5 | const app = new cdk.App(); 6 | new LambdaStack(app, "EsmFunction"); 7 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/infrastructure/stack.ts: -------------------------------------------------------------------------------- 1 | import { TypeScriptCode } from "@mrgrain/cdk-esbuild"; 2 | import { CfnOutput, Stack, StackProps } from "aws-cdk-lib"; 3 | import { Function, FunctionUrlAuthType, Runtime } from "aws-cdk-lib/aws-lambda"; 4 | import { Construct } from "constructs"; 5 | 6 | export class LambdaStack extends Stack { 7 | constructor(scope?: Construct, id?: string, props?: StackProps) { 8 | super(scope, id, props); 9 | 10 | const lambda = new Function(this, "Lambda", { 11 | runtime: Runtime.NODEJS_18_X, 12 | handler: "index.handler", 13 | code: new TypeScriptCode("./src/index.mts", { 14 | buildOptions: { 15 | format: "esm", 16 | outfile: "index.mjs", 17 | }, 18 | }), 19 | }); 20 | 21 | const url = lambda.addFunctionUrl({ 22 | authType: FunctionUrlAuthType.NONE, 23 | }); 24 | 25 | new CfnOutput(this, "LambdaUrl", { 26 | value: url.url, 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "colour": "green", 3 | "food": "pizza", 4 | "season": "winter" 5 | } 6 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/test'], 3 | testMatch: ['**/*.test.ts'], 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda-esm", 3 | "private": "true", 4 | "version": "0.1.0", 5 | "scripts": { 6 | "test": "jest", 7 | "cdk": "cdk" 8 | }, 9 | "dependencies": { 10 | "@mrgrain/cdk-esbuild": "5.0.0-rc.0", 11 | "aws-cdk-lib": "^2.194.0", 12 | "node-fetch": "^3.3.2" 13 | }, 14 | "devDependencies": { 15 | "@aws-cdk/assert": "^2.68.0", 16 | "@types/aws-lambda": "^8.10.119", 17 | "@types/jest": "^29.5.4", 18 | "@types/node": "^20.6.0", 19 | "aws-cdk": "^2.95.1", 20 | "jest": "^29.6.4", 21 | "ts-jest": "^29.1.1", 22 | "ts-node": "^10.9.1", 23 | "typescript": "~5.2.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/src/index.mts: -------------------------------------------------------------------------------- 1 | import { Handler } from "aws-lambda"; 2 | import fetch from "node-fetch"; 3 | 4 | interface Affirmation { 5 | affirmation: string; 6 | } 7 | 8 | const response = await fetch("https://www.affirmations.dev"); 9 | const data = (await response.json()) as Affirmation; 10 | 11 | export const handler: Handler = async () => { 12 | return data.affirmation; 13 | }; 14 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/test/lambda-esm.test.ts: -------------------------------------------------------------------------------- 1 | import "@aws-cdk/assert/jest"; 2 | import { LambdaStack } from "../infrastructure/stack"; 3 | 4 | test("Creates a Lambda Function", () => { 5 | // WHEN 6 | const stack = new LambdaStack(); 7 | 8 | // THEN 9 | expect(stack).toHaveResourceLike("AWS::Lambda::Function", { 10 | Handler: "index.handler", 11 | Runtime: "nodejs18.x", 12 | }); 13 | 14 | expect(stack).toHaveOutput({ 15 | outputName: "LambdaUrl", 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/typescript/lambda-esm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Settings for Node.js >= 12.9.0 4 | "lib": ["es2020"], 5 | "module": "commonjs", 6 | "target": "es2019", 7 | 8 | // Support some older packages 9 | "esModuleInterop": true, 10 | 11 | // Enable super strict setting 12 | "strict": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "resolveJsonModule": true, 18 | 19 | // Function code never has to be compiled outside zeit/ncc and ts-jest 20 | "rootDir": ".", 21 | "noEmit": true 22 | }, 23 | "include": ["**/*.ts"], 24 | "exclude": ["cdk.out", "node_modules"] 25 | } 26 | -------------------------------------------------------------------------------- /examples/typescript/lambda/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | 10 | # project specific 11 | response.json 12 | -------------------------------------------------------------------------------- /examples/typescript/lambda/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /examples/typescript/lambda/README.md: -------------------------------------------------------------------------------- 1 | # Lambda Function 2 | 3 | Create a basic Lambda function that can be invoked using the `aws-cli` or AWS Console. 4 | 5 | ## Getting started 6 | 7 | Run `npm ci` to get setup. 8 | 9 | Have a look at the Lambda code in `./src/index.ts`. Maybe change the returned text to make it more personal. Also have a look at the values in `input.json`, we will use this later. 10 | 11 | Once you are happy, deploy your app with `npx cdk deploy`. If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `npx cdk bootstrap`) and sort out permissions. Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 12 | 13 | As part of the deployment, the ARN of your function will be displayed. We need this for the next step. 14 | 15 | To test your function, you could either go into the AWS Console and paste the contents of `input.json` into the test feature. 16 | 17 | Alternatively, let's use the aws-cli to invoke our function from the command line: 18 | 19 | ```console 20 | aws lambda invoke --function-name "" --payload fileb://input.json response.json 21 | ``` 22 | 23 | You will get a response containing the status of our request. Now check our `response.json` for the results: 24 | 25 | ```console 26 | cat response.json 27 | ``` 28 | 29 | Don't forget to tear everything down with `npx cdk destroy` - otherwise you will incur costs. 30 | 31 | ## Useful commands 32 | 33 | - `npm install` start with this 34 | - `npm test` perform the jest unit tests 35 | - `npm start` serve the website on localhost 36 | - `npx cdk bootstrap` setup your AWS environment 37 | - `npx cdk deploy` deploy this stack to your default AWS account/region 38 | - `npx cdk destroy` destroy this stack to ensure you don't incur any costs 39 | - `npx cdk diff` compare deployed stack with current state 40 | - `npx cdk synth` emits the synthesized CloudFormation template 41 | -------------------------------------------------------------------------------- /examples/typescript/lambda/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts infrastructure/app.ts" 3 | } 4 | -------------------------------------------------------------------------------- /examples/typescript/lambda/infrastructure/app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from "aws-cdk-lib"; 3 | import { LambdaStack } from "./stack"; 4 | 5 | const app = new cdk.App(); 6 | new LambdaStack(app, "Function"); 7 | -------------------------------------------------------------------------------- /examples/typescript/lambda/infrastructure/stack.ts: -------------------------------------------------------------------------------- 1 | import { TypeScriptCode } from "@mrgrain/cdk-esbuild"; 2 | import { CfnOutput, Stack, StackProps } from "aws-cdk-lib"; 3 | import { Function, Runtime } from "aws-cdk-lib/aws-lambda"; 4 | import { Construct } from "constructs"; 5 | 6 | export class LambdaStack extends Stack { 7 | constructor(scope?: Construct, id?: string, props?: StackProps) { 8 | super(scope, id, props); 9 | 10 | const lambda = new Function(this, "Lambda", { 11 | runtime: Runtime.NODEJS_18_X, 12 | handler: "index.handler", 13 | code: new TypeScriptCode("./src/index.ts"), 14 | }); 15 | 16 | new CfnOutput(this, "LambdaArn", { 17 | value: lambda.functionArn, 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/typescript/lambda/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "colour": "green", 3 | "food": "pizza", 4 | "season": "winter" 5 | } 6 | -------------------------------------------------------------------------------- /examples/typescript/lambda/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/test'], 3 | testMatch: ['**/*.test.ts'], 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /examples/typescript/lambda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda", 3 | "private": "true", 4 | "version": "0.1.0", 5 | "scripts": { 6 | "test": "jest", 7 | "cdk": "cdk" 8 | }, 9 | "dependencies": { 10 | "@mrgrain/cdk-esbuild": "5.0.0-rc.0", 11 | "aws-cdk-lib": "^2.194.0" 12 | }, 13 | "devDependencies": { 14 | "@aws-cdk/assert": "^2.68.0", 15 | "@types/aws-lambda": "^8.10.119", 16 | "@types/jest": "^29.5.4", 17 | "@types/node": "^20.6.0", 18 | "aws-cdk": "^2.95.1", 19 | "jest": "^29.6.4", 20 | "ts-jest": "^29.1.1", 21 | "ts-node": "^10.9.1", 22 | "typescript": "~5.2.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/typescript/lambda/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Handler } from "aws-lambda"; 2 | 3 | interface Favorites { 4 | colour: string; 5 | food: string; 6 | season: string; 7 | } 8 | 9 | export const handler: Handler = async (favorites) => { 10 | return ( 11 | `My favorite colour is ${favorites.colour}, ` + 12 | `I always like to eat some ${favorites.food} and ` + 13 | `${favorites.season} is the best time of the year.` 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /examples/typescript/lambda/test/lambda.test.ts: -------------------------------------------------------------------------------- 1 | import "@aws-cdk/assert/jest"; 2 | import { LambdaStack } from "../infrastructure/stack"; 3 | 4 | test("Creates a Lambda Function", () => { 5 | // WHEN 6 | const stack = new LambdaStack(); 7 | 8 | // THEN 9 | expect(stack).toHaveResourceLike("AWS::Lambda::Function", { 10 | Handler: "index.handler", 11 | Runtime: "nodejs18.x", 12 | }); 13 | 14 | expect(stack).toHaveOutput({ 15 | outputName: "LambdaArn", 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/typescript/lambda/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Settings for Node.js >= 12.9.0 4 | "lib": ["es2020"], 5 | "module": "commonjs", 6 | "target": "es2019", 7 | 8 | // Support some older packages 9 | "esModuleInterop": true, 10 | 11 | // Enable super strict setting 12 | "strict": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "resolveJsonModule": true, 18 | 19 | // Function code never has to be compiled outside zeit/ncc and ts-jest 20 | "rootDir": ".", 21 | "noEmit": true 22 | }, 23 | "include": ["**/*.ts"], 24 | "exclude": ["cdk.out", "node_modules"] 25 | } 26 | -------------------------------------------------------------------------------- /examples/typescript/website/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | -------------------------------------------------------------------------------- /examples/typescript/website/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /examples/typescript/website/README.md: -------------------------------------------------------------------------------- 1 | # Static Website with React 2 | 3 | Make a static website with React and deploy it with a single command using cdk. 4 | 5 | ## Getting started 6 | 7 | Run `npm ci` to get setup. 8 | 9 | Have a look at the React code in `./src`. Maybe change the content in `App.tsx`. 10 | 11 | To view your React app locally, run `npm start` and open the printed URL in a browser. 12 | 13 | Once you are happy, deploy your app with `npx cdk deploy`. If you haven't used the CDK in your account before, you will have bootstrap the account first (typically by running `npx cdk bootstrap`) and sort out permissions. Please refer to [the official AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to get started. 14 | 15 | As part of the deployment, a URL will be displayed. Open it to view your deployed website! 16 | 17 | ## Clean up 18 | 19 | Don't forget to tear everything down with `npx cdk destroy` - otherwise you will incur costs. 20 | 21 | Additionally, Amazon CloudWatch Synthetics creates a number of dependent resources that are not automatically removed when you destroy the stack. These are documented in [this AWS blog post](https://aws.amazon.com/blogs/mt/delete-amazon-cloudwatch-synthetics-dependent-resources-when-you-delete-a-cloudformation-stack/). 22 | 23 | ## Useful commands 24 | 25 | - `npm install` start with this 26 | - `npm test` perform the jest unit tests 27 | - `npm start` serve the website on localhost 28 | - `npx cdk bootstrap` setup your AWS environment 29 | - `npx cdk deploy` deploy this stack to your default AWS account/region 30 | - `npx cdk destroy` destroy this stack to ensure you don't incur any costs 31 | - `npx cdk diff` compare deployed stack with current state 32 | - `npx cdk synth` emits the synthesized CloudFormation template 33 | -------------------------------------------------------------------------------- /examples/typescript/website/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts infrastructure/app.ts" 3 | } 4 | -------------------------------------------------------------------------------- /examples/typescript/website/infrastructure/app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from "aws-cdk-lib"; 3 | import { WebsiteStack } from "./stack"; 4 | 5 | const app = new cdk.App(); 6 | new WebsiteStack(app, "Website"); 7 | -------------------------------------------------------------------------------- /examples/typescript/website/infrastructure/stack.ts: -------------------------------------------------------------------------------- 1 | import { Canary, Cleanup, Runtime, Schedule, Test } from "aws-cdk-lib/aws-synthetics"; 2 | import { TypeScriptCode, TypeScriptSource } from "@mrgrain/cdk-esbuild"; 3 | import { BlockPublicAccess, Bucket, ObjectOwnership } from "aws-cdk-lib/aws-s3"; 4 | import { BucketDeployment } from "aws-cdk-lib/aws-s3-deployment"; 5 | import { Alarm, ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch"; 6 | import { 7 | CfnOutput, 8 | Duration, 9 | RemovalPolicy, 10 | Stack, 11 | StackProps, 12 | } from "aws-cdk-lib"; 13 | import { Construct } from "constructs"; 14 | 15 | export class WebsiteStack extends Stack { 16 | constructor(scope?: Construct, id?: string, props?: StackProps) { 17 | super(scope, id, props); 18 | 19 | const websiteBundle = new TypeScriptSource("./src/index.tsx", { 20 | copyDir: "static", 21 | buildOptions: { 22 | outdir: "js", 23 | }, 24 | }); 25 | 26 | const websiteBucket = new Bucket(this, "WebsiteBucket", { 27 | autoDeleteObjects: true, 28 | publicReadAccess: true, 29 | blockPublicAccess: new BlockPublicAccess({ 30 | blockPublicAcls: false, 31 | blockPublicPolicy: false, 32 | ignorePublicAcls: false, 33 | restrictPublicBuckets: false, 34 | }), 35 | objectOwnership: ObjectOwnership.OBJECT_WRITER, 36 | removalPolicy: RemovalPolicy.DESTROY, 37 | websiteIndexDocument: "index.html", 38 | }); 39 | 40 | const website = new BucketDeployment(this, "DeployWebsite", { 41 | destinationBucket: websiteBucket, 42 | sources: [websiteBundle], 43 | }); 44 | 45 | new CfnOutput(this, "WebsiteUrl", { 46 | value: websiteBucket.bucketWebsiteUrl, 47 | }); 48 | 49 | const canary = new Canary(this, "Monitoring", { 50 | schedule: Schedule.rate(Duration.hours(1)), 51 | runtime: Runtime.SYNTHETICS_NODEJS_PUPPETEER_7_0, 52 | cleanup: Cleanup.LAMBDA, 53 | test: Test.custom({ 54 | code: new TypeScriptCode("./src/canary.ts", { 55 | buildOptions: { 56 | outdir: "nodejs/node_modules", 57 | external: ["Synthetics"], 58 | }, 59 | }), 60 | handler: "canary.handler", 61 | }), 62 | environmentVariables: { 63 | MONITORING_URL: websiteBucket.bucketWebsiteUrl, 64 | TIMEOUT: "3000", 65 | }, 66 | artifactsBucketLocation: { 67 | bucket: new Bucket(this, "ArtifactsBucket", { 68 | autoDeleteObjects: true, 69 | removalPolicy: RemovalPolicy.DESTROY, 70 | }), 71 | }, 72 | }); 73 | canary.node.addDependency(website); 74 | 75 | new Alarm(this, "CanaryAlarm", { 76 | metric: canary.metricSuccessPercent(), 77 | evaluationPeriods: 2, 78 | threshold: 90, 79 | comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD, 80 | }); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/typescript/website/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/test'], 3 | testMatch: ['**/*.test.ts'], 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /examples/typescript/website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "private": "true", 4 | "version": "0.1.0", 5 | "scripts": { 6 | "start": "esbuild ./src/index.tsx --bundle --servedir=static --outdir=static/js", 7 | "test": "jest", 8 | "cdk": "cdk" 9 | }, 10 | "dependencies": { 11 | "@mrgrain/cdk-esbuild": "^5.0.0", 12 | "aws-cdk-lib": "^2.178.1", 13 | "esbuild": "^0.20.2", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@types/aws-synthetics-puppeteer": "^3.1.5", 19 | "@types/jest": "^29.5.4", 20 | "@types/node": "^20.6.0", 21 | "@types/react": "^18.2.21", 22 | "@types/react-dom": "^18.2.7", 23 | "aws-cdk": "^2.139.0", 24 | "jest": "^29.6.4", 25 | "ts-jest": "^29.1.1", 26 | "ts-node": "^10.9.1", 27 | "typescript": "~5.4.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/typescript/website/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const App = (): JSX.Element => ( 4 |
5 |

6 | Static Website with React 7 |
8 | Made easy with @mrgrain/cdk-esbuild 9 |
10 | Uptime monitored with Amazon CloudWatch Synthetics 11 |

12 |
13 | ); 14 | 15 | export default App; 16 | -------------------------------------------------------------------------------- /examples/typescript/website/src/canary.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import synthetics from "Synthetics"; 3 | 4 | export const handler = async () => { 5 | assert(process.env.MONITORING_URL); 6 | assert(process.env.TIMEOUT); 7 | 8 | const { MONITORING_URL, TIMEOUT } = process.env; 9 | 10 | const page = await synthetics.getPage(); 11 | await page.goto(MONITORING_URL, { timeout: parseInt(TIMEOUT) }); 12 | await page.screenshot({ path: "/tmp/screenshot.png" }); 13 | 14 | return; 15 | }; 16 | -------------------------------------------------------------------------------- /examples/typescript/website/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | 5 | ReactDOM.render(, document.getElementById("app")); 6 | -------------------------------------------------------------------------------- /examples/typescript/website/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/typescript/website/test/website.test.ts: -------------------------------------------------------------------------------- 1 | import { Template } from "aws-cdk-lib/assertions"; 2 | import { WebsiteStack } from "../infrastructure/stack"; 3 | 4 | test("Creates a Website bucket", () => { 5 | // WHEN 6 | const stack = new WebsiteStack(); 7 | const template = Template.fromStack(stack); 8 | 9 | // THEN 10 | template.hasResourceProperties("AWS::S3::Bucket", { 11 | WebsiteConfiguration: { 12 | IndexDocument: "index.html", 13 | }, 14 | }); 15 | 16 | template.hasOutput('WebsiteUrl', {}); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/typescript/website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "module": "commonjs", 5 | "lib": ["dom", "es2019"], 6 | "jsx": "react", 7 | "declaration": true, 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "strictNullChecks": true, 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "esModuleInterop": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": ["./node_modules/@types"] 23 | }, 24 | "exclude": ["cdk.out"] 25 | } 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module cdkesbuild_integ_tests 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.6 6 | 7 | require github.com/aws/aws-cdk-go/awscdk/v2 v2.84.0 8 | 9 | require github.com/aws/aws-cdk-go/awscdkintegtestsalpha/v2 v2.84.0-alpha.0 10 | 11 | require ( 12 | github.com/aws/constructs-go/constructs/v10 v10.2.26 13 | github.com/aws/jsii-runtime-go v1.112.0 14 | github.com/mrgrain/cdk-esbuild-go/cdkesbuild v0.0.0-unpublished 15 | ) 16 | 17 | require ( 18 | github.com/Masterminds/semver/v3 v3.3.1 // indirect 19 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.210 // indirect 20 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3 // indirect 21 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv5/v2 v2.0.166 // indirect 22 | github.com/fatih/color v1.18.0 // indirect 23 | github.com/mattn/go-colorable v0.1.13 // indirect 24 | github.com/mattn/go-isatty v0.0.20 // indirect 25 | github.com/yuin/goldmark v1.4.13 // indirect 26 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect 27 | golang.org/x/mod v0.24.0 // indirect 28 | golang.org/x/sync v0.14.0 // indirect 29 | golang.org/x/sys v0.33.0 // indirect 30 | golang.org/x/tools v0.33.0 // indirect 31 | ) 32 | 33 | replace github.com/mrgrain/cdk-esbuild-go/cdkesbuild v0.0.0-unpublished => ./dist/go/cdkesbuild 34 | 35 | replace github.com/mrgrain/cdk-esbuild-go/cdkesbuild/jsii v0.0.0-unpublished => ./dist/go/cdkesbuild/jsii 36 | 37 | replace github.com/mrgrain/cdk-esbuild-go/cdkesbuild/internal v0.0.0-unpublished => ./dist/go/cdkesbuild/internal 38 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= 2 | github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= 3 | github.com/aws/aws-cdk-go/awscdk/v2 v2.84.0 h1:jKPhzgb4G+bqHfZj9pPdFtbJQ+5IyOGgOukC7qHZ/LI= 4 | github.com/aws/aws-cdk-go/awscdk/v2 v2.84.0/go.mod h1:Jyy27U909IuC6bKytIkrHSt0/Hlp3Aq2uVx8L9H3UKg= 5 | github.com/aws/aws-cdk-go/awscdkintegtestsalpha/v2 v2.84.0-alpha.0 h1:XFy+vz0VPbrShC2fF3GrDUungS80tXA6O43vyufQStw= 6 | github.com/aws/aws-cdk-go/awscdkintegtestsalpha/v2 v2.84.0-alpha.0/go.mod h1:vklLYbS3JZ5RXSJz55RPAfTlL+eZZIrpdakFogmmCZM= 7 | github.com/aws/constructs-go/constructs/v10 v10.2.26 h1:mAZE2LDalT/1ySrQZEl54hzghsySWosLxWYo+5b+/3U= 8 | github.com/aws/constructs-go/constructs/v10 v10.2.26/go.mod h1:auRY1XPWnLxvn5fR3sZ9SsYOxH/BCQC697s4Yw8B7tk= 9 | github.com/aws/jsii-runtime-go v1.112.0 h1:7jusWZUgSTuSPLa2ZRv+siGuyoFSzFNk/TaHqlcFe6Y= 10 | github.com/aws/jsii-runtime-go v1.112.0/go.mod h1:jiAbLN2Hz+7At3C59LsQyv8gK3HvfNYF2YFPkWLHll8= 11 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.210 h1:nHGXTnKpckh9xSHIkQSWCsACrhRw54DnvPQikHlQxrw= 12 | github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.210/go.mod h1:zydxApP2CyfXc3jMpJdyb1ERPNVXaCH/LJTKfWfzUBA= 13 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3 h1:u63i5K09xASBNGEM0hpD2z0JwO+iNLVzG74VG85OjDo= 14 | github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3/go.mod h1:0xP6iiSIKPKsShb6T2kadnTq61wL+kwmHTHnEjkFZFI= 15 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv5/v2 v2.0.166 h1:U5yXUyaDEDYyMkXys8T8p+xXnNtrpj8meSjyzMvi87g= 16 | github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv5/v2 v2.0.166/go.mod h1:gRo8jRhn3XwNiy2v47yITrKFM/OPK1Mv9U9fKq5d6lI= 17 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 18 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 19 | github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= 20 | github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= 21 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 22 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 23 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 24 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 25 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 26 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 27 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 28 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 29 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 30 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 31 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 32 | github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= 33 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 34 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 35 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 36 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= 37 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 38 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 39 | golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= 40 | golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 41 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 42 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 43 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 44 | golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= 45 | golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 46 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 47 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 48 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 49 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 50 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= 51 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 52 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 53 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 54 | golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= 55 | golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 56 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 57 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 58 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 59 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgrain/cdk-esbuild/04d4ca69245dfccfe88c1420c239d29570e92527/images/logo.png -------------------------------------------------------------------------------- /images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /images/wordmark-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 20 | 22 | 23 | cdk-esbuild 24 | -------------------------------------------------------------------------------- /images/wordmark-dynamic.svg: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 32 | 34 | 35 | cdk-esbuild 36 | -------------------------------------------------------------------------------- /images/wordmark-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 20 | 22 | 23 | cdk-esbuild 24 | -------------------------------------------------------------------------------- /images/wordmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 20 | 22 | 23 | cdk-esbuild 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mrgrain/cdk-esbuild", 3 | "description": "CDK constructs for esbuild, an extremely fast JavaScript bundler", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/mrgrain/cdk-esbuild" 7 | }, 8 | "scripts": { 9 | "build": "npx projen build", 10 | "bump": "npx projen bump", 11 | "clobber": "npx projen clobber", 12 | "compat": "npx projen compat", 13 | "compile": "npx projen compile", 14 | "default": "npx projen default", 15 | "docgen": "npx projen docgen", 16 | "eject": "npx projen eject", 17 | "eslint": "npx projen eslint", 18 | "integ:go": "npx projen integ:go", 19 | "integ:python": "npx projen integ:python", 20 | "lint:ts": "npx projen lint:ts", 21 | "package": "npx projen package", 22 | "package-all": "npx projen package-all", 23 | "package:dotnet": "npx projen package:dotnet", 24 | "package:go": "npx projen package:go", 25 | "package:java": "npx projen package:java", 26 | "package:js": "npx projen package:js", 27 | "package:python": "npx projen package:python", 28 | "post-compile": "npx projen post-compile", 29 | "post-upgrade": "npx projen post-upgrade", 30 | "pre-compile": "npx projen pre-compile", 31 | "prepare:readme": "npx projen prepare:readme", 32 | "publish:git:v5": "npx projen publish:git:v5", 33 | "release:v5": "npx projen release:v5", 34 | "rosetta": "npx projen rosetta", 35 | "test": "npx projen test", 36 | "test:watch": "npx projen test:watch", 37 | "unbump": "npx projen unbump", 38 | "upgrade": "npx projen upgrade", 39 | "watch": "npx projen watch", 40 | "projen": "npx projen" 41 | }, 42 | "author": { 43 | "name": "Moritz Kornher", 44 | "email": "mail@moritzkornher.de", 45 | "url": "https://moritzkornher.de", 46 | "organization": false 47 | }, 48 | "devDependencies": { 49 | "@aws-cdk/aws-synthetics-alpha": "2.51.0-alpha.0", 50 | "@aws-cdk/integ-runner": "latest", 51 | "@stylistic/eslint-plugin": "^2", 52 | "@types/eslint": "^7.29.0", 53 | "@types/jest": "^29", 54 | "@types/node": "ts5.8", 55 | "@typescript-eslint/eslint-plugin": "^8", 56 | "@typescript-eslint/parser": "^8", 57 | "aws-cdk-lib": "2.51.0", 58 | "commit-and-tag-version": "^12", 59 | "constructs": "10.0.5", 60 | "esbuild": "^0.25.0", 61 | "eslint": "^9", 62 | "eslint-import-resolver-typescript": "^2.7.1", 63 | "eslint-plugin-import": "^2.31.0", 64 | "jest": "^29", 65 | "jest-junit": "^16", 66 | "jest-mock": "^27.5.1", 67 | "jsii": "5.8.x", 68 | "jsii-diff": "^1.112.0", 69 | "jsii-docgen": "^10.5.0", 70 | "jsii-pacmak": "^1.112.0", 71 | "jsii-rosetta": "5.8.x", 72 | "projen": "^0.92.9", 73 | "ts-jest": "^29", 74 | "ts-morph": "^17.0.1", 75 | "ts-node": "^10", 76 | "typescript": "5.8.x" 77 | }, 78 | "peerDependencies": { 79 | "aws-cdk-lib": "^2.51.0", 80 | "constructs": "^10.0.5" 81 | }, 82 | "keywords": [ 83 | "aws-cdk", 84 | "bundler", 85 | "cdk", 86 | "constructs", 87 | "esbuild", 88 | "lambda", 89 | "s3", 90 | "s3-deployment", 91 | "static website" 92 | ], 93 | "main": "lib/index.js", 94 | "license": "MIT", 95 | "homepage": "https://github.com/mrgrain/cdk-esbuild", 96 | "version": "0.0.0", 97 | "jest": { 98 | "coverageProvider": "v8", 99 | "testPathIgnorePatterns": [ 100 | "/node_modules/", 101 | "/examples/" 102 | ], 103 | "coveragePathIgnorePatterns": [ 104 | "/node_modules/", 105 | "/examples/" 106 | ], 107 | "testMatch": [ 108 | "/@(src|test)/**/*(*.)@(spec|test).ts?(x)", 109 | "/@(src|test)/**/__tests__/**/*.ts?(x)", 110 | "/@(projenrc)/**/*(*.)@(spec|test).ts?(x)", 111 | "/@(projenrc)/**/__tests__/**/*.ts?(x)" 112 | ], 113 | "clearMocks": true, 114 | "collectCoverage": true, 115 | "coverageReporters": [ 116 | "json", 117 | "lcov", 118 | "clover", 119 | "cobertura", 120 | "text" 121 | ], 122 | "coverageDirectory": "coverage", 123 | "watchPathIgnorePatterns": [ 124 | "/node_modules/" 125 | ], 126 | "reporters": [ 127 | "default", 128 | [ 129 | "jest-junit", 130 | { 131 | "outputDirectory": "test-reports" 132 | } 133 | ] 134 | ], 135 | "transform": { 136 | "^.+\\.[t]sx?$": [ 137 | "ts-jest", 138 | { 139 | "tsconfig": "tsconfig.dev.json" 140 | } 141 | ] 142 | } 143 | }, 144 | "types": "lib/index.d.ts", 145 | "stability": "stable", 146 | "jsii": { 147 | "outdir": "dist", 148 | "targets": { 149 | "java": { 150 | "package": "io.github.mrgrain.cdkesbuild", 151 | "maven": { 152 | "groupId": "io.github.mrgrain", 153 | "artifactId": "cdkesbuild" 154 | } 155 | }, 156 | "python": { 157 | "distName": "mrgrain.cdk-esbuild", 158 | "module": "mrgrain.cdk_esbuild" 159 | }, 160 | "dotnet": { 161 | "namespace": "Mrgrain.CdkEsbuild", 162 | "packageId": "Mrgrain.CdkEsbuild", 163 | "iconUrl": "https://raw.githubusercontent.com/mrgrain/cdk-esbuild/main/images/logo.png" 164 | }, 165 | "go": { 166 | "moduleName": "github.com/mrgrain/cdk-esbuild-go", 167 | "packageName": "cdkesbuild" 168 | } 169 | }, 170 | "tsc": { 171 | "outDir": "lib", 172 | "rootDir": "src" 173 | } 174 | }, 175 | "awscdkio": { 176 | "twitter": "@mrgrain" 177 | }, 178 | "jsiiRosetta": { 179 | "strict": true, 180 | "exampleDependencies": { 181 | "aws-cdk-lib": "2.139.0", 182 | "@mrgrain/cdk-esbuild": "^5", 183 | "constructs": "^10", 184 | "@types/node": "^18" 185 | } 186 | }, 187 | "optionalDependencies": { 188 | "esbuild": "^0.25.0" 189 | }, 190 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 191 | } 192 | -------------------------------------------------------------------------------- /projenrc/Pipenv.ts: -------------------------------------------------------------------------------- 1 | import { Project, TextFile } from 'projen'; 2 | 3 | export interface PipenvOptions { 4 | /** 5 | * Use a different path and name for the Pipfile 6 | * 7 | * @default "Pipfile" 8 | */ 9 | pipfilePath?: string; 10 | 11 | /** 12 | * The Python version requirement 13 | * 14 | * @default "3" 15 | */ 16 | pythonVersion?: string; 17 | } 18 | 19 | interface Package { 20 | name: string; 21 | constraint?: string; 22 | } 23 | 24 | interface Source { 25 | url: string; 26 | name: string; 27 | verifySsl?: boolean; 28 | } 29 | 30 | export interface SourceOptions { 31 | verifySsl?: boolean; 32 | } 33 | 34 | export class Pipenv extends TextFile { 35 | public readonly sources: { 36 | [name: string]: Source; 37 | } = {}; 38 | 39 | public readonly packages: { 40 | [name: string]: Package; 41 | } = {}; 42 | 43 | public readonly devPackages: { 44 | [name: string]: Package; 45 | } = {}; 46 | 47 | public readonly requires: { 48 | [requirement: string]: string; 49 | } = {}; 50 | 51 | public constructor(project: Project, options: PipenvOptions = {}) { 52 | super(project, options.pipfilePath ?? 'Pipfile', { 53 | marker: true, 54 | committed: true, 55 | readonly: true, 56 | }); 57 | 58 | this.addSource('pypi', 'https://pypi.org/simple', { 59 | verifySsl: true, 60 | }); 61 | 62 | this.requires.python_version = options.pythonVersion ?? '3'; 63 | } 64 | 65 | public addSource(name: string, url: string, options: SourceOptions = {}) { 66 | this.sources[name] = { name, url, ...options }; 67 | } 68 | 69 | public addPackage(pkg: string) { 70 | const [name, constraint] = pkg.split('@'); 71 | const constraintNeedsQuotes = !constraint.startsWith('{') && !constraint.startsWith('"'); 72 | this.packages[name] = { name, constraint: constraintNeedsQuotes ? `"${constraint}"`: constraint }; 73 | } 74 | 75 | protected synthesizeContent(): string { 76 | const sources = Object.values(this.sources).map(source => [ 77 | '[[source]]', 78 | `url = "${source.url}"`, 79 | source.verifySsl ? `verify_ssl = ${source.verifySsl ? 'true' : 'false'}` : undefined, 80 | `name = "${source.name}"`, 81 | ].join('\n')); 82 | 83 | const packages = [ 84 | '[packages]', 85 | ...Object.values(this.packages) 86 | .map(renderPackage), 87 | ].join('\n'); 88 | 89 | const devPackages = [ 90 | '[dev-packages]', 91 | ...Object.values(this.devPackages) 92 | .map(renderPackage), 93 | ].join('\n'); 94 | 95 | const requires = [ 96 | '[requires]', 97 | ...Object.entries(this.requires) 98 | .map(([requirement, value]) => `${requirement} = "${value}"`), 99 | ].join('\n'); 100 | 101 | return [ 102 | ...(this.marker ? [`# ${this.marker}`] : []), 103 | ...sources, 104 | packages, 105 | devPackages, 106 | requires, 107 | ].join('\n\n') + '\n'; 108 | } 109 | } 110 | 111 | function renderPackage(pkg: Package): string { 112 | return `"${pkg.name}" = ${pkg.constraint}`; 113 | } 114 | -------------------------------------------------------------------------------- /projenrc/TypeScriptSourceFile.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs'; 2 | import { Component, FileBase, FileBaseOptions, javascript, Project as ProjenProject, Task } from 'projen'; 3 | import { execCapture } from 'projen/lib/util'; 4 | import { Project, SourceFile } from 'ts-morph'; 5 | 6 | interface TypeScriptSourceFileOptions extends Omit { 7 | source: string; 8 | transformer?: (sourcefile: SourceFile) => void; 9 | format?: boolean; 10 | marker?: boolean; 11 | } 12 | 13 | export class TypeScriptSourceFile extends FileBase { 14 | public readonly options: TypeScriptSourceFileOptions; 15 | private readonly task: Task; 16 | 17 | constructor(project: ProjenProject, filePath: string, options: TypeScriptSourceFileOptions) { 18 | super(project, filePath, { ...options, readonly: false }); 19 | 20 | this.options = { 21 | format: true, 22 | marker: true, 23 | ...options, 24 | }; 25 | 26 | this.task = TypeScriptSourceFileLinter.singleton(project).task; 27 | 28 | const eslint = javascript.Eslint.of(project); 29 | eslint?.addOverride({ 30 | files: [filePath], 31 | rules: { 32 | '@stylistic/max-len': 'off', 33 | }, 34 | }); 35 | } 36 | 37 | protected synthesizeContent(): string { 38 | const tsProject = new Project({ 39 | tsConfigFilePath: 'tsconfig.json', 40 | skipAddingFilesFromTsConfig: true, 41 | }); 42 | 43 | const sourceFile = tsProject.addSourceFileAtPath(this.options.source); 44 | 45 | if (this.options.transformer) { 46 | this.options.transformer(sourceFile); 47 | } 48 | 49 | return [ 50 | ...(this.options.marker ? [`// ${this.marker}`] : []), 51 | '', 52 | sourceFile.getFullText(), 53 | ].join('\n'); 54 | } 55 | 56 | public postSynthesize() { 57 | super.postSynthesize(); 58 | 59 | const outdir = this.project.outdir; 60 | try { 61 | execCapture(this.project.runTaskCommand(this.task) + ' ' + this.absolutePath, { cwd: outdir }); 62 | } catch (error: any) { 63 | const msg = error.stdout?.toString() ?? error.message; 64 | throw Error(msg); 65 | } 66 | } 67 | } 68 | 69 | export class TypeScriptSourceFileLinter extends Component { 70 | public readonly task: Task; 71 | 72 | public static singleton(scope: Construct): TypeScriptSourceFileLinter { 73 | const root = scope.node.root; 74 | return (root.node.findAll().find((c) => c instanceof TypeScriptSourceFileLinter) ?? 75 | new TypeScriptSourceFileLinter(root)) as TypeScriptSourceFileLinter; 76 | } 77 | 78 | private constructor(scope: Construct) { 79 | super(scope, 'TypeScriptSourceFileLinter'); 80 | 81 | this.task = this.project.addTask('lint:ts', { 82 | exec: 'npx eslint --ext .ts --fix $@', 83 | receiveArgs: true, 84 | env: { 85 | ESLINT_USE_FLAT_CONFIG: 'false', 86 | }, 87 | }); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /projenrc/VersionsFile.ts: -------------------------------------------------------------------------------- 1 | import { IConstruct } from 'constructs'; 2 | import { Component, TextFile } from 'projen'; 3 | 4 | export interface VersionsFileOptions { 5 | path?: string; 6 | versions: { 7 | [key: string]: { 8 | minCdk: string; 9 | minNode: string; 10 | endOfSupport?: Date; 11 | }; 12 | }; 13 | } 14 | 15 | export class VersionsFile extends Component { 16 | public constructor(scope: IConstruct, { 17 | path = 'VERSIONS.md', 18 | versions, 19 | }: VersionsFileOptions) { 20 | super(scope, `versions#${path}`); 21 | 22 | const latestVersion = Object.keys(versions).sort().at(-1); 23 | 24 | const table = Object.entries(versions).map(([version, info]) => { 25 | const base = `| ${version} | ^${info.minCdk} | >=${info.minNode} |`; 26 | 27 | if (!(info.endOfSupport instanceof Date)) { 28 | return `${base} :white_check_mark: |`; 29 | } 30 | 31 | const format = new Intl.DateTimeFormat('en-GB', { 32 | year: 'numeric', 33 | month: 'long', 34 | day: 'numeric', 35 | }); 36 | 37 | if (isSupported(info.endOfSupport)) { 38 | return `${base} Security updates and critical bug fixes until ${format.format(info.endOfSupport)} |`; 39 | } 40 | 41 | return `${base} :x: Support ended on ${format.format(info.endOfSupport)} |`; 42 | }).join('\n'); 43 | 44 | new TextFile(this, path, { 45 | marker: false, 46 | lines: `# Supported Versions 47 | 48 | Only the latest release of each major version is supported. 49 | 50 | | Package version | CDK version | Node.js versions | Support | 51 | | --------------- | ----------- | ---------------- | ------------------------------------------------------------- | 52 | ${table} 53 | 54 | ## Tags on npm 55 | 56 | | Tag | Description | Major version | Will the version change? | 57 | | ----------- | ---------------------------------------------------- | ------------- | ---------------------------- | 58 | | \`latest\` | The latest stable release of the package | \`${latestVersion}\` | Yes, with new major versions | 59 | | \`latest-v*\` | The latest stable release of each major version | n/a | No | 60 | | \`cdk-v2\` | The latest stable release compatible with AWS CDK v2 | \`${latestVersion}\` | Yes, with new major versions | 61 | | \`cdk-v1\` | The latest stable release compatible with AWS CDK v1 | \`v2\` | No | 62 | `.split('\n'), 63 | }); 64 | } 65 | } 66 | 67 | 68 | function isSupported(supportedUntil: Date): boolean { 69 | const eos = new Date(+supportedUntil + 86400000); 70 | return new Date() <= eos; 71 | } 72 | -------------------------------------------------------------------------------- /projenrc/WordmarkReadme.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'projen'; 2 | import { JsiiProject } from 'projen/lib/cdk'; 3 | 4 | enum WordmarkStyle { 5 | DEFAULT, 6 | DYNAMIC, 7 | DARK, 8 | LIGHT, 9 | } 10 | 11 | export interface WordmarkReadmeOptions { 12 | altText?: string; 13 | } 14 | 15 | export class WordmarkReadme extends Component { 16 | private static DEFAULT = 'wordmark.svg'; 17 | private static DYNAMIC = 'wordmark-dyanmic.svg'; 18 | private static LIGHT = 'wordmark-light.svg'; 19 | private static DARK = 'wordmark-dark.svg'; 20 | 21 | public constructor(public readonly project: JsiiProject, private readonly options: WordmarkReadmeOptions = {}) { 22 | super(project); 23 | 24 | const readme = project.tasks.addTask('prepare:readme', { 25 | exec: `sed -i -e '1,5d' -e '6i ${this.imageTag(WordmarkStyle.DEFAULT)}' README.md`, 26 | }); 27 | project.tasks.tryFind('compile')?.prependExec(`if [ ! -z \${CI} ]; then npx projen ${readme.name}; fi`); 28 | project.tasks.tryFind('compile')?.exec('if [ ! -z ${CI} ]; then git checkout README.md; fi'); 29 | } 30 | 31 | private imageTag(style: WordmarkStyle): string { 32 | const baseUrl = this.project.package.manifest.repository.url.replace('https://github.com/', 'https://raw.githubusercontent.com/'); 33 | const altText = this.options.altText ?? this.project.name; 34 | 35 | return `${altText}`; 36 | } 37 | 38 | private imageFile(style: WordmarkStyle): string { 39 | switch (style) { 40 | case WordmarkStyle.DARK: 41 | return WordmarkReadme.DARK; 42 | case WordmarkStyle.LIGHT: 43 | return WordmarkReadme.LIGHT; 44 | case WordmarkStyle.DYNAMIC: 45 | return WordmarkReadme.DYNAMIC; 46 | default: 47 | return WordmarkReadme.DEFAULT; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /projenrc/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IntegrationTests'; 2 | export * from './ReleaseBranches'; 3 | export * from './TypeScriptSourceFile'; 4 | export * from './WordmarkReadme'; 5 | -------------------------------------------------------------------------------- /rosetta/default.ts-fixture: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | import * as cdk from 'aws-cdk-lib'; 3 | import * as lambda from 'aws-cdk-lib/aws-lambda'; 4 | import * as s3 from "aws-cdk-lib/aws-s3"; 5 | import * as s3deploy from "aws-cdk-lib/aws-s3-deployment"; 6 | import * as synthetics from "aws-cdk-lib/aws-synthetics"; 7 | import { 8 | BuildOptions, 9 | EsbuildSource, 10 | EsbuildProvider, 11 | IBuildProvider, 12 | ITransformProvider, 13 | InlineTypeScriptCode, 14 | TypeScriptCode, 15 | TypeScriptSource, 16 | TransformOptions 17 | } from '@mrgrain/cdk-esbuild'; 18 | 19 | const stack = new cdk.Stack(); 20 | 21 | class MyCustomEsbuildProvider implements IBuildProvider, ITransformProvider { 22 | buildSync(options: BuildOptions): void { 23 | // custom implementation goes here 24 | } 25 | 26 | transformSync(code: string, options?: TransformOptions): string { 27 | // custom implementation goes here, return transformed code 28 | return 'transformed code'; 29 | } 30 | } 31 | 32 | 33 | /// here -------------------------------------------------------------------------------- /src/asset.ts: -------------------------------------------------------------------------------- 1 | import { isAbsolute, relative } from 'path'; 2 | import { AssetHashType } from 'aws-cdk-lib'; 3 | import { Asset as S3Asset } from 'aws-cdk-lib/aws-s3-assets'; 4 | import { Construct, Node } from 'constructs'; 5 | import { EsbuildBundler, EntryPoints } from './bundler'; 6 | import { TypeScriptCodeProps } from './code'; 7 | 8 | 9 | export interface TypeScriptAssetProps extends TypeScriptCodeProps { 10 | /** 11 | * A path or list or map of paths to the entry points of your code. 12 | * 13 | * Relative paths are by default resolved from the current working directory. 14 | * To change the working directory, see `buildOptions.absWorkingDir`. 15 | * 16 | * Absolute paths can be used if files are part of the working directory. 17 | * 18 | * Examples: 19 | * - `'src/index.ts'` 20 | * - `require.resolve('./lambda')` 21 | * - `['src/index.ts', 'src/util.ts']` 22 | * - `{one: 'src/two.ts', two: 'src/one.ts'}` 23 | * 24 | * @stability stable 25 | */ 26 | readonly entryPoints: EntryPoints; 27 | } 28 | 29 | 30 | /** 31 | * Bundles the entry points and creates a CDK asset which is uploaded to the bootstrapped CDK S3 bucket during deployment. 32 | * 33 | * The asset can be used by other constructs. 34 | * 35 | * @stability stable 36 | */ 37 | export class TypeScriptAsset extends S3Asset { 38 | /** 39 | * @stability stable 40 | */ 41 | public constructor( 42 | scope: Construct, 43 | id: string, 44 | props: TypeScriptAssetProps, 45 | ) { 46 | const { 47 | assetHash, 48 | buildOptions: options = {}, 49 | } = props; 50 | const entryPoints: string[] | Record = 51 | typeof props.entryPoints === 'string' ? [props.entryPoints] : props.entryPoints; 52 | 53 | const name = scope.node.path + Node.PATH_SEP + id; 54 | 55 | const absWorkingDir = options.absWorkingDir ?? process.cwd(); 56 | 57 | const forceRelativeEntrypointPath = (entryPoint: string): string => { 58 | if (!isAbsolute(entryPoint)) { 59 | return entryPoint; 60 | } 61 | 62 | const relativeEntryPoint = relative(absWorkingDir, entryPoint); 63 | if (relativeEntryPoint.startsWith('..') || isAbsolute(relativeEntryPoint)) { 64 | throw new Error( 65 | `${name}: Entry points must be part of the working directory. See \`buildOptions.absWorkingDir\` to set a working directory different to the current one.`, 66 | ); 67 | } 68 | 69 | return relativeEntryPoint; 70 | }; 71 | 72 | const relativeEntryPoints = 73 | Array.isArray(entryPoints) ? 74 | entryPoints.map(forceRelativeEntrypointPath) : 75 | Object.fromEntries( 76 | Object.entries(entryPoints) 77 | .map(([out, entryPoint]) => ([out, forceRelativeEntrypointPath(entryPoint)]), 78 | ), 79 | ); 80 | 81 | 82 | const buildOptions = { 83 | bundle: true, 84 | ...options, 85 | absWorkingDir, 86 | }; 87 | 88 | super(scope, id, { 89 | path: absWorkingDir, 90 | assetHash, 91 | assetHashType: assetHash ? AssetHashType.CUSTOM : AssetHashType.OUTPUT, 92 | bundling: new EsbuildBundler( 93 | relativeEntryPoints, 94 | { 95 | ...props, 96 | buildOptions, 97 | }, 98 | ), 99 | }); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/code.ts: -------------------------------------------------------------------------------- 1 | import { CfnResource, Stack } from 'aws-cdk-lib'; 2 | import { ResourceBindOptions, Code, CodeConfig } from 'aws-cdk-lib/aws-lambda'; 3 | import { Construct } from 'constructs'; 4 | import { 5 | TypeScriptAssetProps, 6 | TypeScriptAsset, 7 | } from './asset'; 8 | import { BundlerProps, EntryPoints } from './bundler'; 9 | import { BuildOptions } from './esbuild-types'; 10 | import { defaultPlatformProps, uniqueAssetId } from './private/utils'; 11 | 12 | export { CodeConfig } from 'aws-cdk-lib/aws-lambda'; 13 | 14 | export interface TypeScriptCodeProps extends BundlerProps { 15 | /** 16 | * A hash of this asset, which is available at construction time. 17 | * 18 | * As this is a plain string, it can be used in construct IDs in order to enforce creation of a new resource when the content hash has changed. 19 | * 20 | * Defaults to a hash of all files in the resulting bundle. 21 | * 22 | * @stability stable 23 | */ 24 | readonly assetHash?: string; 25 | } 26 | 27 | 28 | /** 29 | * Represents the deployed TypeScript Code. 30 | * 31 | * @stability stable 32 | */ 33 | export class TypeScriptCode extends Code { 34 | private props: TypeScriptAssetProps; 35 | private asset?: TypeScriptAsset; 36 | 37 | /** 38 | * Determines whether this Code is inline code or not. 39 | * 40 | * @deprecated this value is ignored since inline is now determined based on the the inlineCode field of CodeConfig returned from bind(). 41 | */ 42 | public isInline: boolean = false; 43 | 44 | constructor( 45 | /** 46 | * A path or list or map of paths to the entry points of your code. 47 | * 48 | * Relative paths are by default resolved from the current working directory. 49 | * To change the working directory, see `buildOptions.absWorkingDir`. 50 | * 51 | * Absolute paths can be used if files are part of the working directory. 52 | * 53 | * Examples: 54 | * - `'src/index.ts'` 55 | * - `require.resolve('./lambda')` 56 | * - `['src/index.ts', 'src/util.ts']` 57 | * - `{one: 'src/two.ts', two: 'src/one.ts'}` 58 | * 59 | * @stability stable 60 | */ 61 | entryPoints: EntryPoints, 62 | 63 | /** 64 | * Props to change the behavior of the bundler. 65 | * 66 | * Default values for `props.buildOptions`: 67 | * - `bundle=true` 68 | * - `platform=node` 69 | * - `target=nodeX` with X being the major node version running locally 70 | * 71 | * @stability stable 72 | */ 73 | props: TypeScriptCodeProps = {}, 74 | ) { 75 | super(); 76 | 77 | const defaultOptions: Partial = defaultPlatformProps(props.buildOptions); 78 | 79 | this.props = { 80 | ...props, 81 | entryPoints, 82 | buildOptions: { 83 | ...defaultOptions, 84 | ...props.buildOptions, 85 | }, 86 | }; 87 | } 88 | 89 | bind(scope: Construct): CodeConfig { 90 | // If the same AssetCode is used multiple times, retain only the first instantiation. 91 | if (!this.asset) { 92 | this.asset = new TypeScriptAsset( 93 | scope, 94 | uniqueAssetId(scope, this.constructor.name), 95 | this.props, 96 | ); 97 | } else if (Stack.of(this.asset) !== Stack.of(scope)) { 98 | throw new Error( 99 | `Asset is already associated with another stack '${ 100 | Stack.of(this.asset).stackName 101 | }'. ` + 'Create a new Asset instance for every stack.', 102 | ); 103 | } 104 | 105 | return { 106 | s3Location: { 107 | bucketName: this.asset.s3BucketName, 108 | objectKey: this.asset.s3ObjectKey, 109 | }, 110 | }; 111 | } 112 | 113 | /** 114 | * Called after the CFN function resource has been created to allow the code class to bind to it. 115 | * 116 | * Specifically it's required to allow assets to add 117 | * metadata for tooling like SAM CLI to be able to find their origins. 118 | * 119 | * @stability stable 120 | */ 121 | bindToResource(resource: CfnResource, options?: ResourceBindOptions) { 122 | if (!this.asset) { 123 | throw new Error('bindToResource() must be called after bind()'); 124 | } 125 | const resourceProperty = options?.resourceProperty || this.constructor.name; 126 | // https://github.com/aws/aws-cdk/issues/1432 127 | this.asset.addResourceMetadata(resource, resourceProperty); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | TypeScriptAsset, 3 | TypeScriptAssetProps, 4 | } from './asset'; 5 | 6 | export { 7 | EsbuildBundler, 8 | BundlerProps, 9 | } from './bundler'; 10 | 11 | export { 12 | CodeConfig, 13 | TypeScriptCode, 14 | TypeScriptCodeProps, 15 | } from './code'; 16 | 17 | export { 18 | BuildOptions, 19 | TransformOptions, 20 | TsconfigRaw, 21 | CompilerOptions, 22 | } from './esbuild-types'; 23 | 24 | export { 25 | TransformerProps, 26 | InlineJavaScriptCode, 27 | InlineTypeScriptCode, 28 | } from './inline-code'; 29 | 30 | export { 31 | EsbuildProvider, 32 | EsbuildProviderProps, 33 | EsbuildSource, 34 | IBuildProvider, 35 | IEsbuildProvider, 36 | ITransformProvider, 37 | ProviderBuildOptions, 38 | ProviderTransformOptions, 39 | } from './provider'; 40 | 41 | export { 42 | TypeScriptSource, 43 | TypeScriptSourceProps, 44 | } from './source'; 45 | -------------------------------------------------------------------------------- /src/inline-code.ts: -------------------------------------------------------------------------------- 1 | import { Lazy, Stack } from 'aws-cdk-lib'; 2 | import { CodeConfig, InlineCode } from 'aws-cdk-lib/aws-lambda'; 3 | import { Construct, Node } from 'constructs'; 4 | import { TransformOptions, Loader } from './esbuild-types'; 5 | import { defaultPlatformProps, isEsbuildError } from './private/utils'; 6 | import { EsbuildProvider, ITransformProvider } from './provider'; 7 | 8 | /** 9 | * @stability stable 10 | */ 11 | export interface TransformerProps { 12 | /** 13 | * Transform options passed on to esbuild. Please refer to the esbuild Transform API docs for details. 14 | * 15 | * @see https://esbuild.github.io/api/#transform-api 16 | * @stability stable 17 | */ 18 | readonly transformOptions?: TransformOptions; 19 | 20 | /** 21 | * The esbuild Transform API implementation to be used. 22 | * 23 | * Configure the default `EsbuildProvider` for more options or 24 | * provide a custom `ITransformProvider` as an escape hatch. 25 | * 26 | * @stability stable 27 | * 28 | * @default new DefaultEsbuildProvider() 29 | */ 30 | readonly transformProvider?: ITransformProvider; 31 | } 32 | 33 | abstract class BaseInlineCode extends InlineCode { 34 | public readonly isInline = true; 35 | private readonly inlineCode: string; 36 | 37 | public constructor( 38 | code: string, 39 | props: TransformerProps, 40 | ) { 41 | super(code); 42 | 43 | this.inlineCode = Lazy.string({ 44 | produce: () => { 45 | try { 46 | const provider = props.transformProvider ?? EsbuildProvider.defaultTransformationProvider(); 47 | 48 | const transformedCode = provider.transformSync(code, { 49 | color: process.env.NO_COLOR ? Boolean(process.env.NO_COLOR) : undefined, 50 | logLevel: 'warning', 51 | ...(props.transformOptions || {}), 52 | }); 53 | 54 | return transformedCode; 55 | } catch (error) { 56 | if (isEsbuildError(error)) { 57 | throw new Error(`Esbuild failed to transform ${this.constructor.name}`); 58 | } 59 | throw error; 60 | } 61 | }, 62 | }); 63 | } 64 | 65 | public bind(scope: Construct): CodeConfig { 66 | const name = scope.node.path + Node.PATH_SEP + this.constructor.name; 67 | process.stderr.write(`Transforming inline code ${name}...\n`); 68 | 69 | return { 70 | inlineCode: Stack.of(scope).resolve(this.inlineCode), 71 | }; 72 | } 73 | } 74 | 75 | function transformerProps(loader: Loader, props: TransformerProps = {}): TransformerProps { 76 | return { 77 | ...props, 78 | transformOptions: { 79 | loader, 80 | format: 'cjs', 81 | ...defaultPlatformProps(props.transformOptions), 82 | ...props.transformOptions, 83 | }, 84 | }; 85 | } 86 | 87 | /** 88 | * An implementation of `lambda.InlineCode` using the esbuild Transform API. Inline function code is limited to 4 KiB after transformation. 89 | * 90 | * @stability stable 91 | */ 92 | export class InlineJavaScriptCode extends BaseInlineCode { 93 | public constructor( 94 | /** 95 | * The inline code to be transformed. 96 | * 97 | * @stability stable 98 | */ 99 | code: string, 100 | /** 101 | * Props to change the behavior of the transformer. 102 | * 103 | * Default values for `props.transformOptions`: 104 | * - `loader='js'` 105 | * - `platform=node` 106 | * - `target=nodeX` with X being the major node version running locally 107 | * 108 | * @see https://esbuild.github.io/api/#transform-api 109 | * @stability stable 110 | */ 111 | props?: TransformerProps, 112 | ) { 113 | super(code, transformerProps('js', props)); 114 | } 115 | } 116 | 117 | 118 | /** 119 | * An implementation of `lambda.InlineCode` using the esbuild Transform API. Inline function code is limited to 4 KiB after transformation. 120 | * 121 | * @stability stable 122 | */ 123 | export class InlineTypeScriptCode extends BaseInlineCode { 124 | public constructor( 125 | /** 126 | * The inline code to be transformed. 127 | * 128 | * @stability stable 129 | */ 130 | code: string, 131 | /** 132 | * Props to change the behavior of the transformer. 133 | * 134 | * Default values for `transformOptions`: 135 | * - `loader='ts'` 136 | * - `platform=node` 137 | * - `target=nodeX` with X being the major node version running locally 138 | * 139 | * @see https://esbuild.github.io/api/#transform-api 140 | * @stability stable 141 | */ 142 | props?: TransformerProps, 143 | ) { 144 | super(code, transformerProps('ts', props)); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/private/dynamic-package.ts: -------------------------------------------------------------------------------- 1 | import { execFileSync } from 'child_process'; 2 | import { mkdtempSync } from 'fs'; 3 | import { tmpdir } from 'os'; 4 | import { join, resolve } from 'path'; 5 | import { Lazy } from 'aws-cdk-lib'; 6 | 7 | export interface DynamicPackageProps { 8 | /** 9 | * If the package is installed, install into this directory 10 | * 11 | * @default - a temporary directory 12 | */ 13 | readonly installPath?: string; 14 | 15 | /** 16 | * Additional paths to search for an existing package installation 17 | * 18 | * @default - a temporary directory 19 | */ 20 | readonly searchPaths?: string[]; 21 | } 22 | 23 | export class DynamicPackage { 24 | public readonly name: string; 25 | 26 | public readonly version?: string; 27 | 28 | public readonly installPath: string; 29 | 30 | public readonly searchPaths: string[]; 31 | 32 | public get spec(): string { 33 | if (!this.version) { 34 | return this.name; 35 | } 36 | 37 | return `${this.name}@${this.version}`; 38 | } 39 | 40 | public constructor( 41 | /** 42 | * Name of the npm package 43 | * Version to install, or version constraint 44 | * 45 | * @default - no version constraint, install the latest version 46 | */ 47 | packageSpec: string, 48 | props: DynamicPackageProps = {}, 49 | ) { 50 | const { name, version } = this.parsePackageSpec(packageSpec); 51 | 52 | this.name = name; 53 | this.version = version; 54 | this.installPath = 55 | props.installPath || 56 | mkdtempSync(join(tmpdir(), `cdk-dynamic-${this.spec}-`)); 57 | this.searchPaths = props.searchPaths || []; 58 | } 59 | 60 | protected tryResolve(paths?: string[]): string | undefined { 61 | try { 62 | return require.resolve(this.name, paths ? { paths } : undefined); 63 | } catch (_) { 64 | return; 65 | } 66 | } 67 | 68 | public auto(): string { 69 | return this.tryResolve() || this.findInPaths() || this.install(); 70 | } 71 | 72 | public nodeJs(): string { 73 | return this.name; 74 | } 75 | 76 | public findIn(paths: string[]): string | undefined { 77 | paths.forEach((p) => process.stderr.write('trying... '+p+'\n')); 78 | process.stderr.write('\n'); 79 | 80 | return this.tryResolve([...paths].filter(Boolean) as string[]); 81 | } 82 | 83 | public findInPaths(): string | undefined { 84 | return ( 85 | this.findInSearchPaths() || 86 | this.findInLocalPaths() || 87 | this.findInGlobalPaths() 88 | ); 89 | } 90 | 91 | public findInSearchPaths(): string | undefined { 92 | return this.findIn(this.searchPaths); 93 | } 94 | 95 | public findInLocalPaths(): string | undefined { 96 | return this.findIn([ 97 | process.cwd(), 98 | process.env.PWD, 99 | resolve(process.env.PWD || process.cwd(), 'node_modules'), 100 | resolve(process.cwd(), 'node_modules'), 101 | ].filter(Boolean) as string[]); 102 | } 103 | 104 | public findInGlobalPaths(): string | undefined { 105 | return this.findIn([ 106 | process.execPath, 107 | resolve(process.execPath, '../..'), 108 | resolve(process.execPath, '../../lib'), 109 | resolve(process.execPath, '../../node_modules'), 110 | resolve(process.execPath, '../../lib/node_modules'), 111 | ]); 112 | } 113 | 114 | private static installedPackagePath = new Map(); 115 | public install(): string { 116 | return Lazy.string({ 117 | produce: () => { 118 | if (!DynamicPackage.installedPackagePath.has(this.spec)) { 119 | const args = [ 120 | 'install', 121 | this.spec, 122 | '--no-save', 123 | '--prefix', 124 | this.installPath, 125 | ]; 126 | 127 | DynamicPackage.log(`Dynamically installing ${this.spec} into "${this.installPath}"...`, 'info'); 128 | execFileSync('npm', args); 129 | 130 | DynamicPackage.installedPackagePath.set( 131 | this.spec, 132 | require.resolve(this.name, { 133 | paths: [this.installPath], 134 | }), 135 | ); 136 | } 137 | 138 | return DynamicPackage.installedPackagePath.get(this.spec); 139 | }, 140 | }); 141 | } 142 | 143 | protected static log(message: string, _level: string = 'info') { 144 | process.stderr.write(`⬥ ${message}\n`); 145 | } 146 | 147 | private parsePackageSpec(spec: string) { 148 | const hasScope = spec.startsWith('@'); 149 | if (hasScope) { 150 | spec = spec.substring(1); 151 | } 152 | const [module, ...version] = spec.split('@'); 153 | const name = hasScope ? `@${module}` : module; 154 | if (version.length == 0) { 155 | return { name }; 156 | } 157 | 158 | return { name, version: version?.join('@') }; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/private/esbuild-source.ts: -------------------------------------------------------------------------------- 1 | import { DynamicPackage } from './dynamic-package'; 2 | 3 | const dynamicEsbuild = new DynamicPackage('esbuild@^0.25.0'); 4 | 5 | export const Esbuild = { 6 | name: dynamicEsbuild.name, 7 | version: dynamicEsbuild.version, 8 | spec: dynamicEsbuild.spec, 9 | }; 10 | 11 | export class EsbuildSource { 12 | private static dynamicPackage = dynamicEsbuild; 13 | 14 | private constructor() {} 15 | 16 | /** 17 | * `EsbuildSource.nodeJs()` for NodeJs, `EsbuildSource.auto()` for all other languages 18 | */ 19 | public static platformDefault() { 20 | if (Boolean(process.env.JSII_AGENT)) { 21 | return this.auto(); 22 | } 23 | 24 | return this.nodeJs(); 25 | } 26 | 27 | /** 28 | * Try to find the module in most common paths. 29 | */ 30 | public static anywhere() { 31 | return this.dynamicPackage.findInPaths(); 32 | } 33 | 34 | /** 35 | * Try to find the module in common global installation paths. 36 | */ 37 | public static globalPaths() { 38 | return this.dynamicPackage.findInGlobalPaths(); 39 | } 40 | 41 | /** 42 | * Require module by name, do not attempt to find it anywhere else. 43 | */ 44 | public static nodeJs() { 45 | return this.dynamicPackage.nodeJs(); 46 | } 47 | 48 | /** 49 | * Install the module to a temporary location. 50 | */ 51 | public static install() { 52 | return this.dynamicPackage.install(); 53 | } 54 | 55 | /** 56 | * First try to find to module, then install it to a temporary location. 57 | */ 58 | public static auto() { 59 | return this.dynamicPackage.auto(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/private/utils.ts: -------------------------------------------------------------------------------- 1 | import { IConstruct } from 'constructs'; 2 | import { BuildOptions, Platform, TransformOptions } from '../esbuild-types'; 3 | 4 | export function isEsbuildError(error: unknown): boolean { 5 | return !!error 6 | && typeof error == 'object' 7 | && error != null 8 | && 'errors' in error 9 | && 'warnings' in error; 10 | } 11 | 12 | export function nodeMajorVersion(): number { 13 | return parseInt(process.versions.node.split('.')[0], 10); 14 | } 15 | 16 | export function defaultPlatformProps(options?: BuildOptions | TransformOptions): { 17 | platform?: Platform; 18 | target?: string | string[]; 19 | } { 20 | if (!options?.platform || options?.platform === 'node') { 21 | return { platform: 'node', target: 'node' + nodeMajorVersion() }; 22 | } 23 | 24 | return {}; 25 | } 26 | 27 | const assetIds = new WeakMap(); 28 | export const uniqueAssetId = (scope: IConstruct, name: string) => { 29 | const nextId = (assetIds.get(scope) ?? 0) + 1; 30 | assetIds.set(scope, nextId); 31 | 32 | // Only one asset per scope, skip the id 33 | if (nextId === 1) { 34 | return name; 35 | } 36 | 37 | return `${name}${nextId}`; 38 | }; 39 | -------------------------------------------------------------------------------- /src/source.ts: -------------------------------------------------------------------------------- 1 | import { Stack } from 'aws-cdk-lib'; 2 | import { 3 | DeploymentSourceContext, 4 | ISource, 5 | SourceConfig, 6 | } from 'aws-cdk-lib/aws-s3-deployment'; 7 | import { Construct } from 'constructs'; 8 | import { TypeScriptAsset, TypeScriptAssetProps } from './asset'; 9 | import { EntryPoints } from './bundler'; 10 | import { TypeScriptCodeProps } from './code'; 11 | import { BuildOptions } from './esbuild-types'; 12 | import { uniqueAssetId } from './private/utils'; 13 | 14 | export interface TypeScriptSourceProps extends TypeScriptCodeProps {}; 15 | 16 | export class TypeScriptSource implements ISource { 17 | private props: TypeScriptAssetProps; 18 | private asset?: TypeScriptAsset; 19 | 20 | constructor( 21 | /** 22 | * A path or list or map of paths to the entry points of your code. 23 | * 24 | * Relative paths are by default resolved from the current working directory. 25 | * To change the working directory, see `buildOptions.absWorkingDir`. 26 | * 27 | * Absolute paths can be used if files are part of the working directory. 28 | * 29 | * Examples: 30 | * - `'src/index.ts'` 31 | * - `require.resolve('./lambda')` 32 | * - `['src/index.ts', 'src/util.ts']` 33 | * - `{one: 'src/two.ts', two: 'src/one.ts'}` 34 | * 35 | * @stability stable 36 | */ 37 | entryPoints: EntryPoints, 38 | 39 | /** 40 | * Props to change the behavior of the bundler. 41 | * 42 | * Default values for `props.buildOptions`: 43 | * - `bundle=true` 44 | * - `platform=browser` 45 | * 46 | * @stability stable 47 | */ 48 | props: TypeScriptSourceProps = {}, 49 | ) { 50 | const defaultOptions: Partial = { 51 | platform: 'browser', 52 | }; 53 | 54 | this.props = { 55 | entryPoints, 56 | ...props, 57 | buildOptions: { 58 | ...defaultOptions, 59 | ...props.buildOptions, 60 | }, 61 | }; 62 | } 63 | 64 | 65 | bind(scope: Construct, context?: DeploymentSourceContext): SourceConfig { 66 | // If the same AssetCode is used multiple times, retain only the first instantiation. 67 | if (!this.asset) { 68 | this.asset = new TypeScriptAsset( 69 | scope, 70 | uniqueAssetId(scope, this.constructor.name), 71 | this.props, 72 | ); 73 | } else if (Stack.of(this.asset) !== Stack.of(scope)) { 74 | throw new Error( 75 | `Asset is already associated with another stack '${ 76 | Stack.of(this.asset).stackName 77 | }'. ` + 'Create a new Asset instance for every stack.', 78 | ); 79 | } 80 | 81 | if (!context) { 82 | throw new Error( 83 | `To use a ${this.constructor.name}, context must be provided`, 84 | ); 85 | } 86 | 87 | // we give permissions on all files in the bucket since we don't want to 88 | // accidentally revoke permission on old versions when deploying a new 89 | // version (for example, when using Lambda traffic shifting). 90 | this.asset.bucket.grantRead(context.handlerRole); 91 | 92 | return { 93 | bucket: this.asset.bucket, 94 | zipObjectKey: this.asset.s3ObjectKey, 95 | }; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /test/fixtures/handlers/colors.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | colour: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites) => { 8 | return ( 9 | `My favorite colour is ${favorites.colour}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/handlers/invalid-handler.js: -------------------------------------------------------------------------------- 1 | import { invalid } from './util'; 2 | 3 | export async function handler(): Promisevoid> { 4 | consoe.lmult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/handlers/js-handler.js: -------------------------------------------------------------------------------- 1 | import { add } from './util'; 2 | 3 | export async function handler() { 4 | console.log(add(1, 2)); 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/handlers/ts-handler.ts: -------------------------------------------------------------------------------- 1 | import { mult } from './util'; 2 | 3 | export async function handler(): Promise { 4 | console.log(mult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/handlers/util.ts: -------------------------------------------------------------------------------- 1 | export function add(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | export function mult(a: number, b: number): number { 6 | return a * b; 7 | } 8 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as cdk 2 | import aws_cdk.aws_lambda as lambda_ 3 | import aws_cdk.integ_tests_alpha as integ 4 | from constructs import Construct 5 | from mrgrain.cdk_esbuild import ( 6 | BuildOptions, 7 | InlineTypeScriptCode, 8 | TypeScriptCode, 9 | EsbuildProvider, 10 | EsbuildSource, 11 | ) 12 | 13 | 14 | class LambdaStack(cdk.Stack): 15 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 16 | super().__init__(scope, construct_id, **kwargs) 17 | 18 | # Set a new default 19 | EsbuildProvider.override_default_provider( 20 | EsbuildProvider(esbuild_module_path=EsbuildSource.install()) 21 | ) 22 | 23 | # Use an explicit provider 24 | lambda_.Function( 25 | self, 26 | "FunctionOne", 27 | runtime=lambda_.Runtime.NODEJS_16_X, 28 | handler="index.handler", 29 | code=TypeScriptCode( 30 | "../fixtures/handlers/colors.ts", 31 | copy_dir="../fixtures/handlers", 32 | build_provider=EsbuildProvider(), # Override for a specific construct 33 | ), 34 | ) 35 | 36 | # Set build options 37 | lambda_.Function( 38 | self, 39 | "FunctionTwo", 40 | runtime=lambda_.Runtime.NODEJS_16_X, 41 | handler="index.handler", 42 | code=TypeScriptCode( 43 | "../fixtures/handlers/colors.ts", 44 | build_options=BuildOptions( 45 | format="esm", 46 | outfile="index.mjs", 47 | external=["aws-sdk"], 48 | log_level="verbose", 49 | ), 50 | ), 51 | ) 52 | 53 | # Inline Code 54 | lambda_.Function( 55 | self, 56 | "InlineFunction", 57 | runtime=lambda_.Runtime.NODEJS_16_X, 58 | handler="index.handler", 59 | code=InlineTypeScriptCode( 60 | """ 61 | const hello: string = 'world'; 62 | export function handler() { 63 | console.log(hello); 64 | } 65 | """, 66 | # Try to find the package anywhere, but don't install it 67 | transform_provider=EsbuildProvider( 68 | esbuild_module_path=EsbuildSource.anywhere() 69 | ), 70 | ), 71 | ) 72 | 73 | 74 | app = cdk.App() 75 | stack = LambdaStack(app, "Lambda") 76 | 77 | integ.IntegTest(app, "LambdaFunctions", test_cases=[stack]) 78 | 79 | app.synth() 80 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/Lambda.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8": { 5 | "source": { 6 | "path": "asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8", 7 | "packaging": "zip" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8.zip", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | }, 17 | "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9": { 18 | "source": { 19 | "path": "asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9", 20 | "packaging": "zip" 21 | }, 22 | "destinations": { 23 | "current_account-current_region": { 24 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 25 | "objectKey": "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9.zip", 26 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 27 | } 28 | } 29 | }, 30 | "343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba": { 31 | "source": { 32 | "path": "Lambda.template.json", 33 | "packaging": "file" 34 | }, 35 | "destinations": { 36 | "current_account-current_region": { 37 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 38 | "objectKey": "343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba.json", 39 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 40 | } 41 | } 42 | } 43 | }, 44 | "dockerImages": {} 45 | } -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/Lambda.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "FunctionOneServiceRoleB0F6870D": { 4 | "Type": "AWS::IAM::Role", 5 | "Properties": { 6 | "AssumeRolePolicyDocument": { 7 | "Statement": [ 8 | { 9 | "Action": "sts:AssumeRole", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "Service": "lambda.amazonaws.com" 13 | } 14 | } 15 | ], 16 | "Version": "2012-10-17" 17 | }, 18 | "ManagedPolicyArns": [ 19 | { 20 | "Fn::Join": [ 21 | "", 22 | [ 23 | "arn:", 24 | { 25 | "Ref": "AWS::Partition" 26 | }, 27 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 28 | ] 29 | ] 30 | } 31 | ] 32 | } 33 | }, 34 | "FunctionOne8A86801F": { 35 | "Type": "AWS::Lambda::Function", 36 | "Properties": { 37 | "Code": { 38 | "S3Bucket": { 39 | "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" 40 | }, 41 | "S3Key": "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8.zip" 42 | }, 43 | "Role": { 44 | "Fn::GetAtt": [ 45 | "FunctionOneServiceRoleB0F6870D", 46 | "Arn" 47 | ] 48 | }, 49 | "Handler": "index.handler", 50 | "Runtime": "nodejs16.x" 51 | }, 52 | "DependsOn": [ 53 | "FunctionOneServiceRoleB0F6870D" 54 | ] 55 | }, 56 | "FunctionTwoServiceRoleF26DAB39": { 57 | "Type": "AWS::IAM::Role", 58 | "Properties": { 59 | "AssumeRolePolicyDocument": { 60 | "Statement": [ 61 | { 62 | "Action": "sts:AssumeRole", 63 | "Effect": "Allow", 64 | "Principal": { 65 | "Service": "lambda.amazonaws.com" 66 | } 67 | } 68 | ], 69 | "Version": "2012-10-17" 70 | }, 71 | "ManagedPolicyArns": [ 72 | { 73 | "Fn::Join": [ 74 | "", 75 | [ 76 | "arn:", 77 | { 78 | "Ref": "AWS::Partition" 79 | }, 80 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 81 | ] 82 | ] 83 | } 84 | ] 85 | } 86 | }, 87 | "FunctionTwoDAB66576": { 88 | "Type": "AWS::Lambda::Function", 89 | "Properties": { 90 | "Code": { 91 | "S3Bucket": { 92 | "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" 93 | }, 94 | "S3Key": "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9.zip" 95 | }, 96 | "Role": { 97 | "Fn::GetAtt": [ 98 | "FunctionTwoServiceRoleF26DAB39", 99 | "Arn" 100 | ] 101 | }, 102 | "Handler": "index.handler", 103 | "Runtime": "nodejs16.x" 104 | }, 105 | "DependsOn": [ 106 | "FunctionTwoServiceRoleF26DAB39" 107 | ] 108 | }, 109 | "InlineFunctionServiceRole8084C553": { 110 | "Type": "AWS::IAM::Role", 111 | "Properties": { 112 | "AssumeRolePolicyDocument": { 113 | "Statement": [ 114 | { 115 | "Action": "sts:AssumeRole", 116 | "Effect": "Allow", 117 | "Principal": { 118 | "Service": "lambda.amazonaws.com" 119 | } 120 | } 121 | ], 122 | "Version": "2012-10-17" 123 | }, 124 | "ManagedPolicyArns": [ 125 | { 126 | "Fn::Join": [ 127 | "", 128 | [ 129 | "arn:", 130 | { 131 | "Ref": "AWS::Partition" 132 | }, 133 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 134 | ] 135 | ] 136 | } 137 | ] 138 | } 139 | }, 140 | "InlineFunction18B48CA2": { 141 | "Type": "AWS::Lambda::Function", 142 | "Properties": { 143 | "Code": { 144 | "ZipFile": "var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar stdin_exports = {};\n__export(stdin_exports, {\n handler: () => handler\n});\nmodule.exports = __toCommonJS(stdin_exports);\nconst hello = \"world\";\nfunction handler() {\n console.log(hello);\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n handler\n});\n" 145 | }, 146 | "Role": { 147 | "Fn::GetAtt": [ 148 | "InlineFunctionServiceRole8084C553", 149 | "Arn" 150 | ] 151 | }, 152 | "Handler": "index.handler", 153 | "Runtime": "nodejs16.x" 154 | }, 155 | "DependsOn": [ 156 | "InlineFunctionServiceRole8084C553" 157 | ] 158 | } 159 | }, 160 | "Parameters": { 161 | "BootstrapVersion": { 162 | "Type": "AWS::SSM::Parameter::Value", 163 | "Default": "/cdk-bootstrap/hnb659fds/version", 164 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 165 | } 166 | }, 167 | "Rules": { 168 | "CheckBootstrapVersion": { 169 | "Assertions": [ 170 | { 171 | "Assert": { 172 | "Fn::Not": [ 173 | { 174 | "Fn::Contains": [ 175 | [ 176 | "1", 177 | "2", 178 | "3", 179 | "4", 180 | "5" 181 | ], 182 | { 183 | "Ref": "BootstrapVersion" 184 | } 185 | ] 186 | } 187 | ] 188 | }, 189 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 190 | } 191 | ] 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/LambdaFunctionsDefaultTestDeployAssertF6E30484.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { 5 | "source": { 6 | "path": "LambdaFunctionsDefaultTestDeployAssertF6E30484.template.json", 7 | "packaging": "file" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | } 17 | }, 18 | "dockerImages": {} 19 | } -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/LambdaFunctionsDefaultTestDeployAssertF6E30484.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "BootstrapVersion": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/cdk-bootstrap/hnb659fds/version", 6 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 7 | } 8 | }, 9 | "Rules": { 10 | "CheckBootstrapVersion": { 11 | "Assertions": [ 12 | { 13 | "Assert": { 14 | "Fn::Not": [ 15 | { 16 | "Fn::Contains": [ 17 | [ 18 | "1", 19 | "2", 20 | "3", 21 | "4", 22 | "5" 23 | ], 24 | { 25 | "Ref": "BootstrapVersion" 26 | } 27 | ] 28 | } 29 | ] 30 | }, 31 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 32 | } 33 | ] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9/index.mjs: -------------------------------------------------------------------------------- 1 | // ../fixtures/handlers/colors.ts 2 | var handler = async (favorites) => { 3 | return `My favorite colour is ${favorites.colour}, I always like to eat some ${favorites.food} and ${favorites.season} is the best time of the year.`; 4 | }; 5 | export { 6 | handler 7 | }; 8 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/colors.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // ../fixtures/handlers/colors.ts 21 | var colors_exports = {}; 22 | __export(colors_exports, { 23 | handler: () => handler 24 | }); 25 | module.exports = __toCommonJS(colors_exports); 26 | var handler = async (favorites) => { 27 | return `My favorite colour is ${favorites.colour}, I always like to eat some ${favorites.food} and ${favorites.season} is the best time of the year.`; 28 | }; 29 | // Annotate the CommonJS export names for ESM import in node: 30 | 0 && (module.exports = { 31 | handler 32 | }); 33 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/colors.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | colour: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites) => { 8 | return ( 9 | `My favorite colour is ${favorites.colour}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/invalid-handler.js: -------------------------------------------------------------------------------- 1 | import { invalid } from './util'; 2 | 3 | export async function handler(): Promisevoid> { 4 | consoe.lmult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/js-handler.js: -------------------------------------------------------------------------------- 1 | import { add } from './util'; 2 | 3 | export async function handler() { 4 | console.log(add(1, 2)); 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/ts-handler.ts: -------------------------------------------------------------------------------- 1 | import { mult } from './util'; 2 | 3 | export async function handler(): Promise { 4 | console.log(mult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/util.ts: -------------------------------------------------------------------------------- 1 | export function add(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | export function mult(a: number, b: number): number { 6 | return a * b; 7 | } 8 | -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/integ.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "testCases": { 4 | "LambdaFunctions/DefaultTest": { 5 | "stacks": [ 6 | "Lambda" 7 | ], 8 | "assertionStack": "LambdaFunctions/DefaultTest/DeployAssert", 9 | "assertionStackName": "LambdaFunctionsDefaultTestDeployAssertF6E30484" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/integ/integ-lambda.py.snapshot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "artifacts": { 4 | "Lambda.assets": { 5 | "type": "cdk:asset-manifest", 6 | "properties": { 7 | "file": "Lambda.assets.json", 8 | "requiresBootstrapStackVersion": 6, 9 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 10 | } 11 | }, 12 | "Lambda": { 13 | "type": "aws:cloudformation:stack", 14 | "environment": "aws://unknown-account/unknown-region", 15 | "properties": { 16 | "templateFile": "Lambda.template.json", 17 | "validateOnSynth": false, 18 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", 19 | "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", 20 | "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba.json", 21 | "requiresBootstrapStackVersion": 6, 22 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", 23 | "additionalDependencies": [ 24 | "Lambda.assets" 25 | ], 26 | "lookupRole": { 27 | "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", 28 | "requiresBootstrapStackVersion": 8, 29 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 30 | } 31 | }, 32 | "dependencies": [ 33 | "Lambda.assets" 34 | ], 35 | "metadata": { 36 | "/Lambda/FunctionOne/ServiceRole/Resource": [ 37 | { 38 | "type": "aws:cdk:logicalId", 39 | "data": "FunctionOneServiceRoleB0F6870D" 40 | } 41 | ], 42 | "/Lambda/FunctionOne/Resource": [ 43 | { 44 | "type": "aws:cdk:logicalId", 45 | "data": "FunctionOne8A86801F" 46 | } 47 | ], 48 | "/Lambda/FunctionTwo/ServiceRole/Resource": [ 49 | { 50 | "type": "aws:cdk:logicalId", 51 | "data": "FunctionTwoServiceRoleF26DAB39" 52 | } 53 | ], 54 | "/Lambda/FunctionTwo/Resource": [ 55 | { 56 | "type": "aws:cdk:logicalId", 57 | "data": "FunctionTwoDAB66576" 58 | } 59 | ], 60 | "/Lambda/InlineFunction/ServiceRole/Resource": [ 61 | { 62 | "type": "aws:cdk:logicalId", 63 | "data": "InlineFunctionServiceRole8084C553" 64 | } 65 | ], 66 | "/Lambda/InlineFunction/Resource": [ 67 | { 68 | "type": "aws:cdk:logicalId", 69 | "data": "InlineFunction18B48CA2" 70 | } 71 | ], 72 | "/Lambda/BootstrapVersion": [ 73 | { 74 | "type": "aws:cdk:logicalId", 75 | "data": "BootstrapVersion" 76 | } 77 | ], 78 | "/Lambda/CheckBootstrapVersion": [ 79 | { 80 | "type": "aws:cdk:logicalId", 81 | "data": "CheckBootstrapVersion" 82 | } 83 | ] 84 | }, 85 | "displayName": "Lambda" 86 | }, 87 | "LambdaFunctionsDefaultTestDeployAssertF6E30484.assets": { 88 | "type": "cdk:asset-manifest", 89 | "properties": { 90 | "file": "LambdaFunctionsDefaultTestDeployAssertF6E30484.assets.json", 91 | "requiresBootstrapStackVersion": 6, 92 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 93 | } 94 | }, 95 | "LambdaFunctionsDefaultTestDeployAssertF6E30484": { 96 | "type": "aws:cloudformation:stack", 97 | "environment": "aws://unknown-account/unknown-region", 98 | "properties": { 99 | "templateFile": "LambdaFunctionsDefaultTestDeployAssertF6E30484.template.json", 100 | "validateOnSynth": false, 101 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", 102 | "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", 103 | "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", 104 | "requiresBootstrapStackVersion": 6, 105 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", 106 | "additionalDependencies": [ 107 | "LambdaFunctionsDefaultTestDeployAssertF6E30484.assets" 108 | ], 109 | "lookupRole": { 110 | "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", 111 | "requiresBootstrapStackVersion": 8, 112 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 113 | } 114 | }, 115 | "dependencies": [ 116 | "LambdaFunctionsDefaultTestDeployAssertF6E30484.assets" 117 | ], 118 | "metadata": { 119 | "/LambdaFunctions/DefaultTest/DeployAssert/BootstrapVersion": [ 120 | { 121 | "type": "aws:cdk:logicalId", 122 | "data": "BootstrapVersion" 123 | } 124 | ], 125 | "/LambdaFunctions/DefaultTest/DeployAssert/CheckBootstrapVersion": [ 126 | { 127 | "type": "aws:cdk:logicalId", 128 | "data": "CheckBootstrapVersion" 129 | } 130 | ] 131 | }, 132 | "displayName": "LambdaFunctions/DefaultTest/DeployAssert" 133 | }, 134 | "Tree": { 135 | "type": "cdk:tree", 136 | "properties": { 137 | "file": "tree.json" 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /test/integ/integ-website.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as cdk 2 | import aws_cdk.aws_s3 as s3 3 | import aws_cdk.aws_s3_deployment as s3_deployment 4 | import aws_cdk.integ_tests_alpha as integ 5 | from constructs import Construct 6 | from mrgrain.cdk_esbuild import ( 7 | TypeScriptSource, 8 | EsbuildProvider, 9 | EsbuildSource, 10 | ) 11 | 12 | 13 | class WebsiteStack(cdk.Stack): 14 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 15 | super().__init__(scope, construct_id, **kwargs) 16 | 17 | # Set a new default 18 | EsbuildProvider.override_default_provider( 19 | EsbuildProvider(esbuild_module_path=EsbuildSource.install()) 20 | ) 21 | 22 | s3_deployment.BucketDeployment( 23 | self, 24 | "Website", 25 | sources=[ 26 | TypeScriptSource( 27 | "../fixtures/handlers/colors.ts", 28 | copy_dir="../fixtures/handlers", 29 | build_provider=EsbuildProvider(), # Override for a specific construct 30 | ) 31 | ], 32 | destination_bucket=s3.Bucket( 33 | self, 34 | "Bucket", 35 | ), 36 | ) 37 | 38 | 39 | app = cdk.App() 40 | stack = WebsiteStack(app, "Website") 41 | 42 | integ.IntegTest(app, "S3Website", test_cases=[stack]) 43 | 44 | app.synth() 45 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/S3WebsiteDefaultTestDeployAssert3345D10F.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "32.0.0", 3 | "files": { 4 | "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { 5 | "source": { 6 | "path": "S3WebsiteDefaultTestDeployAssert3345D10F.template.json", 7 | "packaging": "file" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | } 17 | }, 18 | "dockerImages": {} 19 | } -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/S3WebsiteDefaultTestDeployAssert3345D10F.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "BootstrapVersion": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/cdk-bootstrap/hnb659fds/version", 6 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 7 | } 8 | }, 9 | "Rules": { 10 | "CheckBootstrapVersion": { 11 | "Assertions": [ 12 | { 13 | "Assert": { 14 | "Fn::Not": [ 15 | { 16 | "Fn::Contains": [ 17 | [ 18 | "1", 19 | "2", 20 | "3", 21 | "4", 22 | "5" 23 | ], 24 | { 25 | "Ref": "BootstrapVersion" 26 | } 27 | ] 28 | } 29 | ] 30 | }, 31 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 32 | } 33 | ] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/Website.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "32.0.0", 3 | "files": { 4 | "cff916937906abb9c99e0ecbb4accbc091c734ce975c7ff64b3f4bfae4372b9c": { 5 | "source": { 6 | "path": "asset.cff916937906abb9c99e0ecbb4accbc091c734ce975c7ff64b3f4bfae4372b9c.zip", 7 | "packaging": "file" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "cff916937906abb9c99e0ecbb4accbc091c734ce975c7ff64b3f4bfae4372b9c.zip", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | }, 17 | "9eb41a5505d37607ac419321497a4f8c21cf0ee1f9b4a6b29aa04301aea5c7fd": { 18 | "source": { 19 | "path": "asset.9eb41a5505d37607ac419321497a4f8c21cf0ee1f9b4a6b29aa04301aea5c7fd", 20 | "packaging": "zip" 21 | }, 22 | "destinations": { 23 | "current_account-current_region": { 24 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 25 | "objectKey": "9eb41a5505d37607ac419321497a4f8c21cf0ee1f9b4a6b29aa04301aea5c7fd.zip", 26 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 27 | } 28 | } 29 | }, 30 | "935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b": { 31 | "source": { 32 | "path": "asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b", 33 | "packaging": "zip" 34 | }, 35 | "destinations": { 36 | "current_account-current_region": { 37 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 38 | "objectKey": "935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b.zip", 39 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 40 | } 41 | } 42 | }, 43 | "922c694cf1fa09f560d74a934573a35d073df8814666a5539e8c3f649f93f1ab": { 44 | "source": { 45 | "path": "Website.template.json", 46 | "packaging": "file" 47 | }, 48 | "destinations": { 49 | "current_account-current_region": { 50 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 51 | "objectKey": "922c694cf1fa09f560d74a934573a35d073df8814666a5539e8c3f649f93f1ab.json", 52 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 53 | } 54 | } 55 | } 56 | }, 57 | "dockerImages": {} 58 | } -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/colors.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (() => { 3 | // ../fixtures/handlers/colors.ts 4 | var handler = async (favorites) => { 5 | return `My favorite colour is ${favorites.colour}, I always like to eat some ${favorites.food} and ${favorites.season} is the best time of the year.`; 6 | }; 7 | })(); 8 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/colors.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | colour: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites) => { 8 | return ( 9 | `My favorite colour is ${favorites.colour}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/invalid-handler.js: -------------------------------------------------------------------------------- 1 | import { invalid } from './util'; 2 | 3 | export async function handler(): Promisevoid> { 4 | consoe.lmult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/js-handler.js: -------------------------------------------------------------------------------- 1 | import { add } from './util'; 2 | 3 | export async function handler() { 4 | console.log(add(1, 2)); 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/ts-handler.ts: -------------------------------------------------------------------------------- 1 | import { mult } from './util'; 2 | 3 | export async function handler(): Promise { 4 | console.log(mult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/asset.935a5859f7c86d0e3b9dcd14501bb37bd084abdb755c75bd300d4ef3a8f2243b/util.ts: -------------------------------------------------------------------------------- 1 | export function add(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | export function mult(a: number, b: number): number { 6 | return a * b; 7 | } 8 | -------------------------------------------------------------------------------- /test/integ/integ-website.py.snapshot/integ.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "32.0.0", 3 | "testCases": { 4 | "S3Website/DefaultTest": { 5 | "stacks": [ 6 | "Website" 7 | ], 8 | "assertionStack": "S3Website/DefaultTest/DeployAssert", 9 | "assertionStackName": "S3WebsiteDefaultTestDeployAssert3345D10F" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/aws/aws-cdk-go/awscdk/v2" 5 | "github.com/aws/aws-cdk-go/awscdk/v2/awslambda" 6 | "github.com/aws/aws-cdk-go/awscdkintegtestsalpha/v2" 7 | "github.com/aws/jsii-runtime-go" 8 | "github.com/mrgrain/cdk-esbuild-go/cdkesbuild" 9 | ) 10 | 11 | func main() { 12 | defer jsii.Close() 13 | 14 | app := awscdk.NewApp(nil) 15 | stack := awscdk.NewStack(app, jsii.String("GoLambdaStack"), nil) 16 | 17 | // Override default provider 18 | cdkesbuild.EsbuildProvider_OverrideDefaultBuildProvider( 19 | cdkesbuild.NewEsbuildProvider(&cdkesbuild.EsbuildProviderProps{ 20 | EsbuildModulePath: cdkesbuild.EsbuildSource_Install(), 21 | }), 22 | ) 23 | 24 | // Use an explicit provider 25 | awslambda.NewFunction(stack, jsii.String("FunctionOne"), &awslambda.FunctionProps{ 26 | Runtime: awslambda.Runtime_NODEJS_16_X(), 27 | Handler: jsii.String("index.handler"), 28 | Code: cdkesbuild.NewTypeScriptCode( 29 | jsii.String("../fixtures/handlers/colors.ts"), 30 | &cdkesbuild.TypeScriptCodeProps{ 31 | CopyDir: jsii.String("../fixtures/handlers"), 32 | BuildProvider: cdkesbuild.NewEsbuildProvider(&cdkesbuild.EsbuildProviderProps{}), 33 | }, 34 | ), 35 | }) 36 | 37 | // Set build options 38 | awslambda.NewFunction(stack, jsii.String("FunctionTwo"), &awslambda.FunctionProps{ 39 | Runtime: awslambda.Runtime_NODEJS_16_X(), 40 | Handler: jsii.String("index.handler"), 41 | Code: cdkesbuild.NewTypeScriptCode( 42 | jsii.String("../fixtures/handlers/colors.ts"), 43 | &cdkesbuild.TypeScriptCodeProps{ 44 | BuildOptions: &cdkesbuild.BuildOptions{ 45 | Format: jsii.String("esm"), 46 | Outfile: jsii.String("index.mjs"), 47 | External: &[]*string{ 48 | jsii.String("aws-sdk"), 49 | }, 50 | LogLevel: jsii.String("verbose"), 51 | }, 52 | }, 53 | ), 54 | }) 55 | 56 | // Inline Code 57 | awslambda.NewFunction(stack, jsii.String("InlineFunction"), &awslambda.FunctionProps{ 58 | Runtime: awslambda.Runtime_NODEJS_16_X(), 59 | Handler: jsii.String("index.handler"), 60 | Code: cdkesbuild.NewInlineTypeScriptCode( 61 | jsii.String(` 62 | const hello: string = 'world'; 63 | export function handler() { 64 | console.log(hello); 65 | } 66 | `), 67 | &cdkesbuild.TransformerProps{ 68 | // Try to find the package anywhere, but don't install it 69 | TransformProvider: cdkesbuild.NewEsbuildProvider(&cdkesbuild.EsbuildProviderProps{ 70 | EsbuildModulePath: cdkesbuild.EsbuildSource_Anywhere(), 71 | }), 72 | }, 73 | ), 74 | }) 75 | 76 | awscdkintegtestsalpha.NewIntegTest(app, jsii.String("GoLambdaFunctions"), &awscdkintegtestsalpha.IntegTestProps{ 77 | TestCases: &[]awscdk.Stack{ 78 | stack, 79 | }, 80 | }) 81 | 82 | app.Synth(nil) 83 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { 5 | "source": { 6 | "path": "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.template.json", 7 | "packaging": "file" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | } 17 | }, 18 | "dockerImages": {} 19 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLambdaFunctionsDefaultTestDeployAssert141E9B32.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": { 3 | "BootstrapVersion": { 4 | "Type": "AWS::SSM::Parameter::Value", 5 | "Default": "/cdk-bootstrap/hnb659fds/version", 6 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 7 | } 8 | }, 9 | "Rules": { 10 | "CheckBootstrapVersion": { 11 | "Assertions": [ 12 | { 13 | "Assert": { 14 | "Fn::Not": [ 15 | { 16 | "Fn::Contains": [ 17 | [ 18 | "1", 19 | "2", 20 | "3", 21 | "4", 22 | "5" 23 | ], 24 | { 25 | "Ref": "BootstrapVersion" 26 | } 27 | ] 28 | } 29 | ] 30 | }, 31 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 32 | } 33 | ] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLambdaStack.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8": { 5 | "source": { 6 | "path": "asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8", 7 | "packaging": "zip" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8.zip", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | }, 17 | "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9": { 18 | "source": { 19 | "path": "asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9", 20 | "packaging": "zip" 21 | }, 22 | "destinations": { 23 | "current_account-current_region": { 24 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 25 | "objectKey": "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9.zip", 26 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 27 | } 28 | } 29 | }, 30 | "343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba": { 31 | "source": { 32 | "path": "GoLambdaStack.template.json", 33 | "packaging": "file" 34 | }, 35 | "destinations": { 36 | "current_account-current_region": { 37 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 38 | "objectKey": "343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba.json", 39 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 40 | } 41 | } 42 | } 43 | }, 44 | "dockerImages": {} 45 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLambdaStack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "FunctionOneServiceRoleB0F6870D": { 4 | "Type": "AWS::IAM::Role", 5 | "Properties": { 6 | "AssumeRolePolicyDocument": { 7 | "Statement": [ 8 | { 9 | "Action": "sts:AssumeRole", 10 | "Effect": "Allow", 11 | "Principal": { 12 | "Service": "lambda.amazonaws.com" 13 | } 14 | } 15 | ], 16 | "Version": "2012-10-17" 17 | }, 18 | "ManagedPolicyArns": [ 19 | { 20 | "Fn::Join": [ 21 | "", 22 | [ 23 | "arn:", 24 | { 25 | "Ref": "AWS::Partition" 26 | }, 27 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 28 | ] 29 | ] 30 | } 31 | ] 32 | } 33 | }, 34 | "FunctionOne8A86801F": { 35 | "Type": "AWS::Lambda::Function", 36 | "Properties": { 37 | "Code": { 38 | "S3Bucket": { 39 | "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" 40 | }, 41 | "S3Key": "dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8.zip" 42 | }, 43 | "Role": { 44 | "Fn::GetAtt": [ 45 | "FunctionOneServiceRoleB0F6870D", 46 | "Arn" 47 | ] 48 | }, 49 | "Handler": "index.handler", 50 | "Runtime": "nodejs16.x" 51 | }, 52 | "DependsOn": [ 53 | "FunctionOneServiceRoleB0F6870D" 54 | ] 55 | }, 56 | "FunctionTwoServiceRoleF26DAB39": { 57 | "Type": "AWS::IAM::Role", 58 | "Properties": { 59 | "AssumeRolePolicyDocument": { 60 | "Statement": [ 61 | { 62 | "Action": "sts:AssumeRole", 63 | "Effect": "Allow", 64 | "Principal": { 65 | "Service": "lambda.amazonaws.com" 66 | } 67 | } 68 | ], 69 | "Version": "2012-10-17" 70 | }, 71 | "ManagedPolicyArns": [ 72 | { 73 | "Fn::Join": [ 74 | "", 75 | [ 76 | "arn:", 77 | { 78 | "Ref": "AWS::Partition" 79 | }, 80 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 81 | ] 82 | ] 83 | } 84 | ] 85 | } 86 | }, 87 | "FunctionTwoDAB66576": { 88 | "Type": "AWS::Lambda::Function", 89 | "Properties": { 90 | "Code": { 91 | "S3Bucket": { 92 | "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" 93 | }, 94 | "S3Key": "6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9.zip" 95 | }, 96 | "Role": { 97 | "Fn::GetAtt": [ 98 | "FunctionTwoServiceRoleF26DAB39", 99 | "Arn" 100 | ] 101 | }, 102 | "Handler": "index.handler", 103 | "Runtime": "nodejs16.x" 104 | }, 105 | "DependsOn": [ 106 | "FunctionTwoServiceRoleF26DAB39" 107 | ] 108 | }, 109 | "InlineFunctionServiceRole8084C553": { 110 | "Type": "AWS::IAM::Role", 111 | "Properties": { 112 | "AssumeRolePolicyDocument": { 113 | "Statement": [ 114 | { 115 | "Action": "sts:AssumeRole", 116 | "Effect": "Allow", 117 | "Principal": { 118 | "Service": "lambda.amazonaws.com" 119 | } 120 | } 121 | ], 122 | "Version": "2012-10-17" 123 | }, 124 | "ManagedPolicyArns": [ 125 | { 126 | "Fn::Join": [ 127 | "", 128 | [ 129 | "arn:", 130 | { 131 | "Ref": "AWS::Partition" 132 | }, 133 | ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 134 | ] 135 | ] 136 | } 137 | ] 138 | } 139 | }, 140 | "InlineFunction18B48CA2": { 141 | "Type": "AWS::Lambda::Function", 142 | "Properties": { 143 | "Code": { 144 | "ZipFile": "var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar stdin_exports = {};\n__export(stdin_exports, {\n handler: () => handler\n});\nmodule.exports = __toCommonJS(stdin_exports);\nconst hello = \"world\";\nfunction handler() {\n console.log(hello);\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n handler\n});\n" 145 | }, 146 | "Role": { 147 | "Fn::GetAtt": [ 148 | "InlineFunctionServiceRole8084C553", 149 | "Arn" 150 | ] 151 | }, 152 | "Handler": "index.handler", 153 | "Runtime": "nodejs16.x" 154 | }, 155 | "DependsOn": [ 156 | "InlineFunctionServiceRole8084C553" 157 | ] 158 | } 159 | }, 160 | "Parameters": { 161 | "BootstrapVersion": { 162 | "Type": "AWS::SSM::Parameter::Value", 163 | "Default": "/cdk-bootstrap/hnb659fds/version", 164 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 165 | } 166 | }, 167 | "Rules": { 168 | "CheckBootstrapVersion": { 169 | "Assertions": [ 170 | { 171 | "Assert": { 172 | "Fn::Not": [ 173 | { 174 | "Fn::Contains": [ 175 | [ 176 | "1", 177 | "2", 178 | "3", 179 | "4", 180 | "5" 181 | ], 182 | { 183 | "Ref": "BootstrapVersion" 184 | } 185 | ] 186 | } 187 | ] 188 | }, 189 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 190 | } 191 | ] 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLangDefaultTestDeployAssertA629E612.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "8f0c571812657f9654505faac7869bb410c192d7feba2ed7246fcb86f64e36e0": { 5 | "source": { 6 | "path": "asset.8f0c571812657f9654505faac7869bb410c192d7feba2ed7246fcb86f64e36e0.bundle", 7 | "packaging": "zip" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "8f0c571812657f9654505faac7869bb410c192d7feba2ed7246fcb86f64e36e0.zip", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | }, 17 | "44abbd893206dfd50f2af0eb1eafe8e25656e214e8c776cc21e7f449537a4ad2": { 18 | "source": { 19 | "path": "GoLangDefaultTestDeployAssertA629E612.template.json", 20 | "packaging": "file" 21 | }, 22 | "destinations": { 23 | "current_account-current_region": { 24 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 25 | "objectKey": "44abbd893206dfd50f2af0eb1eafe8e25656e214e8c776cc21e7f449537a4ad2.json", 26 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 27 | } 28 | } 29 | } 30 | }, 31 | "dockerImages": {} 32 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLangDefaultTestDeployAssertA629E612.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "AwsApiCallSQSgetQueueAttributes": { 4 | "Type": "Custom::DeployAssert@SdkCallSQSgetQueueAttributes", 5 | "Properties": { 6 | "ServiceToken": { 7 | "Fn::GetAtt": [ 8 | "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", 9 | "Arn" 10 | ] 11 | }, 12 | "service": "SQS", 13 | "api": "getQueueAttributes", 14 | "expected": "{\"$StringLike\":\".*\\\\.fifo$\"}", 15 | "actualPath": "Attributes.QueueArn", 16 | "parameters": { 17 | "QueueUrl": { 18 | "Fn::ImportValue": "GoLangStack:ExportsOutputRefQueue4A7E3555425E8BD3" 19 | }, 20 | "AttributeNames": [ 21 | "QueueArn" 22 | ] 23 | }, 24 | "flattenResponse": "true", 25 | "outputPaths": [ 26 | "Attributes.QueueArn" 27 | ], 28 | "salt": "1673208672764" 29 | }, 30 | "UpdateReplacePolicy": "Delete", 31 | "DeletionPolicy": "Delete" 32 | }, 33 | "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": { 34 | "Type": "AWS::IAM::Role", 35 | "Properties": { 36 | "AssumeRolePolicyDocument": { 37 | "Version": "2012-10-17", 38 | "Statement": [ 39 | { 40 | "Action": "sts:AssumeRole", 41 | "Effect": "Allow", 42 | "Principal": { 43 | "Service": "lambda.amazonaws.com" 44 | } 45 | } 46 | ] 47 | }, 48 | "ManagedPolicyArns": [ 49 | { 50 | "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 51 | } 52 | ], 53 | "Policies": [ 54 | { 55 | "PolicyName": "Inline", 56 | "PolicyDocument": { 57 | "Version": "2012-10-17", 58 | "Statement": [ 59 | { 60 | "Action": [ 61 | "sqs:GetQueueAttributes" 62 | ], 63 | "Effect": "Allow", 64 | "Resource": [ 65 | "*" 66 | ] 67 | } 68 | ] 69 | } 70 | } 71 | ] 72 | } 73 | }, 74 | "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": { 75 | "Type": "AWS::Lambda::Function", 76 | "Properties": { 77 | "Runtime": "nodejs14.x", 78 | "Code": { 79 | "S3Bucket": { 80 | "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" 81 | }, 82 | "S3Key": "8f0c571812657f9654505faac7869bb410c192d7feba2ed7246fcb86f64e36e0.zip" 83 | }, 84 | "Timeout": 120, 85 | "Handler": "index.handler", 86 | "Role": { 87 | "Fn::GetAtt": [ 88 | "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", 89 | "Arn" 90 | ] 91 | } 92 | } 93 | } 94 | }, 95 | "Outputs": { 96 | "AssertionResultsAwsApiCallSQSgetQueueAttributes": { 97 | "Value": { 98 | "Fn::GetAtt": [ 99 | "AwsApiCallSQSgetQueueAttributes", 100 | "assertion" 101 | ] 102 | } 103 | } 104 | }, 105 | "Parameters": { 106 | "BootstrapVersion": { 107 | "Type": "AWS::SSM::Parameter::Value", 108 | "Default": "/cdk-bootstrap/hnb659fds/version", 109 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 110 | } 111 | }, 112 | "Rules": { 113 | "CheckBootstrapVersion": { 114 | "Assertions": [ 115 | { 116 | "Assert": { 117 | "Fn::Not": [ 118 | { 119 | "Fn::Contains": [ 120 | [ 121 | "1", 122 | "2", 123 | "3", 124 | "4", 125 | "5" 126 | ], 127 | { 128 | "Ref": "BootstrapVersion" 129 | } 130 | ] 131 | } 132 | ] 133 | }, 134 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 135 | } 136 | ] 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLangStack.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "files": { 4 | "cdf94bfd1a3da2b2708c1e970f501fd2aec8dffea45b036ee1f42e20f5081015": { 5 | "source": { 6 | "path": "GoLangStack.template.json", 7 | "packaging": "file" 8 | }, 9 | "destinations": { 10 | "current_account-current_region": { 11 | "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", 12 | "objectKey": "cdf94bfd1a3da2b2708c1e970f501fd2aec8dffea45b036ee1f42e20f5081015.json", 13 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" 14 | } 15 | } 16 | } 17 | }, 18 | "dockerImages": {} 19 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/GoLangStack.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Resources": { 3 | "Queue4A7E3555": { 4 | "Type": "AWS::SQS::Queue", 5 | "Properties": { 6 | "FifoQueue": true 7 | }, 8 | "UpdateReplacePolicy": "Delete", 9 | "DeletionPolicy": "Delete" 10 | } 11 | }, 12 | "Outputs": { 13 | "ExportsOutputRefQueue4A7E3555425E8BD3": { 14 | "Value": { 15 | "Ref": "Queue4A7E3555" 16 | }, 17 | "Export": { 18 | "Name": "GoLangStack:ExportsOutputRefQueue4A7E3555425E8BD3" 19 | } 20 | } 21 | }, 22 | "Parameters": { 23 | "BootstrapVersion": { 24 | "Type": "AWS::SSM::Parameter::Value", 25 | "Default": "/cdk-bootstrap/hnb659fds/version", 26 | "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" 27 | } 28 | }, 29 | "Rules": { 30 | "CheckBootstrapVersion": { 31 | "Assertions": [ 32 | { 33 | "Assert": { 34 | "Fn::Not": [ 35 | { 36 | "Fn::Contains": [ 37 | [ 38 | "1", 39 | "2", 40 | "3", 41 | "4", 42 | "5" 43 | ], 44 | { 45 | "Ref": "BootstrapVersion" 46 | } 47 | ] 48 | } 49 | ] 50 | }, 51 | "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." 52 | } 53 | ] 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.6877b7d4626f48a6cbebe7b4b7dede1761bef6c4c3ec1ea03d0dd6e8301212f9/index.mjs: -------------------------------------------------------------------------------- 1 | // ../fixtures/handlers/colors.ts 2 | var handler = async (favorites) => { 3 | return `My favorite colour is ${favorites.colour}, I always like to eat some ${favorites.food} and ${favorites.season} is the best time of the year.`; 4 | }; 5 | export { 6 | handler 7 | }; 8 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/colors.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // ../fixtures/handlers/colors.ts 21 | var colors_exports = {}; 22 | __export(colors_exports, { 23 | handler: () => handler 24 | }); 25 | module.exports = __toCommonJS(colors_exports); 26 | var handler = async (favorites) => { 27 | return `My favorite colour is ${favorites.colour}, I always like to eat some ${favorites.food} and ${favorites.season} is the best time of the year.`; 28 | }; 29 | // Annotate the CommonJS export names for ESM import in node: 30 | 0 && (module.exports = { 31 | handler 32 | }); 33 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/colors.ts: -------------------------------------------------------------------------------- 1 | interface Favorites { 2 | colour: string; 3 | food: string; 4 | season: string; 5 | } 6 | 7 | export const handler = async (favorites: Favorites) => { 8 | return ( 9 | `My favorite colour is ${favorites.colour}, ` + 10 | `I always like to eat some ${favorites.food} and ` + 11 | `${favorites.season} is the best time of the year.` 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/invalid-handler.js: -------------------------------------------------------------------------------- 1 | import { invalid } from './util'; 2 | 3 | export async function handler(): Promisevoid> { 4 | consoe.lmult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/js-handler.js: -------------------------------------------------------------------------------- 1 | import { add } from './util'; 2 | 3 | export async function handler() { 4 | console.log(add(1, 2)); 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/ts-handler.ts: -------------------------------------------------------------------------------- 1 | import { mult } from './util'; 2 | 3 | export async function handler(): Promise { 4 | console.log(mult(3, 4)); // eslint-disable-line no-console 5 | } 6 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/asset.dd0163817ea2933593cd66b107092d6f6005e66e7d2fbc0a876b3eb86cd3d3a8/util.ts: -------------------------------------------------------------------------------- 1 | export function add(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | export function mult(a: number, b: number): number { 6 | return a * b; 7 | } 8 | -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/integ.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "testCases": { 4 | "GoLambdaFunctions/DefaultTest": { 5 | "stacks": [ 6 | "GoLambdaStack" 7 | ], 8 | "assertionStack": "GoLambdaFunctions/DefaultTest/DeployAssert", 9 | "assertionStackName": "GoLambdaFunctionsDefaultTestDeployAssert141E9B32" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/integ/integ_lambda.go.snapshot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "22.0.0", 3 | "artifacts": { 4 | "GoLambdaStack.assets": { 5 | "type": "cdk:asset-manifest", 6 | "properties": { 7 | "file": "GoLambdaStack.assets.json", 8 | "requiresBootstrapStackVersion": 6, 9 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 10 | } 11 | }, 12 | "GoLambdaStack": { 13 | "type": "aws:cloudformation:stack", 14 | "environment": "aws://unknown-account/unknown-region", 15 | "properties": { 16 | "templateFile": "GoLambdaStack.template.json", 17 | "validateOnSynth": false, 18 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", 19 | "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", 20 | "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/343e9c46db14f6615084d05b8cb1f8bc81ffaaf6dd17b31763cf9dcac5f73eba.json", 21 | "requiresBootstrapStackVersion": 6, 22 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", 23 | "additionalDependencies": [ 24 | "GoLambdaStack.assets" 25 | ], 26 | "lookupRole": { 27 | "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", 28 | "requiresBootstrapStackVersion": 8, 29 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 30 | } 31 | }, 32 | "dependencies": [ 33 | "GoLambdaStack.assets" 34 | ], 35 | "metadata": { 36 | "/GoLambdaStack/FunctionOne/ServiceRole/Resource": [ 37 | { 38 | "type": "aws:cdk:logicalId", 39 | "data": "FunctionOneServiceRoleB0F6870D" 40 | } 41 | ], 42 | "/GoLambdaStack/FunctionOne/Resource": [ 43 | { 44 | "type": "aws:cdk:logicalId", 45 | "data": "FunctionOne8A86801F" 46 | } 47 | ], 48 | "/GoLambdaStack/FunctionTwo/ServiceRole/Resource": [ 49 | { 50 | "type": "aws:cdk:logicalId", 51 | "data": "FunctionTwoServiceRoleF26DAB39" 52 | } 53 | ], 54 | "/GoLambdaStack/FunctionTwo/Resource": [ 55 | { 56 | "type": "aws:cdk:logicalId", 57 | "data": "FunctionTwoDAB66576" 58 | } 59 | ], 60 | "/GoLambdaStack/InlineFunction/ServiceRole/Resource": [ 61 | { 62 | "type": "aws:cdk:logicalId", 63 | "data": "InlineFunctionServiceRole8084C553" 64 | } 65 | ], 66 | "/GoLambdaStack/InlineFunction/Resource": [ 67 | { 68 | "type": "aws:cdk:logicalId", 69 | "data": "InlineFunction18B48CA2" 70 | } 71 | ], 72 | "/GoLambdaStack/BootstrapVersion": [ 73 | { 74 | "type": "aws:cdk:logicalId", 75 | "data": "BootstrapVersion" 76 | } 77 | ], 78 | "/GoLambdaStack/CheckBootstrapVersion": [ 79 | { 80 | "type": "aws:cdk:logicalId", 81 | "data": "CheckBootstrapVersion" 82 | } 83 | ] 84 | }, 85 | "displayName": "GoLambdaStack" 86 | }, 87 | "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets": { 88 | "type": "cdk:asset-manifest", 89 | "properties": { 90 | "file": "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets.json", 91 | "requiresBootstrapStackVersion": 6, 92 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 93 | } 94 | }, 95 | "GoLambdaFunctionsDefaultTestDeployAssert141E9B32": { 96 | "type": "aws:cloudformation:stack", 97 | "environment": "aws://unknown-account/unknown-region", 98 | "properties": { 99 | "templateFile": "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.template.json", 100 | "validateOnSynth": false, 101 | "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", 102 | "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", 103 | "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", 104 | "requiresBootstrapStackVersion": 6, 105 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", 106 | "additionalDependencies": [ 107 | "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets" 108 | ], 109 | "lookupRole": { 110 | "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", 111 | "requiresBootstrapStackVersion": 8, 112 | "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" 113 | } 114 | }, 115 | "dependencies": [ 116 | "GoLambdaFunctionsDefaultTestDeployAssert141E9B32.assets" 117 | ], 118 | "metadata": { 119 | "/GoLambdaFunctions/DefaultTest/DeployAssert/BootstrapVersion": [ 120 | { 121 | "type": "aws:cdk:logicalId", 122 | "data": "BootstrapVersion" 123 | } 124 | ], 125 | "/GoLambdaFunctions/DefaultTest/DeployAssert/CheckBootstrapVersion": [ 126 | { 127 | "type": "aws:cdk:logicalId", 128 | "data": "CheckBootstrapVersion" 129 | } 130 | ] 131 | }, 132 | "displayName": "GoLambdaFunctions/DefaultTest/DeployAssert" 133 | }, 134 | "Tree": { 135 | "type": "cdk:tree", 136 | "properties": { 137 | "file": "tree.json" 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "compilerOptions": { 4 | "alwaysStrict": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "inlineSourceMap": true, 9 | "inlineSources": true, 10 | "lib": [ 11 | "es2020" 12 | ], 13 | "module": "CommonJS", 14 | "noEmitOnError": false, 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noImplicitThis": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "resolveJsonModule": true, 22 | "strict": true, 23 | "strictNullChecks": true, 24 | "strictPropertyInitialization": true, 25 | "stripInternal": true, 26 | "target": "ES2020" 27 | }, 28 | "include": [ 29 | "src/**/*.ts", 30 | "test/**/*.ts", 31 | ".projenrc.ts", 32 | "projenrc/**/*.ts" 33 | ], 34 | "exclude": [ 35 | "node_modules" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "rootDir": "src", 5 | "declarationMap": false, 6 | "inlineSourceMap": true, 7 | "inlineSources": true, 8 | "alwaysStrict": true, 9 | "declaration": true, 10 | "incremental": true, 11 | "lib": [ 12 | "es2020" 13 | ], 14 | "module": "commonjs", 15 | "noEmitOnError": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "noImplicitAny": true, 18 | "noImplicitReturns": true, 19 | "noImplicitThis": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "resolveJsonModule": true, 23 | "skipLibCheck": true, 24 | "strict": true, 25 | "strictNullChecks": true, 26 | "strictPropertyInitialization": true, 27 | "stripInternal": false, 28 | "target": "es2020", 29 | "composite": false, 30 | "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo" 31 | }, 32 | "include": [ 33 | "src/**/*.ts" 34 | ], 35 | "exclude": [ 36 | "node_modules" 37 | ], 38 | "_generated_by_jsii_": "Generated by jsii - safe to delete, and ideally should be in .gitignore" 39 | } --------------------------------------------------------------------------------