├── .eslintrc.json ├── .github ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .mergify.yml ├── .npmignore ├── .npmrc ├── .projen ├── deps.json └── tasks.json ├── .projenrc.js ├── .versionrc.json ├── API.md ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets └── successful-projen-action-run.png ├── lambda-js └── index.js ├── lambda-python └── index.py ├── package.json ├── src ├── ConstructWithProperties.ts ├── LambdaConstruct.ts ├── index.ts ├── lambda-bundled │ └── index.js └── lambda │ └── index.ts ├── test └── index.test.ts ├── tsconfig.eslint.json ├── tsconfig.jest.json ├── version.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true, 4 | "node": true 5 | }, 6 | "root": true, 7 | "plugins": [ 8 | "@typescript-eslint", 9 | "import" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "ecmaVersion": 2018, 14 | "sourceType": "module", 15 | "project": "./tsconfig.eslint.json" 16 | }, 17 | "extends": [ 18 | "plugin:import/typescript" 19 | ], 20 | "settings": { 21 | "import/parsers": { 22 | "@typescript-eslint/parser": [ 23 | ".ts", 24 | ".tsx" 25 | ] 26 | }, 27 | "import/resolver": { 28 | "node": {}, 29 | "typescript": { 30 | "project": "./tsconfig.eslint.json" 31 | } 32 | } 33 | }, 34 | "ignorePatterns": [ 35 | "*.js", 36 | "!.projenrc.js", 37 | "*.d.ts", 38 | "node_modules/", 39 | "*.generated.ts", 40 | "coverage" 41 | ], 42 | "rules": { 43 | "@typescript-eslint/no-require-imports": [ 44 | "error" 45 | ], 46 | "indent": [ 47 | "off" 48 | ], 49 | "@typescript-eslint/indent": [ 50 | "error", 51 | 2 52 | ], 53 | "quotes": [ 54 | "error", 55 | "single", 56 | { 57 | "avoidEscape": true 58 | } 59 | ], 60 | "comma-dangle": [ 61 | "error", 62 | "always-multiline" 63 | ], 64 | "comma-spacing": [ 65 | "error", 66 | { 67 | "before": false, 68 | "after": true 69 | } 70 | ], 71 | "no-multi-spaces": [ 72 | "error", 73 | { 74 | "ignoreEOLComments": false 75 | } 76 | ], 77 | "array-bracket-spacing": [ 78 | "error", 79 | "never" 80 | ], 81 | "array-bracket-newline": [ 82 | "error", 83 | "consistent" 84 | ], 85 | "object-curly-spacing": [ 86 | "error", 87 | "always" 88 | ], 89 | "object-curly-newline": [ 90 | "error", 91 | { 92 | "multiline": true, 93 | "consistent": true 94 | } 95 | ], 96 | "object-property-newline": [ 97 | "error", 98 | { 99 | "allowAllPropertiesOnSameLine": true 100 | } 101 | ], 102 | "keyword-spacing": [ 103 | "error" 104 | ], 105 | "brace-style": [ 106 | "error", 107 | "1tbs", 108 | { 109 | "allowSingleLine": true 110 | } 111 | ], 112 | "space-before-blocks": [ 113 | "error" 114 | ], 115 | "curly": [ 116 | "error", 117 | "multi-line", 118 | "consistent" 119 | ], 120 | "@typescript-eslint/member-delimiter-style": [ 121 | "error" 122 | ], 123 | "import/no-extraneous-dependencies": [ 124 | "error", 125 | { 126 | "devDependencies": [ 127 | "**/test/**", 128 | "**/build-tools/**" 129 | ], 130 | "optionalDependencies": false, 131 | "peerDependencies": true 132 | } 133 | ], 134 | "import/no-unresolved": [ 135 | "error" 136 | ], 137 | "import/order": [ 138 | "warn", 139 | { 140 | "groups": [ 141 | "builtin", 142 | "external" 143 | ], 144 | "alphabetize": { 145 | "order": "asc", 146 | "caseInsensitive": true 147 | } 148 | } 149 | ], 150 | "no-duplicate-imports": [ 151 | "error" 152 | ], 153 | "no-shadow": [ 154 | "off" 155 | ], 156 | "@typescript-eslint/no-shadow": [ 157 | "error" 158 | ], 159 | "key-spacing": [ 160 | "error" 161 | ], 162 | "semi": [ 163 | "error", 164 | "always" 165 | ], 166 | "quote-props": [ 167 | "error", 168 | "consistent-as-needed" 169 | ], 170 | "no-multiple-empty-lines": [ 171 | "error" 172 | ], 173 | "max-len": [ 174 | "error", 175 | { 176 | "code": 150, 177 | "ignoreUrls": true, 178 | "ignoreStrings": true, 179 | "ignoreTemplateLiterals": true, 180 | "ignoreComments": true, 181 | "ignoreRegExpLiterals": true 182 | } 183 | ], 184 | "@typescript-eslint/no-floating-promises": [ 185 | "error" 186 | ], 187 | "no-return-await": [ 188 | "off" 189 | ], 190 | "@typescript-eslint/return-await": [ 191 | "error" 192 | ], 193 | "no-trailing-spaces": [ 194 | "error" 195 | ], 196 | "dot-notation": [ 197 | "error" 198 | ], 199 | "no-bitwise": [ 200 | "error" 201 | ], 202 | "@typescript-eslint/member-ordering": [ 203 | "error", 204 | { 205 | "default": [ 206 | "public-static-field", 207 | "public-static-method", 208 | "protected-static-field", 209 | "protected-static-method", 210 | "private-static-field", 211 | "private-static-method", 212 | "field", 213 | "constructor", 214 | "method" 215 | ] 216 | } 217 | ] 218 | }, 219 | "overrides": [ 220 | { 221 | "files": [ 222 | ".projenrc.js" 223 | ], 224 | "rules": { 225 | "@typescript-eslint/no-require-imports": "off", 226 | "import/no-extraneous-dependencies": "off" 227 | } 228 | } 229 | ] 230 | } 231 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: npm 6 | versioning-strategy: lockfile-only 7 | directory: / 8 | schedule: 9 | interval: weekly 10 | ignore: 11 | - dependency-name: projen 12 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: Build 4 | on: 5 | pull_request: {} 6 | workflow_dispatch: {} 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | env: 11 | CI: "true" 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | with: 16 | ref: ${{ github.event.pull_request.head.ref }} 17 | repository: ${{ github.event.pull_request.head.repo.full_name }} 18 | - name: Install dependencies 19 | run: yarn install --check-files --frozen-lockfile 20 | - name: Set git identity 21 | run: |- 22 | git config user.name "Auto-bump" 23 | git config user.email "github-actions@github.com" 24 | - name: Build 25 | run: npx projen build 26 | - name: Commit and push changes (if any) 27 | run: 'git diff --exit-code || (git commit -am "chore: self mutation" && git push 28 | origin HEAD:${{ github.event.pull_request.head.ref }})' 29 | container: 30 | image: jsii/superchain 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | name: Release 4 | on: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: {} 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | env: 13 | CI: "true" 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | - name: Install dependencies 20 | run: yarn install --check-files --frozen-lockfile 21 | - name: Anti-tamper check 22 | run: git diff --exit-code 23 | - name: Set git identity 24 | run: |- 25 | git config user.name "Auto-bump" 26 | git config user.email "github-actions@github.com" 27 | - name: Bump to next version 28 | run: npx projen bump 29 | - name: Build 30 | run: npx projen build 31 | - name: Anti-tamper check 32 | run: git diff --exit-code 33 | - name: Push commits 34 | run: git push origin HEAD:${{ github.ref }} 35 | - name: Push tags 36 | run: git push --follow-tags origin ${{ github.ref }} 37 | - name: Upload artifact 38 | uses: actions/upload-artifact@v2.1.1 39 | with: 40 | name: dist 41 | path: dist 42 | container: 43 | image: jsii/superchain 44 | release_npm: 45 | name: Release to NPM 46 | needs: build 47 | runs-on: ubuntu-latest 48 | container: 49 | image: jsii/superchain 50 | steps: 51 | - name: Download build artifacts 52 | uses: actions/download-artifact@v2 53 | with: 54 | name: dist 55 | path: dist 56 | - name: Release 57 | run: npx -p jsii-release@latest jsii-release-npm 58 | env: 59 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 60 | NPM_DIST_TAG: latest 61 | NPM_REGISTRY: registry.npmjs.org 62 | release_maven: 63 | name: Release to Maven 64 | needs: build 65 | runs-on: ubuntu-latest 66 | container: 67 | image: jsii/superchain 68 | steps: 69 | - name: Download build artifacts 70 | uses: actions/download-artifact@v2 71 | with: 72 | name: dist 73 | path: dist 74 | - name: Release 75 | run: npx -p jsii-release@latest jsii-release-maven 76 | env: 77 | MAVEN_GPG_PRIVATE_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 78 | MAVEN_GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.MAVEN_GPG_PRIVATE_KEY_PASSPHRASE }} 79 | MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} 80 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 81 | MAVEN_STAGING_PROFILE_ID: ${{ secrets.MAVEN_STAGING_PROFILE_ID }} 82 | release_pypi: 83 | name: Release to PyPi 84 | needs: build 85 | runs-on: ubuntu-latest 86 | container: 87 | image: jsii/superchain 88 | steps: 89 | - name: Download build artifacts 90 | uses: actions/download-artifact@v2 91 | with: 92 | name: dist 93 | path: dist 94 | - name: Release 95 | run: npx -p jsii-release@latest jsii-release-pypi 96 | env: 97 | TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} 98 | TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} 99 | release_nuget: 100 | name: Release to Nuget 101 | needs: build 102 | runs-on: ubuntu-latest 103 | container: 104 | image: jsii/superchain 105 | steps: 106 | - name: Download build artifacts 107 | uses: actions/download-artifact@v2 108 | with: 109 | name: dist 110 | path: dist 111 | - name: Release 112 | run: npx -p jsii-release@latest jsii-release-nuget 113 | env: 114 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} 115 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | *.lcov 3 | *.log 4 | *.pid 5 | *.pid.lock 6 | *.seed 7 | *.tgz 8 | *.tsbuildinfo 9 | .cache 10 | .eslintcache 11 | .idea 12 | .jsii 13 | .nyc_output 14 | .yarn-integrity 15 | /coverage 16 | /dist 17 | /lib 18 | /test-reports/ 19 | build/Release 20 | coverage 21 | jspm_packages/ 22 | junit.xml 23 | lerna-debug.log* 24 | lib-cov 25 | logs 26 | node_modules/ 27 | npm-debug.log* 28 | pids 29 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 30 | tsconfig.json 31 | yarn-debug.log* 32 | yarn-error.log* 33 | !/.eslintrc.json 34 | !/.github/dependabot.yml 35 | !/.github/pull_request_template.md 36 | !/.github/workflows/build.yml 37 | !/.github/workflows/release.yml 38 | !/.mergify.yml 39 | !/.npmignore 40 | !/.projen/deps.json 41 | !/.projen/tasks.json 42 | !/.projenrc.js 43 | !/.versionrc.json 44 | !/API.md 45 | !/LICENSE 46 | !/package.json 47 | !/src 48 | !/test 49 | !/tsconfig.eslint.json 50 | !/tsconfig.jest.json 51 | !version.json 52 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | 3 | pull_request_rules: 4 | - name: Automatic merge on approval and successful build 5 | actions: 6 | merge: 7 | method: squash 8 | commit_message: title+body 9 | strict: smart 10 | strict_method: merge 11 | delete_head_branch: {} 12 | conditions: 13 | - "#approved-reviews-by>=1" 14 | - status-success=build 15 | - name: Automatic merge PRs with auto-merge label upon successful build 16 | actions: 17 | merge: 18 | method: squash 19 | commit_message: title+body 20 | strict: smart 21 | strict_method: merge 22 | delete_head_branch: {} 23 | conditions: 24 | - label=auto-merge 25 | - status-success=build 26 | - name: Merge pull requests from dependabot if CI passes 27 | conditions: 28 | - author=dependabot[bot] 29 | - status-success=build 30 | actions: 31 | merge: 32 | method: squash 33 | commit_message: title+body 34 | strict: smart 35 | strict_method: merge 36 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". 2 | /.eslintrc.json 3 | /.github 4 | /.idea 5 | /.mergify.yml 6 | /.projen 7 | /.projenrc.js 8 | /.versionrc.json 9 | /.vscode 10 | /coverage 11 | /src 12 | /test 13 | /test-reports/ 14 | /tsconfig.eslint.json 15 | /tsconfig.jest.json 16 | /tsconfig.json 17 | dist 18 | junit.xml 19 | !.jsii 20 | !/lib 21 | !/lib/**/*.d.ts 22 | !/lib/**/*.js 23 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.projen/deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "@aws-cdk/assert", 5 | "version": "^1.97.0", 6 | "type": "build" 7 | }, 8 | { 9 | "name": "@types/jest", 10 | "type": "build" 11 | }, 12 | { 13 | "name": "@types/node", 14 | "version": "^10.17.0", 15 | "type": "build" 16 | }, 17 | { 18 | "name": "@typescript-eslint/eslint-plugin", 19 | "type": "build" 20 | }, 21 | { 22 | "name": "@typescript-eslint/parser", 23 | "type": "build" 24 | }, 25 | { 26 | "name": "esbuild", 27 | "type": "build" 28 | }, 29 | { 30 | "name": "eslint", 31 | "type": "build" 32 | }, 33 | { 34 | "name": "eslint-import-resolver-node", 35 | "type": "build" 36 | }, 37 | { 38 | "name": "eslint-import-resolver-typescript", 39 | "type": "build" 40 | }, 41 | { 42 | "name": "eslint-plugin-import", 43 | "type": "build" 44 | }, 45 | { 46 | "name": "jest", 47 | "type": "build" 48 | }, 49 | { 50 | "name": "jest-junit", 51 | "version": "^12", 52 | "type": "build" 53 | }, 54 | { 55 | "name": "jsii", 56 | "type": "build" 57 | }, 58 | { 59 | "name": "jsii-diff", 60 | "type": "build" 61 | }, 62 | { 63 | "name": "jsii-docgen", 64 | "type": "build" 65 | }, 66 | { 67 | "name": "jsii-pacmak", 68 | "type": "build" 69 | }, 70 | { 71 | "name": "json-schema", 72 | "type": "build" 73 | }, 74 | { 75 | "name": "projen", 76 | "version": "^0.17.31", 77 | "type": "build" 78 | }, 79 | { 80 | "name": "standard-version", 81 | "version": "^9", 82 | "type": "build" 83 | }, 84 | { 85 | "name": "ts-jest", 86 | "type": "build" 87 | }, 88 | { 89 | "name": "typedoc", 90 | "type": "build" 91 | }, 92 | { 93 | "name": "typescript", 94 | "type": "build" 95 | }, 96 | { 97 | "name": "@aws-cdk/aws-lambda", 98 | "version": "^1.97.0", 99 | "type": "peer" 100 | }, 101 | { 102 | "name": "@aws-cdk/core", 103 | "version": "^1.97.0", 104 | "type": "peer" 105 | }, 106 | { 107 | "name": "constructs", 108 | "version": "^3.2.27", 109 | "type": "peer" 110 | }, 111 | { 112 | "name": "@aws-cdk/aws-lambda", 113 | "version": "^1.97.0", 114 | "type": "runtime" 115 | }, 116 | { 117 | "name": "@aws-cdk/core", 118 | "version": "^1.97.0", 119 | "type": "runtime" 120 | } 121 | ], 122 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 123 | } 124 | -------------------------------------------------------------------------------- /.projen/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "clobber": { 4 | "name": "clobber", 5 | "category": "30.maintain", 6 | "description": "hard resets to HEAD of origin and cleans the local repo", 7 | "env": { 8 | "BRANCH": "$(git branch --show-current)" 9 | }, 10 | "steps": [ 11 | { 12 | "exec": "git checkout -b scratch", 13 | "name": "save current HEAD in \"scratch\" branch" 14 | }, 15 | { 16 | "exec": "git checkout $BRANCH" 17 | }, 18 | { 19 | "exec": "git fetch origin", 20 | "name": "fetch latest changes from origin" 21 | }, 22 | { 23 | "exec": "git reset --hard origin/$BRANCH", 24 | "name": "hard reset to origin commit" 25 | }, 26 | { 27 | "exec": "git clean -fdx", 28 | "name": "clean all untracked files" 29 | }, 30 | { 31 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)" 32 | } 33 | ], 34 | "condition": "git diff --exit-code > /dev/null" 35 | }, 36 | "compile": { 37 | "name": "compile", 38 | "category": "00.build", 39 | "description": "Only compile", 40 | "steps": [ 41 | { 42 | "exec": "jsii --silence-warnings=reserved-word --no-fix-peer-dependencies" 43 | }, 44 | { 45 | "spawn": "docgen" 46 | }, 47 | { 48 | "exec": "esbuild src/lambda-bundled/index.js --bundle --platform=node --target=node12 --external:aws-sdk --outfile=lib/lambda-bundled/index.js" 49 | } 50 | ] 51 | }, 52 | "test:compile": { 53 | "name": "test:compile", 54 | "category": "10.test", 55 | "description": "compiles the test code", 56 | "steps": [ 57 | { 58 | "exec": "tsc --noEmit --project tsconfig.jest.json" 59 | } 60 | ] 61 | }, 62 | "test": { 63 | "name": "test", 64 | "category": "10.test", 65 | "description": "Run tests", 66 | "steps": [ 67 | { 68 | "exec": "rm -fr lib/" 69 | }, 70 | { 71 | "spawn": "test:compile" 72 | }, 73 | { 74 | "exec": "jest --passWithNoTests --all --updateSnapshot" 75 | }, 76 | { 77 | "spawn": "eslint" 78 | } 79 | ] 80 | }, 81 | "build": { 82 | "name": "build", 83 | "category": "00.build", 84 | "description": "Full release build (test+compile)", 85 | "steps": [ 86 | { 87 | "exec": "npx projen" 88 | }, 89 | { 90 | "spawn": "test" 91 | }, 92 | { 93 | "spawn": "compile" 94 | }, 95 | { 96 | "spawn": "package" 97 | }, 98 | { 99 | "spawn": "docgen" 100 | } 101 | ] 102 | }, 103 | "bump": { 104 | "name": "bump", 105 | "category": "20.release", 106 | "description": "Commits a bump to the package version based on conventional commits", 107 | "steps": [ 108 | { 109 | "exec": "standard-version" 110 | } 111 | ], 112 | "condition": "! git log --oneline -1 | grep -q \"chore(release):\"" 113 | }, 114 | "release": { 115 | "name": "release", 116 | "category": "20.release", 117 | "description": "Bumps version & push to main", 118 | "steps": [ 119 | { 120 | "spawn": "bump" 121 | }, 122 | { 123 | "exec": "git push --follow-tags origin main" 124 | } 125 | ], 126 | "condition": "! git log --oneline -1 | grep -q \"chore(release):\"" 127 | }, 128 | "test:watch": { 129 | "name": "test:watch", 130 | "category": "10.test", 131 | "description": "Run jest in watch mode", 132 | "steps": [ 133 | { 134 | "exec": "jest --watch" 135 | } 136 | ] 137 | }, 138 | "test:update": { 139 | "name": "test:update", 140 | "category": "10.test", 141 | "description": "Update jest snapshots", 142 | "steps": [ 143 | { 144 | "exec": "jest --updateSnapshot" 145 | } 146 | ] 147 | }, 148 | "projen:upgrade": { 149 | "name": "projen:upgrade", 150 | "category": "30.maintain", 151 | "description": "upgrades projen to the latest version", 152 | "steps": [ 153 | { 154 | "exec": "yarn upgrade -L projen" 155 | }, 156 | { 157 | "exec": "CI=\"\" yarn projen" 158 | } 159 | ] 160 | }, 161 | "watch": { 162 | "name": "watch", 163 | "category": "00.build", 164 | "description": "Watch & compile in the background", 165 | "steps": [ 166 | { 167 | "exec": "jsii -w --silence-warnings=reserved-word --no-fix-peer-dependencies" 168 | } 169 | ] 170 | }, 171 | "package": { 172 | "name": "package", 173 | "category": "20.release", 174 | "description": "Create an npm tarball", 175 | "steps": [ 176 | { 177 | "exec": "jsii-pacmak" 178 | } 179 | ] 180 | }, 181 | "eslint": { 182 | "name": "eslint", 183 | "category": "10.test", 184 | "description": "Runs eslint against the codebase", 185 | "steps": [ 186 | { 187 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js" 188 | } 189 | ] 190 | }, 191 | "docgen": { 192 | "name": "docgen", 193 | "category": "20.release", 194 | "description": "Generate API.md from .jsii manifest", 195 | "steps": [ 196 | { 197 | "exec": "jsii-docgen" 198 | } 199 | ] 200 | }, 201 | "compat": { 202 | "name": "compat", 203 | "category": "20.release", 204 | "description": "Perform API compatibility check against latest version", 205 | "steps": [ 206 | { 207 | "exec": "jsii-diff npm:$(node -p \"require('./package.json').name\") -k --ignore-file .compatignore || (echo \"\nUNEXPECTED BREAKING CHANGES: add keys such as 'removed:constructs.Node.of' to .compatignore to skip.\n\" && exit 1)" 208 | } 209 | ] 210 | } 211 | }, 212 | "env": { 213 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")" 214 | }, 215 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 216 | } 217 | -------------------------------------------------------------------------------- /.projenrc.js: -------------------------------------------------------------------------------- 1 | const { NpmAccess } = require('projen'); 2 | const { ProjectType } = require('projen'); 3 | const { AwsCdkConstructLibrary } = require('projen'); 4 | const { DependabotScheduleInterval } = require('projen/lib/github'); 5 | 6 | const project = new AwsCdkConstructLibrary({ 7 | name: '@seeebiii/projen-test', 8 | repositoryUrl: 'https://github.com/seeebiii/projen-test', 9 | author: 'seeebiii', 10 | authorName: 'Sebastian Hesse', 11 | authorAddress: 'https://www.sebastianhesse.de', 12 | jsiiFqn: 'projen.AwsCdkConstructLibrary', 13 | 14 | cdkVersion: '1.97.0', 15 | cdkAssert: true, 16 | cdkDependencies: ['@aws-cdk/core', '@aws-cdk/aws-lambda'], 17 | cdkVersionPinning: false, // see https://www.matthewbonig.com/2021/04/06/automating-construct-publishing/ 18 | 19 | devDeps: ['esbuild'], 20 | 21 | npmAccess: NpmAccess.PUBLIC, 22 | projectType: ProjectType.LIB, 23 | 24 | docgen: true, 25 | eslint: true, 26 | mergify: true, 27 | antitamper: true, 28 | 29 | dependabot: true, 30 | dependabotOptions: { 31 | autoMerge: true, 32 | ignoreProjen: true, 33 | scheduleInterval: DependabotScheduleInterval.WEEKLY, 34 | }, 35 | 36 | gitignore: ['.idea'], 37 | defaultReleaseBranch: 'main', 38 | releaseBranches: ['main'], 39 | releaseToNpm: true, 40 | releaseWorkflow: true, 41 | 42 | publishToMaven: { 43 | mavenGroupId: 'de.sebastianhesse.examples', 44 | mavenArtifactId: 'projen-test', 45 | javaPackage: 'de.sebastianhesse.examples.projen.test', 46 | }, 47 | publishToNuget: { 48 | dotNetNamespace: 'SebastianHesse.Examples', 49 | packageId: 'Projen.Test', 50 | }, 51 | publishToPypi: { 52 | distName: 'projen-test', 53 | module: 'projen_test', 54 | }, 55 | }); 56 | 57 | // example to show how you can use your own esbuild task to bundle your Lambda function without using constructs like NodejsFunction 58 | project.compileTask.exec('esbuild src/lambda-bundled/index.js --bundle --platform=node --target=node12 --external:aws-sdk --outfile=lib/lambda-bundled/index.js'); 59 | 60 | project.synth(); 61 | -------------------------------------------------------------------------------- /.versionrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageFiles": [ 3 | { 4 | "filename": "version.json", 5 | "type": "json" 6 | } 7 | ], 8 | "bumpFiles": [ 9 | { 10 | "filename": "version.json", 11 | "type": "json" 12 | } 13 | ], 14 | "commitAll": true, 15 | "scripts": { 16 | "postbump": "npx projen && git add ." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | **Classes** 4 | 5 | Name|Description 6 | ----|----------- 7 | [ConstructWithProperties](#seeebiii-projen-test-constructwithproperties)|A simple CDK construct illustrating the differences in declaring construct properties with interfaces. 8 | [LambdaConstruct](#seeebiii-projen-test-lambdaconstruct)|A CDK construct to create Lambda functions. 9 | 10 | 11 | **Structs** 12 | 13 | Name|Description 14 | ----|----------- 15 | [StructProperties](#seeebiii-projen-test-structproperties)|This interface is translated into a _struct_ containing data. 16 | 17 | 18 | **Interfaces** 19 | 20 | Name|Description 21 | ----|----------- 22 | [IBehaviorProperties](#seeebiii-projen-test-ibehaviorproperties)|This is a _behavioral interface_ identified by `I` in its name. 23 | 24 | 25 | 26 | ## class ConstructWithProperties 27 | 28 | A simple CDK construct illustrating the differences in declaring construct properties with interfaces. 29 | 30 | __Implements__: [IConstruct](#constructs-iconstruct), [IConstruct](#aws-cdk-core-iconstruct), [IConstruct](#constructs-iconstruct), [IDependable](#aws-cdk-core-idependable) 31 | __Extends__: [Construct](#aws-cdk-core-construct) 32 | 33 | ### Initializer 34 | 35 | 36 | 37 | 38 | ```ts 39 | new ConstructWithProperties(parent: Construct, name: string, props: StructProperties, props2: IBehaviorProperties) 40 | ``` 41 | 42 | * **parent** ([Construct](#aws-cdk-core-construct)) *No description* 43 | * **name** (string) *No description* 44 | * **props** ([StructProperties](#seeebiii-projen-test-structproperties)) *No description* 45 | * **props2** ([IBehaviorProperties](#seeebiii-projen-test-ibehaviorproperties)) *No description* 46 | 47 | 48 | 49 | 50 | ## class LambdaConstruct 51 | 52 | A CDK construct to create Lambda functions. 53 | 54 | __Implements__: [IConstruct](#constructs-iconstruct), [IConstruct](#aws-cdk-core-iconstruct), [IConstruct](#constructs-iconstruct), [IDependable](#aws-cdk-core-idependable) 55 | __Extends__: [Construct](#aws-cdk-core-construct) 56 | 57 | ### Initializer 58 | 59 | 60 | 61 | 62 | ```ts 63 | new LambdaConstruct(parent: Construct, name: string) 64 | ``` 65 | 66 | * **parent** ([Construct](#aws-cdk-core-construct)) *No description* 67 | * **name** (string) *No description* 68 | 69 | 70 | 71 | 72 | ## interface IBehaviorProperties 73 | 74 | 75 | This is a _behavioral interface_ identified by `I` in its name. 76 | 77 | It will be translated to a "regular" interface which needs to be implemented. 78 | You can also use methods here, e.g. `doSth(): void;`. 79 | 80 | ### Properties 81 | 82 | 83 | Name | Type | Description 84 | -----|------|------------- 85 | **otherProp** | string | 86 | 87 | 88 | 89 | ## struct StructProperties 90 | 91 | 92 | This interface is translated into a _struct_ containing data. 93 | 94 | E.g. if translated to Java, an interface `StructProperties` is created containing a builder subclass to create an instance of the interface. 95 | 96 | 97 | 98 | Name | Type | Description 99 | -----|------|------------- 100 | **myProp** | string | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.1.109](https://github.com/seeebiii/projen-test/compare/v0.1.108...v0.1.109) (2021-10-04) 6 | 7 | ### [0.1.108](https://github.com/seeebiii/projen-test/compare/v0.1.107...v0.1.108) (2021-10-04) 8 | 9 | ### [0.1.107](https://github.com/seeebiii/projen-test/compare/v0.1.106...v0.1.107) (2021-09-27) 10 | 11 | ### [0.1.106](https://github.com/seeebiii/projen-test/compare/v0.1.105...v0.1.106) (2021-09-27) 12 | 13 | ### [0.1.105](https://github.com/seeebiii/projen-test/compare/v0.1.104...v0.1.105) (2021-09-27) 14 | 15 | ### [0.1.104](https://github.com/seeebiii/projen-test/compare/v0.1.103...v0.1.104) (2021-09-13) 16 | 17 | ### [0.1.103](https://github.com/seeebiii/projen-test/compare/v0.1.102...v0.1.103) (2021-09-06) 18 | 19 | ### [0.1.102](https://github.com/seeebiii/projen-test/compare/v0.1.101...v0.1.102) (2021-09-06) 20 | 21 | ### [0.1.101](https://github.com/seeebiii/projen-test/compare/v0.1.100...v0.1.101) (2021-08-30) 22 | 23 | ### [0.1.100](https://github.com/seeebiii/projen-test/compare/v0.1.99...v0.1.100) (2021-08-30) 24 | 25 | ### [0.1.99](https://github.com/seeebiii/projen-test/compare/v0.1.98...v0.1.99) (2021-08-30) 26 | 27 | ### [0.1.98](https://github.com/seeebiii/projen-test/compare/v0.1.97...v0.1.98) (2021-08-30) 28 | 29 | ### [0.1.97](https://github.com/seeebiii/projen-test/compare/v0.1.96...v0.1.97) (2021-08-30) 30 | 31 | ### [0.1.96](https://github.com/seeebiii/projen-test/compare/v0.1.95...v0.1.96) (2021-08-23) 32 | 33 | ### [0.1.95](https://github.com/seeebiii/projen-test/compare/v0.1.94...v0.1.95) (2021-08-23) 34 | 35 | ### [0.1.94](https://github.com/seeebiii/projen-test/compare/v0.1.93...v0.1.94) (2021-08-23) 36 | 37 | ### [0.1.93](https://github.com/seeebiii/projen-test/compare/v0.1.92...v0.1.93) (2021-08-23) 38 | 39 | ### [0.1.92](https://github.com/seeebiii/projen-test/compare/v0.1.91...v0.1.92) (2021-08-23) 40 | 41 | ### [0.1.91](https://github.com/seeebiii/projen-test/compare/v0.1.90...v0.1.91) (2021-08-23) 42 | 43 | ### [0.1.90](https://github.com/seeebiii/projen-test/compare/v0.1.89...v0.1.90) (2021-08-16) 44 | 45 | ### [0.1.89](https://github.com/seeebiii/projen-test/compare/v0.1.88...v0.1.89) (2021-08-16) 46 | 47 | ### [0.1.88](https://github.com/seeebiii/projen-test/compare/v0.1.87...v0.1.88) (2021-08-16) 48 | 49 | ### [0.1.87](https://github.com/seeebiii/projen-test/compare/v0.1.86...v0.1.87) (2021-08-09) 50 | 51 | ### [0.1.86](https://github.com/seeebiii/projen-test/compare/v0.1.85...v0.1.86) (2021-08-09) 52 | 53 | ### [0.1.85](https://github.com/seeebiii/projen-test/compare/v0.1.84...v0.1.85) (2021-08-09) 54 | 55 | ### [0.1.84](https://github.com/seeebiii/projen-test/compare/v0.1.83...v0.1.84) (2021-08-02) 56 | 57 | ### [0.1.83](https://github.com/seeebiii/projen-test/compare/v0.1.82...v0.1.83) (2021-08-02) 58 | 59 | ### [0.1.82](https://github.com/seeebiii/projen-test/compare/v0.1.81...v0.1.82) (2021-08-02) 60 | 61 | ### [0.1.81](https://github.com/seeebiii/projen-test/compare/v0.1.80...v0.1.81) (2021-07-26) 62 | 63 | ### [0.1.80](https://github.com/seeebiii/projen-test/compare/v0.1.79...v0.1.80) (2021-07-26) 64 | 65 | ### [0.1.79](https://github.com/seeebiii/projen-test/compare/v0.1.78...v0.1.79) (2021-07-26) 66 | 67 | ### [0.1.78](https://github.com/seeebiii/projen-test/compare/v0.1.77...v0.1.78) (2021-07-26) 68 | 69 | ### [0.1.77](https://github.com/seeebiii/projen-test/compare/v0.1.76...v0.1.77) (2021-07-19) 70 | 71 | ### [0.1.76](https://github.com/seeebiii/projen-test/compare/v0.1.75...v0.1.76) (2021-07-19) 72 | 73 | ### [0.1.75](https://github.com/seeebiii/projen-test/compare/v0.1.74...v0.1.75) (2021-07-19) 74 | 75 | ### [0.1.74](https://github.com/seeebiii/projen-test/compare/v0.1.73...v0.1.74) (2021-07-12) 76 | 77 | ### [0.1.73](https://github.com/seeebiii/projen-test/compare/v0.1.72...v0.1.73) (2021-07-12) 78 | 79 | ### [0.1.72](https://github.com/seeebiii/projen-test/compare/v0.1.71...v0.1.72) (2021-07-12) 80 | 81 | ### [0.1.71](https://github.com/seeebiii/projen-test/compare/v0.1.70...v0.1.71) (2021-07-12) 82 | 83 | ### [0.1.70](https://github.com/seeebiii/projen-test/compare/v0.1.69...v0.1.70) (2021-07-12) 84 | 85 | ### [0.1.69](https://github.com/seeebiii/projen-test/compare/v0.1.68...v0.1.69) (2021-07-12) 86 | 87 | ### [0.1.68](https://github.com/seeebiii/projen-test/compare/v0.1.67...v0.1.68) (2021-07-05) 88 | 89 | ### [0.1.67](https://github.com/seeebiii/projen-test/compare/v0.1.66...v0.1.67) (2021-07-05) 90 | 91 | ### [0.1.66](https://github.com/seeebiii/projen-test/compare/v0.1.65...v0.1.66) (2021-07-05) 92 | 93 | ### [0.1.65](https://github.com/seeebiii/projen-test/compare/v0.1.64...v0.1.65) (2021-07-05) 94 | 95 | ### [0.1.64](https://github.com/seeebiii/projen-test/compare/v0.1.63...v0.1.64) (2021-06-28) 96 | 97 | ### [0.1.63](https://github.com/seeebiii/projen-test/compare/v0.1.62...v0.1.63) (2021-06-28) 98 | 99 | ### [0.1.62](https://github.com/seeebiii/projen-test/compare/v0.1.61...v0.1.62) (2021-06-28) 100 | 101 | ### [0.1.61](https://github.com/seeebiii/projen-test/compare/v0.1.60...v0.1.61) (2021-06-21) 102 | 103 | ### [0.1.60](https://github.com/seeebiii/projen-test/compare/v0.1.59...v0.1.60) (2021-06-21) 104 | 105 | ### [0.1.59](https://github.com/seeebiii/projen-test/compare/v0.1.58...v0.1.59) (2021-06-21) 106 | 107 | ### [0.1.58](https://github.com/seeebiii/projen-test/compare/v0.1.57...v0.1.58) (2021-06-21) 108 | 109 | ### [0.1.57](https://github.com/seeebiii/projen-test/compare/v0.1.56...v0.1.57) (2021-06-21) 110 | 111 | ### [0.1.56](https://github.com/seeebiii/projen-test/compare/v0.1.55...v0.1.56) (2021-06-21) 112 | 113 | ### [0.1.55](https://github.com/seeebiii/projen-test/compare/v0.1.54...v0.1.55) (2021-06-21) 114 | 115 | ### [0.1.54](https://github.com/seeebiii/projen-test/compare/v0.1.53...v0.1.54) (2021-06-21) 116 | 117 | ### [0.1.53](https://github.com/seeebiii/projen-test/compare/v0.1.52...v0.1.53) (2021-06-14) 118 | 119 | ### [0.1.52](https://github.com/seeebiii/projen-test/compare/v0.1.51...v0.1.52) (2021-05-31) 120 | 121 | ### [0.1.51](https://github.com/seeebiii/projen-test/compare/v0.1.50...v0.1.51) (2021-05-31) 122 | 123 | ### [0.1.50](https://github.com/seeebiii/projen-test/compare/v0.1.49...v0.1.50) (2021-05-31) 124 | 125 | ### [0.1.49](https://github.com/seeebiii/projen-test/compare/v0.1.48...v0.1.49) (2021-05-31) 126 | 127 | ### [0.1.48](https://github.com/seeebiii/projen-test/compare/v0.1.47...v0.1.48) (2021-05-24) 128 | 129 | ### [0.1.47](https://github.com/seeebiii/projen-test/compare/v0.1.46...v0.1.47) (2021-05-24) 130 | 131 | ### [0.1.46](https://github.com/seeebiii/projen-test/compare/v0.1.45...v0.1.46) (2021-05-24) 132 | 133 | ### [0.1.45](https://github.com/seeebiii/projen-test/compare/v0.1.44...v0.1.45) (2021-05-24) 134 | 135 | ### [0.1.44](https://github.com/seeebiii/projen-test/compare/v0.1.43...v0.1.44) (2021-05-17) 136 | 137 | ### [0.1.43](https://github.com/seeebiii/projen-test/compare/v0.1.42...v0.1.43) (2021-05-17) 138 | 139 | ### [0.1.42](https://github.com/seeebiii/projen-test/compare/v0.1.41...v0.1.42) (2021-05-17) 140 | 141 | ### [0.1.41](https://github.com/seeebiii/projen-test/compare/v0.1.40...v0.1.41) (2021-05-17) 142 | 143 | ### [0.1.40](https://github.com/seeebiii/projen-test/compare/v0.1.39...v0.1.40) (2021-05-17) 144 | 145 | ### [0.1.39](https://github.com/seeebiii/projen-test/compare/v0.1.38...v0.1.39) (2021-05-17) 146 | 147 | ### [0.1.38](https://github.com/seeebiii/projen-test/compare/v0.1.37...v0.1.38) (2021-05-10) 148 | 149 | ### [0.1.37](https://github.com/seeebiii/projen-test/compare/v0.1.36...v0.1.37) (2021-05-10) 150 | 151 | ### [0.1.36](https://github.com/seeebiii/projen-test/compare/v0.1.35...v0.1.36) (2021-05-10) 152 | 153 | ### [0.1.35](https://github.com/seeebiii/projen-test/compare/v0.1.34...v0.1.35) (2021-05-10) 154 | 155 | ### [0.1.34](https://github.com/seeebiii/projen-test/compare/v0.1.33...v0.1.34) (2021-05-10) 156 | 157 | ### [0.1.33](https://github.com/seeebiii/projen-test/compare/v0.1.32...v0.1.33) (2021-05-10) 158 | 159 | ### [0.1.32](https://github.com/seeebiii/projen-test/compare/v0.1.31...v0.1.32) (2021-05-10) 160 | 161 | ### [0.1.31](https://github.com/seeebiii/projen-test/compare/v0.1.30...v0.1.31) (2021-05-03) 162 | 163 | ### [0.1.30](https://github.com/seeebiii/projen-test/compare/v0.1.29...v0.1.30) (2021-05-03) 164 | 165 | ### [0.1.29](https://github.com/seeebiii/projen-test/compare/v0.1.28...v0.1.29) (2021-05-03) 166 | 167 | ### [0.1.28](https://github.com/seeebiii/projen-test/compare/v0.1.27...v0.1.28) (2021-05-03) 168 | 169 | ### [0.1.27](https://github.com/seeebiii/projen-test/compare/v0.1.26...v0.1.27) (2021-05-03) 170 | 171 | ### [0.1.26](https://github.com/seeebiii/projen-test/compare/v0.1.25...v0.1.26) (2021-05-03) 172 | 173 | ### [0.1.25](https://github.com/seeebiii/projen-test/compare/v0.1.24...v0.1.25) (2021-04-26) 174 | 175 | ### [0.1.24](https://github.com/seeebiii/projen-test/compare/v0.1.23...v0.1.24) (2021-04-26) 176 | 177 | ### [0.1.23](https://github.com/seeebiii/projen-test/compare/v0.1.22...v0.1.23) (2021-04-26) 178 | 179 | ### [0.1.22](https://github.com/seeebiii/projen-test/compare/v0.1.21...v0.1.22) (2021-04-26) 180 | 181 | ### [0.1.21](https://github.com/seeebiii/projen-test/compare/v0.1.20...v0.1.21) (2021-04-26) 182 | 183 | ### [0.1.20](https://github.com/seeebiii/projen-test/compare/v0.1.19...v0.1.20) (2021-04-19) 184 | 185 | ### [0.1.19](https://github.com/seeebiii/projen-test/compare/v0.1.18...v0.1.19) (2021-04-17) 186 | 187 | ### [0.1.18](https://github.com/seeebiii/projen-test/compare/v0.1.17...v0.1.18) (2021-04-17) 188 | 189 | ### [0.1.17](https://github.com/seeebiii/projen-test/compare/v0.1.16...v0.1.17) (2021-04-17) 190 | 191 | ### [0.1.16](https://github.com/seeebiii/projen-test/compare/v0.1.15...v0.1.16) (2021-04-17) 192 | 193 | 194 | ### Features 195 | 196 | * add Lambda and construct properties examples ([900a93f](https://github.com/seeebiii/projen-test/commit/900a93f9a45a284c654049b67935bec08435a7bb)) 197 | 198 | 199 | ### Bug Fixes 200 | 201 | * adjust interface names to avoid clash in C# ([769ec29](https://github.com/seeebiii/projen-test/commit/769ec29a72eaf3a605c493851c98d1a638822fc3)) 202 | 203 | ### [0.1.15](https://github.com/seeebiii/projen-test/compare/v0.1.14...v0.1.15) (2021-04-10) 204 | 205 | ### [0.1.14](https://github.com/info/projen-test/compare/v0.1.13...v0.1.14) (2021-02-02) 206 | 207 | ### [0.1.13](https://github.com/info/projen-test/compare/v0.1.11...v0.1.13) (2021-02-02) 208 | 209 | ### [0.1.11](https://github.com/info/projen-test/compare/v0.1.10...v0.1.11) (2021-01-31) 210 | 211 | ### [0.1.10](https://github.com/info/projen-test/compare/v0.1.9...v0.1.10) (2021-01-31) 212 | 213 | ### [0.1.9](https://github.com/info/projen-test/compare/v0.1.8...v0.1.9) (2021-01-31) 214 | 215 | ### [0.1.8](https://github.com/info/projen-test/compare/v0.1.7...v0.1.8) (2021-01-31) 216 | 217 | ### [0.1.7](https://github.com/info/projen-test/compare/v0.1.6...v0.1.7) (2021-01-31) 218 | 219 | ### [0.1.6](https://github.com/info/projen-test/compare/v0.1.5...v0.1.6) (2021-01-31) 220 | 221 | ### [0.1.5](https://github.com/info/projen-test/compare/v0.1.4...v0.1.5) (2021-01-31) 222 | 223 | ### [0.1.4](https://github.com/info/projen-test/compare/v0.1.3...v0.1.4) (2021-01-31) 224 | 225 | ### [0.1.3](https://github.com/info/projen-test/compare/v0.1.2...v0.1.3) (2021-01-31) 226 | 227 | ### [0.1.2](https://github.com/info/projen-test/compare/v0.1.1...v0.1.2) (2021-01-30) 228 | 229 | ### [0.1.1](https://github.com/info/projen-test/compare/v0.0.1...v0.1.1) (2021-01-30) 230 | 231 | ### 0.0.1 (2021-01-30) 232 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2021 Sebastian Hesse 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create and Publish CDK Constructs Using projen and jsii 2 | 3 | This project tests and describes the workflow of creating an [AWS CDK](https://aws.amazon.com/cdk/) construct using [projen](https://github.com/projen/projen) + [jsii](https://github.com/aws/jsii) and publishing it to various repositories like npm, Maven Central, PyPi and NuGet. 4 | 5 | In order to verify the process is working as expected, this project contains an [`LambdaConstruct`](src/LambdaConstruct.ts). 6 | It only creates a very simple Lambda function using inline code that prints out the event it's receiving. 7 | Btw. did you know there are multiple [ways to bundle an AWS Lambda function in a CDK construct](https://www.sebastianhesse.de/2021/01/16/5-ways-to-bundle-a-lambda-function-within-an-aws-cdk-construct/)? 8 | 9 | **Note:** If you are reading this on npm, NuGet, or PyPi as part of the package description, then please head over to https://github.com/seeebiii/projen-test. 10 | Otherwise the links might not work properly. 11 | 12 | ## Questions? 13 | 14 | Do you have further questions? 15 | Feel free to reach out via [Twitter](https://twitter.com/seeebiii) or visit my website - I'm a [Freelance Software Engineer](https://www.sebastianhesse.de) focusing on serverless cloud projects. 16 | 17 | There's also a [CDK developer Slack workspace](https://cdk.dev/) that you can join to ask questions. 18 | 19 | ## Table of Contents 20 | 21 | - [About projen](#about-projen) 22 | - [About jsii](#about-jsii) 23 | - [Requirements](#requirements) 24 | - [Setup Project](#setup-project) 25 | - [Write CDK Construct](#write-cdk-construct) 26 | - [Connect to GitHub](#connect-to-github) 27 | - [Publish to Different Repositories](#publishing-to-different-repositories) 28 | - [Verify Your CDK Construct](#verify-your-cdk-construct) 29 | - [Next Steps](#next-steps) 30 | - [Additional Help](#additional-help) 31 | 32 | ## About projen 33 | 34 | [projen](https://github.com/projen/projen) is a tool to write your project configuration using code instead of managing it yourself. 35 | It was initially created to help you writing CDK constructs but can also be used to create any other project stub like a React app. 36 | 37 | The important thing to note is that you only define the project configuration in the [.projenrc.js](.projenrc.js) file and it will generate everything for you, like `package.json` or other files. 38 | **Remember:** do not manually change the generated files, otherwise changes will be lost after you run `projen` again. 39 | 40 | Besides that, it is recommended to create an alias in your command line to avoid typing `npx projen` over and over again. 41 | For example: `alias pj='npx projen'` 42 | 43 | Further links: 44 | 45 | - [A Beginner's Guide to Create AWS CDK Construct Library with projen](https://dev.to/aws-builders/a-beginner-s-guide-to-create-aws-cdk-construct-library-with-projen-5eh4) 46 | - [Converting a CDK construct to using projen](https://www.matthewbonig.com/2020/10/04/converting-to-projen/) 47 | 48 | ## About jsii 49 | 50 | [jsii](https://github.com/aws/jsii) is the technology behind the AWS CDK that allows you to write CDK constructs in TypeScript/JavaScript and compile them to other languages like Java or Python. 51 | There's an [AWS blog post](https://aws.amazon.com/blogs/opensource/generate-python-java-dotnet-software-libraries-from-typescript-source/) about how it works. 52 | 53 | There are a few jsii related projects that support us in the steps below, e.g. for releasing our artifacts. 54 | 55 | ## Requirements 56 | 57 | - ~30 of your time (maybe more if you run into errors or need to read through a few documents) 58 | - Node.js/npm installed on your machine 59 | - AWS CDK installed on your machine 60 | - GitHub Account (free account is enough) 61 | 62 | ### Optional 63 | 64 | - AWS Account (for verification) 65 | - Java + Maven (for local packaging & verification) 66 | - Python (for local packaging & verification) 67 | 68 | ## Steps For Creating a New CDK Construct Using projen 69 | 70 | In case you want to test `projen` as well, here are the steps I've performed. 71 | 72 | ### Setup Project 73 | 74 | 1. Initialize a new project using `projen`: 75 | 76 | ```shell 77 | mkdir projen-test 78 | cd projen-test 79 | npx projen new awscdk-construct 80 | ``` 81 | 82 | 2. Now create a new Git repository using `git init` and connect an existing Git project using `git remote add origin `. 83 | (Create your Git repository in GitHub first before you call `git remote add ...`) 84 | 85 | - Note: if your local branch is `master` but your remote branch is `main`, then use `git branch -M main` to rename the local branch. 86 | 87 | 3. Create an alias for your command-line if you haven't done already: `alias pj='npx projen'` 88 | 89 | 4. Adjust the `projen` options in `.projenrc.js` a bit. For example: 90 | - adjust metadata like `name`, `author`, `authorName`, `authorAddress`, `repositoryUrl`. 91 | By default `name` is also used as the `name` in the generated `package.json`. 92 | However, you can define a custom one by using `packageName`. 93 | - add `projectType: ProjectType.LIB` since we'll create a library 94 | - add `cdkAssert: true` for being able to test my CDK construct 95 | - add `cdkDependencies: ['@aws-cdk/core', '@aws-cdk/aws-lambda']` to let `projen` add these CDK dependencies for me 96 | - optional: add `mergify: false` if you don't want to use it at the moment 97 | - optional: explicitly add `docgen: true` so it automatically generates API documentation 🙌 98 | - optional: explicitly add `eslint: true` to make sure you use common coding standards 99 | - optional: add `dependabot: true` and `dependabotOptions: {...}` to enable [Dependabot](https://dependabot.com/) if you hate manually managing dependency updates 100 | - optional: add `gitignore: ['.idea']` if you love using IntelliJ ♥️ but don't want to commit its settings - or if you want to ignore any other files :) 101 | - optional: use `packageManager: NodePackageManager.NPM` if you want to use `npm` instead of `yarn` - might be important in case you are migrating an existing CDK Construct to `projen`. 102 | 103 | Don't forget to add necessary imports in the config file when applying the `projen` settings, e.g. for using `ProjectType` or `NodePackageManager`. 104 | 105 | 5. Set a version number in [version.json](version.json), e.g. `0.0.1`. 106 | 107 | 6. Run `pj` again on your command-line. 108 | This will update all project files like [package.json](package.json) based on what you have configured in [.projenrc.js](.projenrc.js). 109 | Remember to not manually update these files as `projen` will override your changes otherwise. 110 | 111 | **💡 Hint:** I can recommend to play around with the options a little bit and run `pj` after each change. 112 | Then observe what happens and how the project files differ. 113 | If you commit the changes to Git each time after running `pj`, you can easily compare the Git diff 😊 114 | 115 | ### Write CDK Construct 116 | 117 | 1. Write a simple CDK construct in `src/index.ts`. 118 | There are already great tutorials like [cdkworkshop.com](https://cdkworkshop.com/) available about how to write constructs. 119 | Here's a small code snippet for a simple Lambda function using inline code: 120 | 121 | ```typescript 122 | new Function(this, 'SampleFunction', { 123 | runtime: Runtime.NODEJS_12_X, 124 | code: Code.fromInline('exports.handler = function (e, ctx, cb) { console.log("Event: ", e); cb(); };'), 125 | handler: 'index.handler', 126 | timeout: Duration.seconds(10), 127 | }); 128 | ``` 129 | 130 | Have a look at [LambdaConstruct.ts](src/index.ts) for an examples construct that declares various Lambda functions. 131 | Instead of using a Lambda function, you can also use whatever you like. 132 | 133 | 2. Write a simple test for this construct in [test/index.test.ts](test/index.test.ts). 134 | Here's also a small code snippet which ensures that our Lambda function is created in the stack: 135 | 136 | ```typescript 137 | test('Simple test', () => { 138 | const app = new cdk.App(); 139 | const stack = new cdk.Stack(app, 'TestStack'); 140 | 141 | new LambdaConstruct(stack, 'LambdaConstruct'); 142 | 143 | expectCDK(stack).to(countResources('AWS::Lambda::Function', 1)); 144 | }); 145 | ``` 146 | 147 | The test is creating a stack and verifies that the stack contains exactly one resource of type `AWS::Lambda::Function`. 148 | Have a look at [index.test.js](test/index.test.ts) for further details. 149 | 150 | 3. Run `yarn run build`. 151 | This command will compile the code, execute the tests using [Jest](https://jestjs.io/) and also generate [API.md](API.md) 😍 152 | 153 | ### Connect to GitHub 154 | 155 | Add all files to Git, commit and push your changes. 156 | 157 | ```shell 158 | # Maybe adjust this to really add all files from every folder, or use IntelliJ or some Git GUI to do this 159 | git add . 160 | git commit -M "Initial commit" 161 | git push -u origin main 162 | ``` 163 | 164 | ### Publishing to Different Repositories 165 | 166 | ![successful-projen-action-run](assets/successful-projen-action-run.png) 167 | 168 | If you want to release your package to one or multiple repositories like npm or Maven Central, you'll have to enable this in [.projenrc.js](.projenrc.js). 169 | After changing the configuration as described below and calling `pj` (or `npx projen` if you're not using the alias), you'll notice that there are a few files in [.github/workflows](.github/workflows) folder. 170 | They take care of running [GitHub Actions](https://github.com/features/actions) to build and release/publish the library to npm and other repositories. 171 | The action steps are using [jsii-superchain](https://github.com/aws/jsii/tree/main/superchain) as the Docker image to run a step. 172 | 173 | The release process is also using the npm module [jsii-release](https://github.com/aws/jsii-release) to help releasing the artifacts. 174 | The project's README is explaining all the different parameters that you need to set for publishing to the different repositories that are supported. 175 | Currently, npm (Node.js), Maven (Java), NuGet (C#) and PyPi (Python) are supported. 176 | 177 | #### Publish to npm 178 | 179 | I'm assuming you already have an [npm](https://www.npmjs.com/) account. 180 | If not, register first. 181 | 182 | 1. Update [.projenrc.js](.projenrc.js) and enable npm releases: 183 | - `releaseBranches: ['main']` 184 | - `releaseToNpm: true` -> Yes, I want to publish a new version to npm every time :) 185 | - `releaseWorkflow: true` 186 | - Optional: `releaseEveryCommit: true` -> will run the release GitHub Action on each push to the defined `releaseBranches` 187 | 188 | 2. Run `pj` to update your project files. 189 | You'll notice [release.yml](.github/workflows/release.yml) contains a few steps to build and release your artifact. 190 | The `release_npm` step requires an `NPM_TOKEN` so that the GitHub Action can publish your package for you. 191 | 192 | 3. Create an [access token](https://docs.npmjs.com/about-access-tokens) for npm. 193 | Use type 'Automation' for the token type. 194 | The token will be used in a GitHub Action to release your package. 195 | 196 | 4. Add the access token as a [repository secret](https://docs.github.com/en/actions/reference/encrypted-secrets) to your GitHub repository. 197 | Use `NPM_TOKEN` as name and insert the access token from the previous step. 198 | This is 199 | 200 | 5. Commit and push your changes. 201 | If you have configured `releaseBranches: ['main']` in [.projenrc.js](.projenrc.js) as discussed above, then a new Action run is triggered that builds your CDK construct and publishes it to npm. 202 | 203 | After the last step, you'll notice that the first GitHub Action should be running. 204 | 205 | Have a look at the published package: [@seeebiii/projen-test](https://www.npmjs.com/package/@seeebiii/projen-test) 206 | 207 | #### Publish to Maven Repository 208 | 209 | Since we want to make our CDK construct public, I'm describing the steps to publish it to [Maven Central](https://oss.sonatype.org/), the main Maven repository (like npm fo Node.js packages). 210 | However, this process requires a few more steps compared to npm. 211 | 212 | **Maven Requirements** 213 | 214 | In order to publish to Maven Central, you need an account and also "authenticate" yourself using GPG. 215 | This ensures that others can verify the correctness of your artifacts and no one else distributes them to introduce vulnerable code. 216 | 217 | 1. Create an account for Maven Central and register your own namespace like `org.example` if you are the owner of the domain `example.org`. 218 | This is described in [this OSSRH Guide](https://central.sonatype.org/pages/ossrh-guide.html#initial-setup). 219 | If you don't have your own domain, you can also use `com.github.` instead. 220 | The Jira system has a bot installed that helps you verifying your domain or your GitHub user, so just register and create an issue as described. 221 | The bot will tell you what to do next 😊 222 | 223 | 2. Upload a PGP key to a well-known key registry, so other people can verify that the artifacts are from you. 224 | This is explained well in the [jsii-release README](https://github.com/aws/jsii-release#maven) in the subsection **How to create a GPG key?**. 225 | 226 | 3. Please save the passphrase of your PGP key somewhere safe, e.g. a password manager. 227 | You'll need it in a step below! 228 | 229 | **Setup Maven Release Action** 230 | 231 | 1. Update [.projenrc.js](.projenrc.js) and enable Java releases to Maven Central: 232 | 233 | ```javascript 234 | publishToMaven: { 235 | mavenGroupId: '', 237 | javaPackage: '', 238 | } 239 | ``` 240 | 241 | You can specify anything you want as long as the namespace you've registered with Maven Central is a prefix of `mavenGroupId`. 242 | For example, I have registered `de.sebastianhesse` since I also own the domain [www.sebastianhesse.de](https://www.sebastianhesse.de). 243 | Therefore, I can use `de.sebastianhesse.examples` as the `mavenGroupId`. 244 | 245 | 2. Run `pj` to update your project files. 246 | You'll notice changes in the [release.yml](.github/workflows/release.yml) and a new step `release_maven`. 247 | As you can see, it uses a few secrets like `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PRIVATE_KEY_PASSPHRASE`, `MAVEN_USERNAME`, `MAVEN_PASSWORD`, and `MAVEN_STAGING_PROFILE_ID`. 248 | These are the same as described in the [jsii-release README](https://github.com/aws/jsii-release#maven). 249 | If you need help figuring out the `MAVEN_STAGING_PROFILE_ID`, then please see below in the [Additional Help](#additional-help) section. 250 | 251 | 3. Add all the required secrets as [repository secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) to your GitHub repository. 252 | 253 | 4. Commit and push your changes. 254 | 255 | Like with the npm release process above, as soon as you push your changes a GitHub Action is triggered and performs the release. 256 | You'll notice that the release process for Maven takes a lot more time than the one for npm. 257 | Also take care that it might take some time to find your artifact in Maven Central (usually within a few minutes but it can take longer). 258 | 259 | Have a look at the published package: [projen-test](https://oss.sonatype.org/#nexus-search;quick~de.sebastianhesse) 260 | 261 | #### Publish to PyPi 262 | 263 | In order to publish to [PyPi](https://pypi.org/), you need an account there. 264 | 265 | 1. Update [.projenrc.js](.projenrc.js) configuration: 266 | 267 | ```javascript 268 | publishToPypi: { 269 | distName: '', 270 | module: '', 271 | }, 272 | ``` 273 | 274 | 2. Run `pj` to update your project files. 275 | Again, [release.yml](.github/workflows/release.yml) has been updated and a `release_pypi` step has been added. 276 | The step requires two secrets: `TWINE_USERNAME` and `TWINE_PASSWORD`. 277 | 278 | 3. Use your PyPi `username` for `TWINE_USERNAME` and `password` for `TWINE_PASSWORD`. 279 | Add the secrets as [repository secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) to your GitHub repository. 280 | 281 | Have a look at the published package: [projen-test](https://pypi.org/project/projen-test/) 282 | 283 | #### Publish to NuGet 284 | 285 | 1. Update [.projenrc.js](.projenrc.js) configuration: 286 | 287 | ```javascript 288 | publishToNuget: { 289 | dotNetNamespace: 'Organization.Namespace', 290 | packageId: 'Package.Name', 291 | }, 292 | ``` 293 | 294 | 2. Run `pj` to update your project files. 295 | Again, [release.yml](.github/workflows/release.yml) has been updated and a `release_nuget` step has been added. 296 | The step requires the secret `NUGET_API_KEY`. 297 | 298 | 3. Generate an [API Key](https://www.nuget.org/account/apikeys) for your account and use it for `NUGET_API_KEY`. 299 | Add the secret as a [repository secret](https://docs.github.com/en/actions/reference/encrypted-secrets) to your GitHub repository. 300 | 301 | Have a look at published package: [Projen.Test](https://www.nuget.org/packages/Projen.Test/) 302 | 303 | ## Verify Your CDK Construct 304 | 305 | Congratulations 🙌 306 | You have successfully published your first CDK construct using `projen` to multiple repositories. 307 | (At least you hope so at the moment 😀) 308 | 309 | Let's verify that our construct is working as expected in different languages. 310 | Since my main programming languages are Java and Node.js/JavaScript, I'll only present those two here. 311 | If I have time, I'll add the others as well - or if you want to contribute something? 😉 312 | 313 | **Note**: when deploying a CDK app, you need to provide the AWS Account ID and Region. 314 | You can do this either using environment variables in the CLI or by explicitly providing `environment` details in the file/class where the CDK app is defined. 315 | See [this page](https://docs.aws.amazon.com/cdk/latest/guide/environments.html) for further help. 316 | 317 | ### Verify in Node.js 318 | 319 | 1. Initialize a new CDK app in TypeScript: 320 | 321 | ```shell 322 | mkdir cdk-npm-test 323 | cd cdk-npm-test 324 | cdk init app --language=typescript 325 | ``` 326 | 327 | This will initialize a new CDK app project. 328 | You can also use `--language=javascript` which initializes the project using JavaScript instead of TypeScript. 329 | In `bin/cdk-npm-test.ts` you'll find the CDK app definition and in `lib/cdk-npm-test-stack.ts` you can find the stack definition. 330 | 331 | 2. Add your new CDK construct as a dev dependency: `npm i -D `, e.g. `npm i -D projen-test`. 332 | 333 | **Take care** that the versions for all AWS CDK dependencies in `package.json` (e.g. for `aws-cdk` or `@aws-cdk/core`) are matching the version that you have specified in [.projenrc.js](.projenrc.js) under `cdkVersion`. 334 | Otherwise you'll see some funny compilation errors. 335 | If you need to update the dependencies, you can use `npm i -S @latest` (for dependencies) or `npm i -D @latest` (for dev dependencies). 336 | 337 | 3. Add your new CDK construct in `bin/cdk-npm-test-stack.ts` like: `new LambdaConstruct(this, 'NpmSample');` 338 | 339 | 4. Build your code: `npm run build` 340 | 341 | 5. Now you can deploy your app using `cdk deploy`. 342 | Wait for the stack to be created and test that everything looks like expected. 343 | 344 | ### Verify in Java 345 | 346 | 1. Initialize new CDK app in Java: 347 | 348 | ```shell 349 | mkdir cdk-java-test 350 | cd cdk-java-test 351 | cdk init app --language=java 352 | ``` 353 | 354 | This will initialize a new CDK app project. 355 | In `src/main/java/com/myorg` you'll see the files `CdkJavaTestApp` and `CdkJavaTestStack` that contain CDK samples. 356 | 357 | 2. Add the CDK construct you've just published to the project's `pom.xml` (adjust the details): 358 | 359 | ```xml 360 | 361 | de.sebastianhesse.examples 362 | projen-test 363 | 0.1.16 364 | 365 | ``` 366 | 367 | Replace the Maven coordinates based on your settings that you've configured with `publishToMaven` in [.projenrc.js](.projenrc.js) and the correct version. 368 | 369 | 3. Then go to `CdkJavaTestStack` and make use of your CDK construct. 370 | In my case, I have added the following line in the constructor: `new LambdaConstruct(this, "JavaSample");` 371 | 372 | 4. Package your code (including running the tests): `mvn package` 373 | 374 | 5. Now you can deploy your app using `cdk deploy`. 375 | Wait for the stack to be created and test that everything looks like expected. 376 | 377 | ### Verify in Python 378 | 379 | TODO 380 | 381 | Note: If you are eager to go through this tutorial and explore the steps for Python, feel free to contribute to this README :) 382 | 383 | ### Verify in C# 384 | 385 | TODO 386 | 387 | Note: If you are eager to go through this tutorial and explore the steps for NuGet / C#, feel free to contribute to this README :) 388 | 389 | ## Next Steps 390 | 391 | You are amazing! 🚀 392 | If you went until this point, you have successfully published your first multi-language CDK construct! 393 | 394 | Check out more resources: 395 | 396 | - [cdkworkshop.com](https://cdkworkshop.com/) 397 | - [CDK Constructs](https://github.com/awslabs/aws-solutions-constructs) 398 | - [awesome-cdk](https://github.com/kolomied/awesome-cdk) 399 | - [cdkpatterns.com](https://cdkpatterns.com/) 400 | - [CDK Construct Catalog](https://awscdk.io) 401 | - [More CDK Constructs 1](https://github.com/cloudcomponents/cdk-constructs) 402 | - [More CDK Constructs 2](https://github.com/taimos/cdk-constructs) 403 | 404 | ## Additional Help 405 | 406 | Below are a few topics that I've discovered along the way and would like to explain further. 407 | 408 | ### Find The `MAVEN_STAGING_PROFILE_ID` 409 | 410 | In order to figure out the `MAVEN_STAGING_PROFILE_ID`, follow these steps: 411 | - Login to [oss.sonatype.org](https://oss.sonatype.org/) using your Maven Central credentials. 412 | - On the left, click on `Staging Profiles` 413 | - In the main window, make sure you select the tab `Staging Profiles` and select the entry matching your namespace `org.example` 414 | - You'll notice the URL has changed to `https://oss.sonatype.org/#stagingProfiles;12abc3456789` 415 | - Use the id after the `;` semicolon as the `MAVEN_STAGING_PROFILE_ID` 416 | -------------------------------------------------------------------------------- /assets/successful-projen-action-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seeebiii/projen-test/bb234900ca1a4c1a43130d540b0beb7685686bee/assets/successful-projen-action-run.png -------------------------------------------------------------------------------- /lambda-js/index.js: -------------------------------------------------------------------------------- 1 | exports.handler = (event) => { 2 | console.log('Event: ', event); 3 | return {}; 4 | }; 5 | -------------------------------------------------------------------------------- /lambda-python/index.py: -------------------------------------------------------------------------------- 1 | def handler(event, context): 2 | print("Event: ", event) 3 | return {} 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@seeebiii/projen-test", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/seeebiii/projen-test" 6 | }, 7 | "scripts": { 8 | "clobber": "npx projen clobber", 9 | "compile": "npx projen compile", 10 | "test:compile": "npx projen test:compile", 11 | "test": "npx projen test", 12 | "build": "npx projen build", 13 | "bump": "npx projen bump", 14 | "release": "npx projen release", 15 | "test:watch": "npx projen test:watch", 16 | "test:update": "npx projen test:update", 17 | "projen:upgrade": "npx projen projen:upgrade", 18 | "watch": "npx projen watch", 19 | "package": "npx projen package", 20 | "eslint": "npx projen eslint", 21 | "docgen": "npx projen docgen", 22 | "compat": "npx projen compat", 23 | "projen": "npx projen", 24 | "start": "npx projen start" 25 | }, 26 | "author": { 27 | "name": "Sebastian Hesse", 28 | "url": "https://www.sebastianhesse.de", 29 | "organization": false 30 | }, 31 | "devDependencies": { 32 | "@aws-cdk/assert": "^1.97.0", 33 | "@types/jest": "^26.0.20", 34 | "@types/node": "^10.17.0", 35 | "@typescript-eslint/eslint-plugin": "^4.3.0", 36 | "@typescript-eslint/parser": "^4.3.0", 37 | "esbuild": "^0.11.6", 38 | "eslint": "^7.18.0", 39 | "eslint-import-resolver-node": "^0.3.4", 40 | "eslint-import-resolver-typescript": "^2.3.0", 41 | "eslint-plugin-import": "^2.22.1", 42 | "jest": "^26.6.3", 43 | "jest-junit": "^12", 44 | "jsii": "^1.18.0", 45 | "jsii-diff": "^1.18.0", 46 | "jsii-docgen": "^1.8.31", 47 | "jsii-pacmak": "^1.18.0", 48 | "json-schema": "^0.3.0", 49 | "projen": "^0.17.31", 50 | "standard-version": "^9", 51 | "ts-jest": "^26.5.0", 52 | "typedoc": "^0.20.19", 53 | "typescript": "^3.9.5" 54 | }, 55 | "peerDependencies": { 56 | "@aws-cdk/aws-lambda": "^1.97.0", 57 | "@aws-cdk/core": "^1.97.0", 58 | "constructs": "^3.2.27" 59 | }, 60 | "dependencies": { 61 | "@aws-cdk/aws-lambda": "^1.97.0", 62 | "@aws-cdk/core": "^1.97.0" 63 | }, 64 | "bundledDependencies": [], 65 | "keywords": [ 66 | "cdk" 67 | ], 68 | "main": "lib/index.js", 69 | "license": "Apache-2.0", 70 | "version": "0.1.109", 71 | "publishConfig": { 72 | "access": "public" 73 | }, 74 | "jest": { 75 | "testMatch": [ 76 | "**/__tests__/**/*.ts?(x)", 77 | "**/?(*.)+(spec|test).ts?(x)" 78 | ], 79 | "clearMocks": true, 80 | "collectCoverage": true, 81 | "coverageReporters": [ 82 | "json", 83 | "lcov", 84 | "clover", 85 | "text" 86 | ], 87 | "coverageDirectory": "coverage", 88 | "coveragePathIgnorePatterns": [ 89 | "/node_modules/" 90 | ], 91 | "testPathIgnorePatterns": [ 92 | "/node_modules/" 93 | ], 94 | "watchPathIgnorePatterns": [ 95 | "/node_modules/" 96 | ], 97 | "reporters": [ 98 | "default", 99 | [ 100 | "jest-junit", 101 | { 102 | "outputDirectory": "test-reports" 103 | } 104 | ] 105 | ], 106 | "preset": "ts-jest", 107 | "globals": { 108 | "ts-jest": { 109 | "tsconfig": "tsconfig.jest.json" 110 | } 111 | } 112 | }, 113 | "types": "lib/index.d.ts", 114 | "stability": "stable", 115 | "jsii": { 116 | "outdir": "dist", 117 | "targets": { 118 | "java": { 119 | "package": "de.sebastianhesse.examples.projen.test", 120 | "maven": { 121 | "groupId": "de.sebastianhesse.examples", 122 | "artifactId": "projen-test" 123 | } 124 | }, 125 | "python": { 126 | "distName": "projen-test", 127 | "module": "projen_test" 128 | }, 129 | "dotnet": { 130 | "namespace": "SebastianHesse.Examples", 131 | "packageId": "Projen.Test" 132 | } 133 | }, 134 | "tsc": { 135 | "outDir": "lib", 136 | "rootDir": "src" 137 | } 138 | }, 139 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." 140 | } -------------------------------------------------------------------------------- /src/ConstructWithProperties.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from '@aws-cdk/core'; 2 | 3 | /** 4 | * This interface is translated into a _struct_ containing data. 5 | * E.g. if translated to Java, an interface `StructProperties` is created containing a builder subclass to create an instance of the interface. 6 | * 7 | * @see https://aws.github.io/jsii/user-guides/lib-author/typescript-restrictions/#interfaces 8 | */ 9 | export interface StructProperties { 10 | readonly myProp: string; 11 | } 12 | 13 | /** 14 | * This is a _behavioral interface_ identified by `I` in its name. 15 | * It will be translated to a "regular" interface which needs to be implemented. 16 | * You can also use methods here, e.g. `doSth(): void;`. 17 | * 18 | * @see https://aws.github.io/jsii/user-guides/lib-author/typescript-restrictions/#interfaces 19 | */ 20 | export interface IBehaviorProperties { 21 | // using 'readonly' here will not create a setter method for this property but only a getter; not using 'readonly' will produce a setter + getter 22 | readonly otherProp: string; 23 | } 24 | 25 | /** 26 | * A simple CDK construct illustrating the differences in declaring construct properties with interfaces. 27 | */ 28 | export class ConstructWithProperties extends Construct { 29 | constructor(parent: Construct, name: string, props: StructProperties, props2: IBehaviorProperties) { 30 | super(parent, name); 31 | 32 | if (props.myProp === 'foo') { 33 | console.log('Hello'); 34 | } 35 | 36 | if (props2.otherProp === 'bar') { 37 | console.log('World'); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/LambdaConstruct.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; 3 | import { Construct, Duration } from '@aws-cdk/core'; 4 | 5 | /** 6 | * A CDK construct to create Lambda functions. 7 | */ 8 | export class LambdaConstruct extends Construct { 9 | constructor(parent: Construct, name: string) { 10 | super(parent, name); 11 | 12 | // most simple function with static inline code that prints the event and calls the callback function 13 | new Function(this, 'InlineFunction', { 14 | runtime: Runtime.NODEJS_12_X, 15 | code: Code.fromInline('exports.handler = function (e, ctx, cb) { console.log("Event: ", e); cb(); };'), 16 | handler: 'index.handler', 17 | timeout: Duration.seconds(10), 18 | }); 19 | 20 | // a function which is written in regular Node.js outside of the src folder 21 | new Function(this, 'JsFunction1', { 22 | runtime: Runtime.NODEJS_12_X, 23 | code: Code.fromAsset(path.join(__dirname, '../lambda-js')), 24 | handler: 'index.handler', 25 | }); 26 | 27 | // a function which is written in TypeScript inside the src/lambda folder 28 | new Function(this, 'JsFunction2', { 29 | runtime: Runtime.NODEJS_12_X, 30 | code: Code.fromAsset(path.join(__dirname, 'lambda')), 31 | handler: 'index.handler', 32 | }); 33 | 34 | // a function which is written in Python outside of the src folder 35 | new Function(this, 'PythonFunction', { 36 | runtime: Runtime.PYTHON_3_8, 37 | code: Code.fromAsset(path.join(__dirname, '../lambda-python')), 38 | handler: 'index.handler', 39 | }); 40 | 41 | // a function which is ignored by TypeScript but still included by running a custom compile task; 42 | // the compile task is using 'esbuild' to bundle & minify the function, i.e. include all depedencies into one target file 43 | new Function(this, 'BundledDepsFunction', { 44 | runtime: Runtime.NODEJS_12_X, 45 | code: Code.fromAsset(path.join(__dirname, 'lambda-bundled')), 46 | handler: 'index.handler', 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './LambdaConstruct'; 2 | export * from './ConstructWithProperties'; 3 | -------------------------------------------------------------------------------- /src/lambda-bundled/index.js: -------------------------------------------------------------------------------- 1 | // Add any kind of imports here (or use require) 2 | // -> esbuild will take care of bundling everything into one file 3 | 4 | exports.handler = (event) => { 5 | console.log('Event: ', event); 6 | return {}; 7 | }; 8 | -------------------------------------------------------------------------------- /src/lambda/index.ts: -------------------------------------------------------------------------------- 1 | exports.handler = (event: any) => { 2 | console.log('Event: ', event); 3 | return {}; 4 | }; 5 | -------------------------------------------------------------------------------- /test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { countResources, expect as expectCDK } from '@aws-cdk/assert'; 2 | import * as cdk from '@aws-cdk/core'; 3 | import { LambdaConstruct } from '../src'; 4 | 5 | test('Simple test', () => { 6 | const app = new cdk.App(); 7 | const stack = new cdk.Stack(app, 'TestStack'); 8 | 9 | new LambdaConstruct(stack, 'LambdaConstruct'); 10 | 11 | expectCDK(stack).to(countResources('AWS::Lambda::Function', 5)); 12 | }); 13 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "alwaysStrict": true, 4 | "declaration": true, 5 | "experimentalDecorators": true, 6 | "inlineSourceMap": true, 7 | "inlineSources": true, 8 | "lib": [ 9 | "es2018" 10 | ], 11 | "module": "CommonJS", 12 | "noEmitOnError": false, 13 | "noFallthroughCasesInSwitch": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitThis": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "resolveJsonModule": true, 20 | "strict": true, 21 | "strictNullChecks": true, 22 | "strictPropertyInitialization": true, 23 | "stripInternal": true, 24 | "target": "ES2018" 25 | }, 26 | "include": [ 27 | ".projenrc.js", 28 | "src/**/*.ts", 29 | "test/**/*.ts" 30 | ], 31 | "exclude": [ 32 | "node_modules" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tsconfig.jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "alwaysStrict": true, 4 | "declaration": true, 5 | "experimentalDecorators": true, 6 | "inlineSourceMap": true, 7 | "inlineSources": true, 8 | "lib": [ 9 | "es2018" 10 | ], 11 | "module": "CommonJS", 12 | "noEmitOnError": false, 13 | "noFallthroughCasesInSwitch": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitThis": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "resolveJsonModule": true, 20 | "strict": true, 21 | "strictNullChecks": true, 22 | "strictPropertyInitialization": true, 23 | "stripInternal": true, 24 | "target": "ES2018" 25 | }, 26 | "include": [ 27 | ".projenrc.js", 28 | "src/**/*.ts", 29 | "test/**/*.ts" 30 | ], 31 | "exclude": [ 32 | "node_modules" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.109" 3 | } 4 | --------------------------------------------------------------------------------