├── .github
└── issue_template.md
├── .gitignore
├── .idea
├── .gitignore
└── aws.xml
├── README.md
├── api-endpoint
├── .eslintrc.json
├── .gitattributes
├── .github
│ ├── pull_request_template.md
│ └── workflows
│ │ ├── build.yml
│ │ ├── pull-request-lint.yml
│ │ └── upgrade.yml
├── .gitignore
├── .mergify.yml
├── .npmignore
├── .projen
│ ├── deps.json
│ ├── files.json
│ └── tasks.json
├── .projenrc.js
├── LICENSE
├── README.md
├── cdk.json
├── package.json
├── src
│ ├── MyApiGatewayStack.ts
│ ├── handlers
│ │ ├── newsletter
│ │ │ ├── newsletter-function.ts
│ │ │ └── newsletter.lambda.ts
│ │ └── reviews
│ │ │ ├── reviews-handler-function.ts
│ │ │ └── reviews-handler.lambda.ts
│ └── main.ts
├── test
│ └── main.test.ts
├── tsconfig.dev.json
├── tsconfig.json
└── yarn.lock
└── chapters
├── project-layout
├── lots-of-lambdas
│ └── README.md
└── more-complexity
│ └── README.md
└── testing
├── basic-snapshot-test
└── README.md
├── infra-apig
├── .eslintrc.json
├── .gitattributes
├── .github
│ ├── pull_request_template.md
│ └── workflows
│ │ ├── build.yml
│ │ └── upgrade-dependencies.yml
├── .gitignore
├── .idea
│ ├── infra-apig.iml
│ ├── inspectionProfiles
│ │ └── Project_Default.xml
│ ├── jsLinters
│ │ └── eslint.xml
│ ├── modules.xml
│ └── vcs.xml
├── .mergify.yml
├── .npmignore
├── .projen
│ ├── deps.json
│ └── tasks.json
├── .projenrc.js
├── .versionrc.json
├── LICENSE
├── README.md
├── cdk.json
├── package-lock.json
├── package.json
├── src
│ ├── ApiTester.ts
│ ├── SimpleApiWithTestsStack.ts
│ ├── handlers
│ │ ├── custom-resource.ts
│ │ ├── proxy.ts
│ │ └── runTest.ts
│ └── main.ts
├── test
│ └── main.test.ts
├── tsconfig.eslint.json
├── tsconfig.jest.json
├── tsconfig.json
└── yarn.lock
├── infra-async
├── .eslintrc.json
├── .gitattributes
├── .github
│ ├── pull_request_template.md
│ └── workflows
│ │ ├── build.yml
│ │ └── upgrade-dependencies.yml
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── aws.xml
│ ├── infra-async.iml
│ ├── inspectionProfiles
│ │ └── Project_Default.xml
│ ├── jsLinters
│ │ └── eslint.xml
│ ├── modules.xml
│ └── vcs.xml
├── .mergify.yml
├── .npmignore
├── .projen
│ ├── deps.json
│ └── tasks.json
├── .projenrc.js
├── .versionrc.json
├── LICENSE
├── README.md
├── cdk.json
├── package.json
├── src
│ ├── PubSubStack.QueueHandler.ts
│ ├── PubSubStack.ts
│ ├── main.ts
│ └── test-handlers
│ │ ├── CheckForDLQMessage.handler.ts
│ │ ├── SendCfnResponse.handler.ts
│ │ └── StartTests.handler.ts
├── test
│ ├── __snapshots__
│ │ └── main.test.ts.snap
│ └── main.test.ts
├── tsconfig.eslint.json
├── tsconfig.jest.json
├── tsconfig.json
└── yarn.lock
└── refactoring
├── .eslintrc.json
├── .gitattributes
├── .github
├── pull_request_template.md
└── workflows
│ ├── build.yml
│ ├── stale.yml
│ └── upgrade.yml
├── .gitignore
├── .idea
├── .gitignore
├── aws.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jsLibraryMappings.xml
├── jsLinters
│ └── eslint.xml
├── modules.xml
├── refactoring.iml
└── vcs.xml
├── .mergify.yml
├── .npmignore
├── .projen
├── deps.json
└── tasks.json
├── .projenrc.js
├── LICENSE
├── README.md
├── cdk.json
├── package-lock.json
├── package.json
├── src
├── LogicalIdMapper.ts
├── OriginalStack.ts
├── RefactoredStack.ts
├── SomeConstruct.ts
└── main.ts
├── test
├── __snapshots__
│ └── main.test.ts.snap
└── main.test.ts
├── tsconfig.eslint.json
├── tsconfig.jest.json
├── tsconfig.json
└── yarn.lock
/.github/issue_template.md:
--------------------------------------------------------------------------------
1 | I'd like to see an example of...
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/aws.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Examples for The CDK Book
2 |
3 | # TOC
4 |
5 | * chapters - These are related to various sections of The CDK Book
6 | * testing
7 | * infra-apig - Testing Chapter, use case #2
8 | * infra-async - Testing Chapter, use case #3
9 | * api-endpoint - An example of creating API Gateway REST endpoints
--------------------------------------------------------------------------------
/api-endpoint/.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.dev.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.dev.json",
31 | "alwaysTryTypes": true
32 | }
33 | }
34 | },
35 | "ignorePatterns": [
36 | "*.js",
37 | "!.projenrc.js",
38 | "*.d.ts",
39 | "node_modules/",
40 | "*.generated.ts",
41 | "coverage"
42 | ],
43 | "rules": {
44 | "indent": [
45 | "off"
46 | ],
47 | "@typescript-eslint/indent": [
48 | "error",
49 | 2
50 | ],
51 | "quotes": [
52 | "error",
53 | "single",
54 | {
55 | "avoidEscape": true
56 | }
57 | ],
58 | "comma-dangle": [
59 | "error",
60 | "always-multiline"
61 | ],
62 | "comma-spacing": [
63 | "error",
64 | {
65 | "before": false,
66 | "after": true
67 | }
68 | ],
69 | "no-multi-spaces": [
70 | "error",
71 | {
72 | "ignoreEOLComments": false
73 | }
74 | ],
75 | "array-bracket-spacing": [
76 | "error",
77 | "never"
78 | ],
79 | "array-bracket-newline": [
80 | "error",
81 | "consistent"
82 | ],
83 | "object-curly-spacing": [
84 | "error",
85 | "always"
86 | ],
87 | "object-curly-newline": [
88 | "error",
89 | {
90 | "multiline": true,
91 | "consistent": true
92 | }
93 | ],
94 | "object-property-newline": [
95 | "error",
96 | {
97 | "allowAllPropertiesOnSameLine": true
98 | }
99 | ],
100 | "keyword-spacing": [
101 | "error"
102 | ],
103 | "brace-style": [
104 | "error",
105 | "1tbs",
106 | {
107 | "allowSingleLine": true
108 | }
109 | ],
110 | "space-before-blocks": [
111 | "error"
112 | ],
113 | "curly": [
114 | "error",
115 | "multi-line",
116 | "consistent"
117 | ],
118 | "@typescript-eslint/member-delimiter-style": [
119 | "error"
120 | ],
121 | "semi": [
122 | "error",
123 | "always"
124 | ],
125 | "max-len": [
126 | "error",
127 | {
128 | "code": 150,
129 | "ignoreUrls": true,
130 | "ignoreStrings": true,
131 | "ignoreTemplateLiterals": true,
132 | "ignoreComments": true,
133 | "ignoreRegExpLiterals": true
134 | }
135 | ],
136 | "quote-props": [
137 | "error",
138 | "consistent-as-needed"
139 | ],
140 | "@typescript-eslint/no-require-imports": [
141 | "error"
142 | ],
143 | "import/no-extraneous-dependencies": [
144 | "error",
145 | {
146 | "devDependencies": [
147 | "**/test/**",
148 | "**/build-tools/**",
149 | "src/handlers/newsletter/newsletter.lambda.ts",
150 | "src/handlers/reviews/reviews-handler.lambda.ts"
151 | ],
152 | "optionalDependencies": false,
153 | "peerDependencies": true
154 | }
155 | ],
156 | "import/no-unresolved": [
157 | "error"
158 | ],
159 | "import/order": [
160 | "warn",
161 | {
162 | "groups": [
163 | "builtin",
164 | "external"
165 | ],
166 | "alphabetize": {
167 | "order": "asc",
168 | "caseInsensitive": true
169 | }
170 | }
171 | ],
172 | "no-duplicate-imports": [
173 | "error"
174 | ],
175 | "no-shadow": [
176 | "off"
177 | ],
178 | "@typescript-eslint/no-shadow": [
179 | "error"
180 | ],
181 | "key-spacing": [
182 | "error"
183 | ],
184 | "no-multiple-empty-lines": [
185 | "error"
186 | ],
187 | "@typescript-eslint/no-floating-promises": [
188 | "error"
189 | ],
190 | "no-return-await": [
191 | "off"
192 | ],
193 | "@typescript-eslint/return-await": [
194 | "error"
195 | ],
196 | "no-trailing-spaces": [
197 | "error"
198 | ],
199 | "dot-notation": [
200 | "error"
201 | ],
202 | "no-bitwise": [
203 | "error"
204 | ],
205 | "@typescript-eslint/member-ordering": [
206 | "error",
207 | {
208 | "default": [
209 | "public-static-field",
210 | "public-static-method",
211 | "protected-static-field",
212 | "protected-static-method",
213 | "private-static-field",
214 | "private-static-method",
215 | "field",
216 | "constructor",
217 | "method"
218 | ]
219 | }
220 | ]
221 | },
222 | "overrides": [
223 | {
224 | "files": [
225 | ".projenrc.js"
226 | ],
227 | "rules": {
228 | "@typescript-eslint/no-require-imports": "off",
229 | "import/no-extraneous-dependencies": "off"
230 | }
231 | }
232 | ]
233 | }
234 |
--------------------------------------------------------------------------------
/api-endpoint/.gitattributes:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | *.snap linguist-generated
4 | /.eslintrc.json linguist-generated
5 | /.gitattributes linguist-generated
6 | /.github/pull_request_template.md linguist-generated
7 | /.github/workflows/build.yml linguist-generated
8 | /.github/workflows/pull-request-lint.yml linguist-generated
9 | /.github/workflows/upgrade.yml linguist-generated
10 | /.gitignore linguist-generated
11 | /.mergify.yml linguist-generated
12 | /.npmignore linguist-generated
13 | /.projen/** linguist-generated
14 | /.projen/deps.json linguist-generated
15 | /.projen/files.json linguist-generated
16 | /.projen/tasks.json linguist-generated
17 | /cdk.json linguist-generated
18 | /LICENSE linguist-generated
19 | /package.json linguist-generated
20 | /src/handlers/newsletter/newsletter-function.ts linguist-generated
21 | /src/handlers/reviews/reviews-handler-function.ts linguist-generated
22 | /tsconfig.dev.json linguist-generated
23 | /tsconfig.json linguist-generated
24 | /yarn.lock linguist-generated
--------------------------------------------------------------------------------
/api-endpoint/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes #
--------------------------------------------------------------------------------
/api-endpoint/.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 | permissions:
11 | contents: write
12 | outputs:
13 | self_mutation_happened: ${{ steps.self_mutation.outputs.self_mutation_happened }}
14 | env:
15 | CI: "true"
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | with:
20 | ref: ${{ github.event.pull_request.head.ref }}
21 | repository: ${{ github.event.pull_request.head.repo.full_name }}
22 | - name: Install dependencies
23 | run: yarn install --check-files
24 | - name: build
25 | run: npx projen build
26 | - id: self_mutation
27 | name: Find mutations
28 | run: |-
29 | git add .
30 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=self_mutation_happened::true"
31 | - if: steps.self_mutation.outputs.self_mutation_happened
32 | name: Upload patch
33 | uses: actions/upload-artifact@v2
34 | with:
35 | name: .repo.patch
36 | path: .repo.patch
37 | - name: Fail build on mutation
38 | if: steps.self_mutation.outputs.self_mutation_happened
39 | run: |-
40 | echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch."
41 | cat .repo.patch
42 | exit 1
43 | self-mutation:
44 | needs: build
45 | runs-on: ubuntu-latest
46 | permissions:
47 | contents: write
48 | if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository)
49 | steps:
50 | - name: Checkout
51 | uses: actions/checkout@v2
52 | with:
53 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
54 | ref: ${{ github.event.pull_request.head.ref }}
55 | repository: ${{ github.event.pull_request.head.repo.full_name }}
56 | - name: Download patch
57 | uses: actions/download-artifact@v2
58 | with:
59 | name: .repo.patch
60 | path: ${{ runner.temp }}
61 | - name: Apply patch
62 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."'
63 | - name: Set git identity
64 | run: |-
65 | git config user.name "github-actions"
66 | git config user.email "github-actions@github.com"
67 | - name: Push changes
68 | run: |2-
69 | git add .
70 | git commit -s -m "chore: self mutation"
71 | git push origin HEAD:${{ github.event.pull_request.head.ref }}
72 |
--------------------------------------------------------------------------------
/api-endpoint/.github/workflows/pull-request-lint.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js 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 | jobs:
14 | validate:
15 | name: Validate PR title
16 | runs-on: ubuntu-latest
17 | permissions:
18 | pull-requests: write
19 | steps:
20 | - uses: amannn/action-semantic-pull-request@v3.4.6
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | with:
24 | types: |-
25 | feat
26 | fix
27 | chore
28 | requireScope: false
29 |
--------------------------------------------------------------------------------
/api-endpoint/.github/workflows/upgrade.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: upgrade
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@v2
19 | - name: Install dependencies
20 | run: yarn install --check-files --frozen-lockfile
21 | - name: Upgrade dependencies
22 | run: npx projen upgrade
23 | - id: create_patch
24 | name: Find mutations
25 | run: |-
26 | git add .
27 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=patch_created::true"
28 | - if: steps.create_patch.outputs.patch_created
29 | name: Upload patch
30 | uses: actions/upload-artifact@v2
31 | with:
32 | name: .repo.patch
33 | path: .repo.patch
34 | pr:
35 | name: Create Pull Request
36 | needs: upgrade
37 | runs-on: ubuntu-latest
38 | permissions:
39 | contents: write
40 | pull-requests: write
41 | if: ${{ needs.upgrade.outputs.patch_created }}
42 | steps:
43 | - name: Checkout
44 | uses: actions/checkout@v2
45 | with:
46 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
47 | - name: Download patch
48 | uses: actions/download-artifact@v2
49 | with:
50 | name: .repo.patch
51 | path: ${{ runner.temp }}
52 | - name: Apply patch
53 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."'
54 | - name: Set git identity
55 | run: |-
56 | git config user.name "github-actions"
57 | git config user.email "github-actions@github.com"
58 | - name: Create Pull Request
59 | id: create-pr
60 | uses: peter-evans/create-pull-request@v3
61 | with:
62 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
63 | commit-message: |-
64 | chore(deps): upgrade dependencies
65 |
66 | Upgrades project dependencies. See details in [workflow run].
67 |
68 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
69 |
70 | ------
71 |
72 | *Automatically created by projen via the "upgrade" workflow*
73 | branch: github-actions/upgrade
74 | title: "chore(deps): upgrade dependencies"
75 | body: |-
76 | Upgrades project dependencies. See details in [workflow run].
77 |
78 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
79 |
80 | ------
81 |
82 | *Automatically created by projen via the "upgrade" workflow*
83 | author: github-actions
84 | committer: github-actions
85 | signoff: true
86 |
--------------------------------------------------------------------------------
/api-endpoint/.gitignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js 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 | !/package.json
8 | !/LICENSE
9 | !/.npmignore
10 | logs
11 | *.log
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 | lerna-debug.log*
16 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
17 | pids
18 | *.pid
19 | *.seed
20 | *.pid.lock
21 | lib-cov
22 | coverage
23 | *.lcov
24 | .nyc_output
25 | build/Release
26 | node_modules/
27 | jspm_packages/
28 | *.tsbuildinfo
29 | .eslintcache
30 | *.tgz
31 | .yarn-integrity
32 | .cache
33 | .idea/
34 | !/.projenrc.js
35 | /test-reports/
36 | junit.xml
37 | /coverage/
38 | !/.github/workflows/build.yml
39 | !/.mergify.yml
40 | !/.github/workflows/upgrade.yml
41 | !/.github/pull_request_template.md
42 | !/test/
43 | !/tsconfig.json
44 | !/tsconfig.dev.json
45 | !/src/
46 | /lib
47 | /dist/
48 | !/.eslintrc.json
49 | /assets/
50 | !/cdk.json
51 | /cdk.out/
52 | .cdk.staging/
53 | .parcel-cache/
54 | !/src/handlers/newsletter/newsletter-function.ts
55 | !/src/handlers/reviews/reviews-handler-function.ts
56 |
--------------------------------------------------------------------------------
/api-endpoint/.mergify.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | queue_rules:
4 | - name: default
5 | conditions:
6 | - "#approved-reviews-by>=1"
7 | - -label~=(do-not-merge)
8 | - status-success=build
9 | pull_request_rules:
10 | - name: Automatic merge on approval and successful build
11 | actions:
12 | delete_head_branch: {}
13 | queue:
14 | method: squash
15 | name: default
16 | commit_message_template: |-
17 | {{ title }} (#{{ number }})
18 |
19 | {{ body }}
20 | conditions:
21 | - "#approved-reviews-by>=1"
22 | - -label~=(do-not-merge)
23 | - status-success=build
24 |
--------------------------------------------------------------------------------
/api-endpoint/.npmignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | /.projen/
3 | /test-reports/
4 | junit.xml
5 | /coverage/
6 | /.mergify.yml
7 | /test/
8 | /tsconfig.dev.json
9 | /src/
10 | !/lib/
11 | !/lib/**/*.js
12 | !/lib/**/*.d.ts
13 | dist
14 | /tsconfig.json
15 | /.github/
16 | /.vscode/
17 | /.idea/
18 | /.projenrc.js
19 | tsconfig.tsbuildinfo
20 | /.eslintrc.json
21 | !/assets/
22 | cdk.out/
23 | .cdk.staging/
24 |
--------------------------------------------------------------------------------
/api-endpoint/.projen/deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "name": "@types/jest",
5 | "type": "build"
6 | },
7 | {
8 | "name": "@types/node",
9 | "version": "^12",
10 | "type": "build"
11 | },
12 | {
13 | "name": "@typescript-eslint/eslint-plugin",
14 | "version": "^5",
15 | "type": "build"
16 | },
17 | {
18 | "name": "@typescript-eslint/parser",
19 | "version": "^5",
20 | "type": "build"
21 | },
22 | {
23 | "name": "aws-cdk",
24 | "version": "^2.4.0",
25 | "type": "build"
26 | },
27 | {
28 | "name": "esbuild",
29 | "type": "build"
30 | },
31 | {
32 | "name": "eslint-import-resolver-node",
33 | "type": "build"
34 | },
35 | {
36 | "name": "eslint-import-resolver-typescript",
37 | "type": "build"
38 | },
39 | {
40 | "name": "eslint-plugin-import",
41 | "type": "build"
42 | },
43 | {
44 | "name": "eslint",
45 | "version": "^8",
46 | "type": "build"
47 | },
48 | {
49 | "name": "jest",
50 | "type": "build"
51 | },
52 | {
53 | "name": "jest-junit",
54 | "version": "^13",
55 | "type": "build"
56 | },
57 | {
58 | "name": "json-schema",
59 | "type": "build"
60 | },
61 | {
62 | "name": "npm-check-updates",
63 | "version": "^12",
64 | "type": "build"
65 | },
66 | {
67 | "name": "projen",
68 | "type": "build"
69 | },
70 | {
71 | "name": "ts-jest",
72 | "type": "build"
73 | },
74 | {
75 | "name": "ts-node",
76 | "version": "^9",
77 | "type": "build"
78 | },
79 | {
80 | "name": "typescript",
81 | "type": "build"
82 | },
83 | {
84 | "name": "@types/aws-lambda",
85 | "type": "runtime"
86 | },
87 | {
88 | "name": "aws-cdk-lib",
89 | "version": "^2.4.0",
90 | "type": "runtime"
91 | },
92 | {
93 | "name": "constructs",
94 | "version": "^10.0.5",
95 | "type": "runtime"
96 | }
97 | ],
98 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
99 | }
100 |
--------------------------------------------------------------------------------
/api-endpoint/.projen/files.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | ".eslintrc.json",
4 | ".gitattributes",
5 | ".github/pull_request_template.md",
6 | ".github/workflows/build.yml",
7 | ".github/workflows/pull-request-lint.yml",
8 | ".github/workflows/upgrade.yml",
9 | ".gitignore",
10 | ".mergify.yml",
11 | ".npmignore",
12 | ".projen/deps.json",
13 | ".projen/files.json",
14 | ".projen/tasks.json",
15 | "cdk.json",
16 | "LICENSE",
17 | "src/handlers/newsletter/newsletter-function.ts",
18 | "src/handlers/reviews/reviews-handler-function.ts",
19 | "tsconfig.dev.json",
20 | "tsconfig.json"
21 | ],
22 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
23 | }
24 |
--------------------------------------------------------------------------------
/api-endpoint/.projen/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": {
3 | "build": {
4 | "name": "build",
5 | "description": "Full release build",
6 | "steps": [
7 | {
8 | "spawn": "default"
9 | },
10 | {
11 | "spawn": "pre-compile"
12 | },
13 | {
14 | "spawn": "compile"
15 | },
16 | {
17 | "spawn": "post-compile"
18 | },
19 | {
20 | "spawn": "test"
21 | },
22 | {
23 | "spawn": "package"
24 | }
25 | ]
26 | },
27 | "bundle": {
28 | "name": "bundle",
29 | "description": "Prepare assets",
30 | "steps": [
31 | {
32 | "spawn": "bundle:handlers/newsletter/newsletter.lambda"
33 | },
34 | {
35 | "spawn": "bundle:handlers/reviews/reviews-handler.lambda"
36 | }
37 | ]
38 | },
39 | "bundle:handlers/newsletter/newsletter.lambda": {
40 | "name": "bundle:handlers/newsletter/newsletter.lambda",
41 | "description": "Create a JavaScript bundle from src/handlers/newsletter/newsletter.lambda.ts",
42 | "steps": [
43 | {
44 | "exec": "esbuild --bundle src/handlers/newsletter/newsletter.lambda.ts --target=\"node14\" --platform=\"node\" --outfile=\"assets/handlers/newsletter/newsletter.lambda/index.js\" --external:aws-sdk"
45 | }
46 | ]
47 | },
48 | "bundle:handlers/newsletter/newsletter.lambda:watch": {
49 | "name": "bundle:handlers/newsletter/newsletter.lambda:watch",
50 | "description": "Continuously update the JavaScript bundle from src/handlers/newsletter/newsletter.lambda.ts",
51 | "steps": [
52 | {
53 | "exec": "esbuild --bundle src/handlers/newsletter/newsletter.lambda.ts --target=\"node14\" --platform=\"node\" --outfile=\"assets/handlers/newsletter/newsletter.lambda/index.js\" --external:aws-sdk --watch"
54 | }
55 | ]
56 | },
57 | "bundle:handlers/reviews/reviews-handler.lambda": {
58 | "name": "bundle:handlers/reviews/reviews-handler.lambda",
59 | "description": "Create a JavaScript bundle from src/handlers/reviews/reviews-handler.lambda.ts",
60 | "steps": [
61 | {
62 | "exec": "esbuild --bundle src/handlers/reviews/reviews-handler.lambda.ts --target=\"node14\" --platform=\"node\" --outfile=\"assets/handlers/reviews/reviews-handler.lambda/index.js\" --external:aws-sdk"
63 | }
64 | ]
65 | },
66 | "bundle:handlers/reviews/reviews-handler.lambda:watch": {
67 | "name": "bundle:handlers/reviews/reviews-handler.lambda:watch",
68 | "description": "Continuously update the JavaScript bundle from src/handlers/reviews/reviews-handler.lambda.ts",
69 | "steps": [
70 | {
71 | "exec": "esbuild --bundle src/handlers/reviews/reviews-handler.lambda.ts --target=\"node14\" --platform=\"node\" --outfile=\"assets/handlers/reviews/reviews-handler.lambda/index.js\" --external:aws-sdk --watch"
72 | }
73 | ]
74 | },
75 | "clobber": {
76 | "name": "clobber",
77 | "description": "hard resets to HEAD of origin and cleans the local repo",
78 | "env": {
79 | "BRANCH": "$(git branch --show-current)"
80 | },
81 | "steps": [
82 | {
83 | "exec": "git checkout -b scratch",
84 | "name": "save current HEAD in \"scratch\" branch"
85 | },
86 | {
87 | "exec": "git checkout $BRANCH"
88 | },
89 | {
90 | "exec": "git fetch origin",
91 | "name": "fetch latest changes from origin"
92 | },
93 | {
94 | "exec": "git reset --hard origin/$BRANCH",
95 | "name": "hard reset to origin commit"
96 | },
97 | {
98 | "exec": "git clean -fdx",
99 | "name": "clean all untracked files"
100 | },
101 | {
102 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)"
103 | }
104 | ],
105 | "condition": "git diff --exit-code > /dev/null"
106 | },
107 | "compile": {
108 | "name": "compile",
109 | "description": "Only compile"
110 | },
111 | "default": {
112 | "name": "default",
113 | "description": "Synthesize project files",
114 | "steps": [
115 | {
116 | "exec": "node .projenrc.js"
117 | }
118 | ]
119 | },
120 | "deploy": {
121 | "name": "deploy",
122 | "description": "Deploys your CDK app to the AWS cloud",
123 | "steps": [
124 | {
125 | "exec": "cdk deploy"
126 | }
127 | ]
128 | },
129 | "destroy": {
130 | "name": "destroy",
131 | "description": "Destroys your cdk app in the AWS cloud",
132 | "steps": [
133 | {
134 | "exec": "cdk destroy"
135 | }
136 | ]
137 | },
138 | "diff": {
139 | "name": "diff",
140 | "description": "Diffs the currently deployed app against your code",
141 | "steps": [
142 | {
143 | "exec": "cdk diff"
144 | }
145 | ]
146 | },
147 | "eject": {
148 | "name": "eject",
149 | "description": "Remove projen from the project",
150 | "env": {
151 | "PROJEN_EJECTING": "true"
152 | },
153 | "steps": [
154 | {
155 | "spawn": "default"
156 | }
157 | ]
158 | },
159 | "eslint": {
160 | "name": "eslint",
161 | "description": "Runs eslint against the codebase",
162 | "steps": [
163 | {
164 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js"
165 | }
166 | ]
167 | },
168 | "package": {
169 | "name": "package",
170 | "description": "Creates the distribution package"
171 | },
172 | "post-compile": {
173 | "name": "post-compile",
174 | "description": "Runs after successful compilation",
175 | "steps": [
176 | {
177 | "spawn": "synth:silent"
178 | }
179 | ]
180 | },
181 | "post-upgrade": {
182 | "name": "post-upgrade",
183 | "description": "Runs after upgrading dependencies"
184 | },
185 | "pre-compile": {
186 | "name": "pre-compile",
187 | "description": "Prepare the project for compilation"
188 | },
189 | "synth": {
190 | "name": "synth",
191 | "description": "Synthesizes your cdk app into cdk.out",
192 | "steps": [
193 | {
194 | "exec": "cdk synth"
195 | }
196 | ]
197 | },
198 | "synth:silent": {
199 | "name": "synth:silent",
200 | "description": "Synthesizes your cdk app into cdk.out and suppresses the template in stdout (part of \"yarn build\")",
201 | "steps": [
202 | {
203 | "exec": "cdk synth > /dev/null"
204 | }
205 | ]
206 | },
207 | "test": {
208 | "name": "test",
209 | "description": "Run tests",
210 | "steps": [
211 | {
212 | "exec": "jest --passWithNoTests --all --updateSnapshot"
213 | },
214 | {
215 | "spawn": "eslint"
216 | }
217 | ]
218 | },
219 | "test:update": {
220 | "name": "test:update",
221 | "description": "Update jest snapshots",
222 | "steps": [
223 | {
224 | "exec": "jest --updateSnapshot"
225 | }
226 | ]
227 | },
228 | "test:watch": {
229 | "name": "test:watch",
230 | "description": "Run jest in watch mode",
231 | "steps": [
232 | {
233 | "exec": "jest --watch"
234 | }
235 | ]
236 | },
237 | "upgrade": {
238 | "name": "upgrade",
239 | "description": "upgrade dependencies",
240 | "env": {
241 | "CI": "0"
242 | },
243 | "steps": [
244 | {
245 | "exec": "yarn upgrade npm-check-updates"
246 | },
247 | {
248 | "exec": "npm-check-updates --dep dev --upgrade --target=minor"
249 | },
250 | {
251 | "exec": "npm-check-updates --dep optional --upgrade --target=minor"
252 | },
253 | {
254 | "exec": "npm-check-updates --dep peer --upgrade --target=minor"
255 | },
256 | {
257 | "exec": "npm-check-updates --dep prod --upgrade --target=minor"
258 | },
259 | {
260 | "exec": "npm-check-updates --dep bundle --upgrade --target=minor"
261 | },
262 | {
263 | "exec": "yarn install --check-files"
264 | },
265 | {
266 | "exec": "yarn upgrade"
267 | },
268 | {
269 | "exec": "npx projen"
270 | },
271 | {
272 | "spawn": "post-upgrade"
273 | }
274 | ]
275 | },
276 | "watch": {
277 | "name": "watch",
278 | "description": "Watches changes in your source code and rebuilds and deploys to the current account",
279 | "steps": [
280 | {
281 | "exec": "cdk deploy --hotswap"
282 | },
283 | {
284 | "exec": "cdk watch"
285 | }
286 | ]
287 | }
288 | },
289 | "env": {
290 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")"
291 | },
292 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
293 | }
294 |
--------------------------------------------------------------------------------
/api-endpoint/.projenrc.js:
--------------------------------------------------------------------------------
1 | const { awscdk } = require('projen');
2 | const project = new awscdk.AwsCdkTypeScriptApp({
3 | cdkVersion: '2.4.0',
4 | defaultReleaseBranch: 'main',
5 | name: 'api-endpoint',
6 | deps: ['@types/aws-lambda'],
7 | gitignore: ['.idea/'],
8 | });
9 | project.synth();
--------------------------------------------------------------------------------
/api-endpoint/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/api-endpoint/README.md:
--------------------------------------------------------------------------------
1 | # replace this
--------------------------------------------------------------------------------
/api-endpoint/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node -P tsconfig.json --prefer-ts-exts src/main.ts",
3 | "output": "cdk.out",
4 | "build": "npx projen bundle",
5 | "watch": {
6 | "include": [
7 | "src/**/*.ts",
8 | "test/**/*.ts"
9 | ],
10 | "exclude": [
11 | "README.md",
12 | "cdk*.json",
13 | "**/*.d.ts",
14 | "**/*.js",
15 | "tsconfig.json",
16 | "package*.json",
17 | "yarn.lock",
18 | "node_modules"
19 | ]
20 | },
21 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
22 | }
23 |
--------------------------------------------------------------------------------
/api-endpoint/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-endpoint",
3 | "scripts": {
4 | "build": "npx projen build",
5 | "bundle": "npx projen bundle",
6 | "bundle:handlers/newsletter/newsletter.lambda": "npx projen bundle:handlers/newsletter/newsletter.lambda",
7 | "bundle:handlers/newsletter/newsletter.lambda:watch": "npx projen bundle:handlers/newsletter/newsletter.lambda:watch",
8 | "bundle:handlers/reviews/reviews-handler.lambda": "npx projen bundle:handlers/reviews/reviews-handler.lambda",
9 | "bundle:handlers/reviews/reviews-handler.lambda:watch": "npx projen bundle:handlers/reviews/reviews-handler.lambda:watch",
10 | "clobber": "npx projen clobber",
11 | "compile": "npx projen compile",
12 | "default": "npx projen default",
13 | "deploy": "npx projen deploy",
14 | "destroy": "npx projen destroy",
15 | "diff": "npx projen diff",
16 | "eject": "npx projen eject",
17 | "eslint": "npx projen eslint",
18 | "package": "npx projen package",
19 | "post-compile": "npx projen post-compile",
20 | "post-upgrade": "npx projen post-upgrade",
21 | "pre-compile": "npx projen pre-compile",
22 | "synth": "npx projen synth",
23 | "synth:silent": "npx projen synth:silent",
24 | "test": "npx projen test",
25 | "test:update": "npx projen test:update",
26 | "test:watch": "npx projen test:watch",
27 | "upgrade": "npx projen upgrade",
28 | "watch": "npx projen watch",
29 | "projen": "npx projen"
30 | },
31 | "devDependencies": {
32 | "@types/jest": "^27.4.1",
33 | "@types/node": "^12",
34 | "@typescript-eslint/eslint-plugin": "^5",
35 | "@typescript-eslint/parser": "^5",
36 | "aws-cdk": "^2.4.0",
37 | "esbuild": "^0.14.36",
38 | "eslint": "^8",
39 | "eslint-import-resolver-node": "^0.3.6",
40 | "eslint-import-resolver-typescript": "^2.7.1",
41 | "eslint-plugin-import": "^2.26.0",
42 | "jest": "^27.5.1",
43 | "jest-junit": "^13",
44 | "json-schema": "^0.4.0",
45 | "npm-check-updates": "^12",
46 | "projen": "^0.54.29",
47 | "ts-jest": "^27.1.4",
48 | "ts-node": "^9",
49 | "typescript": "^4.6.3"
50 | },
51 | "dependencies": {
52 | "@types/aws-lambda": "^8.10.93",
53 | "aws-cdk-lib": "^2.4.0",
54 | "constructs": "^10.0.5"
55 | },
56 | "license": "Apache-2.0",
57 | "version": "0.0.0",
58 | "jest": {
59 | "testMatch": [
60 | "/src/**/__tests__/**/*.ts?(x)",
61 | "/(test|src)/**/?(*.)+(spec|test).ts?(x)"
62 | ],
63 | "clearMocks": true,
64 | "collectCoverage": true,
65 | "coverageReporters": [
66 | "json",
67 | "lcov",
68 | "clover",
69 | "cobertura",
70 | "text"
71 | ],
72 | "coverageDirectory": "coverage",
73 | "coveragePathIgnorePatterns": [
74 | "/node_modules/"
75 | ],
76 | "testPathIgnorePatterns": [
77 | "/node_modules/"
78 | ],
79 | "watchPathIgnorePatterns": [
80 | "/node_modules/"
81 | ],
82 | "reporters": [
83 | "default",
84 | [
85 | "jest-junit",
86 | {
87 | "outputDirectory": "test-reports"
88 | }
89 | ]
90 | ],
91 | "preset": "ts-jest",
92 | "globals": {
93 | "ts-jest": {
94 | "tsconfig": "tsconfig.dev.json"
95 | }
96 | }
97 | },
98 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
99 | }
--------------------------------------------------------------------------------
/api-endpoint/src/MyApiGatewayStack.ts:
--------------------------------------------------------------------------------
1 | import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
2 | import { LambdaIntegration, RestApi } from 'aws-cdk-lib/aws-apigateway';
3 | import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';
4 | import { ARecord, HostedZone, RecordTarget } from 'aws-cdk-lib/aws-route53';
5 | import { ApiGateway } from 'aws-cdk-lib/aws-route53-targets';
6 | import { Construct } from 'constructs';
7 | import { NewsletterFunction } from './handlers/newsletter/newsletter-function';
8 | import { ReviewsHandlerFunction } from './handlers/reviews/reviews-handler-function';
9 |
10 | export interface MyApiGatewayStackProps extends StackProps {
11 | /**
12 | * The ARN of the ACM certificate to use for the endpoint.
13 | */
14 | readonly certificateArn: string;
15 |
16 | /**
17 | * The Hosted Zone ID of the domain being used.
18 | */
19 | readonly hostedZoneId: string;
20 | }
21 |
22 | export class MyApiGatewayStack extends Stack {
23 | constructor(scope: Construct, id: string, props: MyApiGatewayStackProps) {
24 | super(scope, id, props);
25 |
26 | const api = new RestApi(this, 'Api', {
27 | description: 'A simple API example for The CDK Book',
28 | restApiName: 'TheCDKBookApi',
29 | deploy: true, // let's make this easier by always redeploying,
30 | deployOptions: {
31 | stageName: 'v1',
32 | throttlingRateLimit: 10,
33 | },
34 | domainName: {
35 | domainName: 'api.thecdkbook.com',
36 | certificate: Certificate.fromCertificateArn(this, 'ApiCertificate', props.certificateArn),
37 | },
38 | });
39 | this.createNewsletterResource(api);
40 | this.createReviewsResource(api);
41 | this.addDns(api, props);
42 | }
43 |
44 | private addDns(api: RestApi, props: MyApiGatewayStackProps) {
45 |
46 | const aRecord = new ARecord(this, 'ApiDNS', {
47 | recordName: 'api',
48 | zone: HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
49 | hostedZoneId: props.hostedZoneId,
50 | zoneName: 'thecdkbook.com',
51 | }),
52 | target: RecordTarget.fromAlias(new ApiGateway(api)),
53 | });
54 |
55 | new CfnOutput(this, 'ApiGatewayEndpoint', {
56 | value: aRecord.domainName,
57 | });
58 | }
59 |
60 | private createNewsletterResource(api: RestApi) {
61 | const newsletterHandler = new NewsletterFunction(this, 'NewsletterHandler');
62 | const lambdaIntegration = new LambdaIntegration(newsletterHandler);
63 | const newsletterResource = api.root.addResource('newsletter', {
64 | defaultCorsPreflightOptions: {
65 | allowCredentials: true,
66 | allowHeaders: ['*'],
67 | allowMethods: ['*'],
68 | allowOrigins: ['www.thecdkbook.com', 'thecdkbook.com'],
69 | },
70 | defaultIntegration: lambdaIntegration,
71 | });
72 | newsletterResource.addMethod('GET', lambdaIntegration, {});
73 | }
74 |
75 | private createReviewsResource(api: RestApi) {
76 | const reviewsHandler = new ReviewsHandlerFunction(this, 'ReviewsHandler');
77 | const lambdaIntegration = new LambdaIntegration(reviewsHandler);
78 | const reviewsResource = api.root.addResource('reviews', {
79 | defaultCorsPreflightOptions: {
80 | allowCredentials: true,
81 | allowHeaders: ['*'],
82 | allowMethods: ['*'],
83 | allowOrigins: ['www.thecdkbook.com', 'thecdkbook.com'],
84 | },
85 | defaultIntegration: lambdaIntegration,
86 | });
87 | reviewsResource.addMethod('GET', lambdaIntegration, {});
88 | }
89 | }
--------------------------------------------------------------------------------
/api-endpoint/src/handlers/newsletter/newsletter-function.ts:
--------------------------------------------------------------------------------
1 | // ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | import * as path from 'path';
3 | import * as lambda from 'aws-cdk-lib/aws-lambda';
4 | import { Construct } from 'constructs';
5 |
6 | /**
7 | * Props for NewsletterFunction
8 | */
9 | export interface NewsletterFunctionProps extends lambda.FunctionOptions {
10 | }
11 |
12 | /**
13 | * An AWS Lambda function which executes src/handlers/newsletter/newsletter.
14 | */
15 | export class NewsletterFunction extends lambda.Function {
16 | constructor(scope: Construct, id: string, props?: NewsletterFunctionProps) {
17 | super(scope, id, {
18 | description: 'src/handlers/newsletter/newsletter.lambda.ts',
19 | ...props,
20 | runtime: lambda.Runtime.NODEJS_14_X,
21 | handler: 'index.handler',
22 | code: lambda.Code.fromAsset(path.join(__dirname, '../../../assets/handlers/newsletter/newsletter.lambda')),
23 | });
24 | this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true });
25 | }
26 | }
--------------------------------------------------------------------------------
/api-endpoint/src/handlers/newsletter/newsletter.lambda.ts:
--------------------------------------------------------------------------------
1 | import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
2 |
3 | export const handler = async (event: APIGatewayProxyEvent): Promise => {
4 | console.log('event: ', JSON.stringify(event, null, 2));
5 | return {
6 | body: 'This is your latest newsletter...',
7 | headers: {},
8 | isBase64Encoded: false,
9 | statusCode: 200,
10 | };
11 | };
--------------------------------------------------------------------------------
/api-endpoint/src/handlers/reviews/reviews-handler-function.ts:
--------------------------------------------------------------------------------
1 | // ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | import * as path from 'path';
3 | import * as lambda from 'aws-cdk-lib/aws-lambda';
4 | import { Construct } from 'constructs';
5 |
6 | /**
7 | * Props for ReviewsHandlerFunction
8 | */
9 | export interface ReviewsHandlerFunctionProps extends lambda.FunctionOptions {
10 | }
11 |
12 | /**
13 | * An AWS Lambda function which executes src/handlers/reviews/reviews-handler.
14 | */
15 | export class ReviewsHandlerFunction extends lambda.Function {
16 | constructor(scope: Construct, id: string, props?: ReviewsHandlerFunctionProps) {
17 | super(scope, id, {
18 | description: 'src/handlers/reviews/reviews-handler.lambda.ts',
19 | ...props,
20 | runtime: lambda.Runtime.NODEJS_14_X,
21 | handler: 'index.handler',
22 | code: lambda.Code.fromAsset(path.join(__dirname, '../../../assets/handlers/reviews/reviews-handler.lambda')),
23 | });
24 | this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true });
25 | }
26 | }
--------------------------------------------------------------------------------
/api-endpoint/src/handlers/reviews/reviews-handler.lambda.ts:
--------------------------------------------------------------------------------
1 | import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
2 |
3 | export const handler = async (event: APIGatewayProxyEvent): Promise => {
4 | console.log('event: ', JSON.stringify(event, null, 2));
5 | return {
6 | body: JSON.stringify([{
7 | author: 'Matthew Bonig',
8 | stars: 4,
9 | comment: 'Yeah, it\'s a pretty good book.',
10 | }]),
11 | headers: {},
12 | isBase64Encoded: false,
13 | statusCode: 200,
14 | };
15 | };
--------------------------------------------------------------------------------
/api-endpoint/src/main.ts:
--------------------------------------------------------------------------------
1 | import { App } from 'aws-cdk-lib';
2 | import { MyApiGatewayStack } from './MyApiGatewayStack';
3 |
4 | const devEnv = {
5 | account: process.env.CDK_DEFAULT_ACCOUNT,
6 | region: process.env.CDK_DEFAULT_REGION,
7 | };
8 |
9 | const app = new App();
10 |
11 | new MyApiGatewayStack(app, 'MyApi', {
12 | env: devEnv,
13 | certificateArn: 'arn:aws:acm:us-east-1:536309290949:certificate/92dbf914-21fc-4132-a915-4b67eb029d75',
14 | hostedZoneId: 'Z09129483SE6UWS2RDQ9Z',
15 | });
16 |
17 | app.synth();
--------------------------------------------------------------------------------
/api-endpoint/test/main.test.ts:
--------------------------------------------------------------------------------
1 | import '@aws-cdk/assert/jest';
2 | import { App } from '@aws-cdk/core';
3 | import { MyApiGatewayStack } from "../src/MyApiGatewayStack";
4 |
5 | test('Snapshot', () => {
6 | const app = new App();
7 | const stack = new MyApiGatewayStack(app, 'test');
8 |
9 | expect(stack).not.toHaveResource('AWS::S3::Bucket');
10 | expect(app.synth().getStackArtifact(stack.artifactId).template).toMatchSnapshot();
11 | });
--------------------------------------------------------------------------------
/api-endpoint/tsconfig.dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "alwaysStrict": true,
4 | "declaration": true,
5 | "esModuleInterop": true,
6 | "experimentalDecorators": true,
7 | "inlineSourceMap": true,
8 | "inlineSources": true,
9 | "lib": [
10 | "es2019"
11 | ],
12 | "module": "CommonJS",
13 | "noEmitOnError": false,
14 | "noFallthroughCasesInSwitch": true,
15 | "noImplicitAny": true,
16 | "noImplicitReturns": true,
17 | "noImplicitThis": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "resolveJsonModule": true,
21 | "strict": true,
22 | "strictNullChecks": true,
23 | "strictPropertyInitialization": true,
24 | "stripInternal": true,
25 | "target": "ES2019"
26 | },
27 | "include": [
28 | ".projenrc.js",
29 | "src/**/*.ts",
30 | "test/**/*.ts"
31 | ],
32 | "exclude": [
33 | "node_modules"
34 | ],
35 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
36 | }
37 |
--------------------------------------------------------------------------------
/api-endpoint/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": "src",
4 | "outDir": "lib",
5 | "alwaysStrict": true,
6 | "declaration": true,
7 | "esModuleInterop": true,
8 | "experimentalDecorators": true,
9 | "inlineSourceMap": true,
10 | "inlineSources": true,
11 | "lib": [
12 | "es2019"
13 | ],
14 | "module": "CommonJS",
15 | "noEmitOnError": false,
16 | "noFallthroughCasesInSwitch": true,
17 | "noImplicitAny": true,
18 | "noImplicitReturns": true,
19 | "noImplicitThis": true,
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | "resolveJsonModule": true,
23 | "strict": true,
24 | "strictNullChecks": true,
25 | "strictPropertyInitialization": true,
26 | "stripInternal": true,
27 | "target": "ES2019"
28 | },
29 | "include": [
30 | "src/**/*.ts"
31 | ],
32 | "exclude": [
33 | "cdk.out"
34 | ],
35 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
36 | }
37 |
--------------------------------------------------------------------------------
/chapters/project-layout/lots-of-lambdas/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdkbook/examples/f6e4bcf6099d04b03f695bbccf638503bad9b831/chapters/project-layout/lots-of-lambdas/README.md
--------------------------------------------------------------------------------
/chapters/project-layout/more-complexity/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdkbook/examples/f6e4bcf6099d04b03f695bbccf638503bad9b831/chapters/project-layout/more-complexity/README.md
--------------------------------------------------------------------------------
/chapters/testing/basic-snapshot-test/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdkbook/examples/f6e4bcf6099d04b03f695bbccf638503bad9b831/chapters/testing/basic-snapshot-test/README.md
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.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 | "indent": [
44 | "off"
45 | ],
46 | "@typescript-eslint/indent": [
47 | "error",
48 | 2
49 | ],
50 | "quotes": [
51 | "error",
52 | "single",
53 | {
54 | "avoidEscape": true
55 | }
56 | ],
57 | "comma-dangle": [
58 | "error",
59 | "always-multiline"
60 | ],
61 | "comma-spacing": [
62 | "error",
63 | {
64 | "before": false,
65 | "after": true
66 | }
67 | ],
68 | "no-multi-spaces": [
69 | "error",
70 | {
71 | "ignoreEOLComments": false
72 | }
73 | ],
74 | "array-bracket-spacing": [
75 | "error",
76 | "never"
77 | ],
78 | "array-bracket-newline": [
79 | "error",
80 | "consistent"
81 | ],
82 | "object-curly-spacing": [
83 | "error",
84 | "always"
85 | ],
86 | "object-curly-newline": [
87 | "error",
88 | {
89 | "multiline": true,
90 | "consistent": true
91 | }
92 | ],
93 | "object-property-newline": [
94 | "error",
95 | {
96 | "allowAllPropertiesOnSameLine": true
97 | }
98 | ],
99 | "keyword-spacing": [
100 | "error"
101 | ],
102 | "brace-style": [
103 | "error",
104 | "1tbs",
105 | {
106 | "allowSingleLine": true
107 | }
108 | ],
109 | "space-before-blocks": [
110 | "error"
111 | ],
112 | "curly": [
113 | "error",
114 | "multi-line",
115 | "consistent"
116 | ],
117 | "@typescript-eslint/member-delimiter-style": [
118 | "error"
119 | ],
120 | "semi": [
121 | "error",
122 | "always"
123 | ],
124 | "max-len": [
125 | "error",
126 | {
127 | "code": 150,
128 | "ignoreUrls": true,
129 | "ignoreStrings": true,
130 | "ignoreTemplateLiterals": true,
131 | "ignoreComments": true,
132 | "ignoreRegExpLiterals": true
133 | }
134 | ],
135 | "quote-props": [
136 | "error",
137 | "consistent-as-needed"
138 | ],
139 | "@typescript-eslint/no-require-imports": [
140 | "error"
141 | ],
142 | "import/no-extraneous-dependencies": [
143 | "error",
144 | {
145 | "devDependencies": [
146 | "**/test/**",
147 | "**/build-tools/**"
148 | ],
149 | "optionalDependencies": false,
150 | "peerDependencies": true
151 | }
152 | ],
153 | "import/no-unresolved": [
154 | "error"
155 | ],
156 | "import/order": [
157 | "warn",
158 | {
159 | "groups": [
160 | "builtin",
161 | "external"
162 | ],
163 | "alphabetize": {
164 | "order": "asc",
165 | "caseInsensitive": true
166 | }
167 | }
168 | ],
169 | "no-duplicate-imports": [
170 | "error"
171 | ],
172 | "no-shadow": [
173 | "off"
174 | ],
175 | "@typescript-eslint/no-shadow": [
176 | "error"
177 | ],
178 | "key-spacing": [
179 | "error"
180 | ],
181 | "no-multiple-empty-lines": [
182 | "error"
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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.gitattributes:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | *.snap linguist-generated
4 | /.eslintrc.json linguist-generated
5 | /.gitattributes linguist-generated
6 | /.github/pull_request_template.md linguist-generated
7 | /.github/workflows/build.yml linguist-generated
8 | /.github/workflows/upgrade-dependencies.yml linguist-generated
9 | /.mergify.yml linguist-generated
10 | /.npmignore linguist-generated
11 | /.projen/ linguist-generated
12 | /.versionrc.json linguist-generated
13 | /cdk.json linguist-generated
14 | /LICENSE linguist-generated
15 | /package.json linguist-generated
16 | /tsconfig.eslint.json linguist-generated
17 | /tsconfig.jest.json linguist-generated
18 | /tsconfig.json linguist-generated
19 | /yarn.lock linguist-generated
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes #
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.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 "Automation"
23 | git config user.email "github-actions@github.com"
24 | - name: Build
25 | run: npx projen build
26 | - name: Check for changes
27 | id: git_diff
28 | run: git diff --exit-code || echo "::set-output name=has_changes::true"
29 | - if: steps.git_diff.outputs.has_changes
30 | name: Commit and push changes (if changed)
31 | run: 'git add . && git commit -m "chore: self mutation" && git push origin
32 | HEAD:${{ github.event.pull_request.head.ref }}'
33 | - if: steps.git_diff.outputs.has_changes
34 | name: Update status check (if changed)
35 | run: gh api -X POST /repos/${{ github.event.pull_request.head.repo.full_name
36 | }}/check-runs -F name="build" -F head_sha="$(git rev-parse HEAD)" -F
37 | status="completed" -F conclusion="success"
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.github/workflows/upgrade-dependencies.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: upgrade-dependencies
4 | on:
5 | workflow_dispatch: {}
6 | schedule:
7 | - cron: 0 0 * * *
8 | jobs:
9 | upgrade:
10 | name: Upgrade
11 | permissions:
12 | contents: read
13 | runs-on: ubuntu-latest
14 | outputs:
15 | conclusion: ${{ steps.build.outputs.conclusion }}
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | - name: Install dependencies
20 | run: yarn install --check-files --frozen-lockfile
21 | - name: Upgrade dependencies
22 | run: npx projen upgrade-dependencies
23 | - name: Build
24 | id: build
25 | run: npx projen build && echo "::set-output name=conclusion::success" || echo
26 | "::set-output name=conclusion::failure"
27 | - name: Create Patch
28 | run: |-
29 | git add .
30 | git diff --patch --staged > ${{ runner.temp }}/upgrade.patch
31 | - name: Upload patch
32 | uses: actions/upload-artifact@v2
33 | with:
34 | name: upgrade.patch
35 | path: ${{ runner.temp }}/upgrade.patch
36 | pr:
37 | name: Create Pull Request
38 | needs: upgrade
39 | permissions:
40 | contents: write
41 | pull-requests: write
42 | checks: write
43 | runs-on: ubuntu-latest
44 | steps:
45 | - name: Checkout
46 | uses: actions/checkout@v2
47 | - name: Download patch
48 | uses: actions/download-artifact@v2
49 | with:
50 | name: upgrade.patch
51 | path: ${{ runner.temp }}
52 | - name: Apply patch
53 | run: '[ -s ${{ runner.temp }}/upgrade.patch ] && git apply ${{ runner.temp
54 | }}/upgrade.patch || echo "Empty patch. Skipping."'
55 | - name: Create Pull Request
56 | id: create-pr
57 | uses: peter-evans/create-pull-request@v3
58 | with:
59 | token: ${{ secrets.GITHUB_TOKEN }}
60 | commit-message: upgrade
61 | branch: github-actions/upgrade-dependencies
62 | title: "chore(deps): upgrade-dependencies"
63 | labels: ""
64 | body: >-
65 | See https://github.com/${{ github.repository }}/actions/runs/${{
66 | github.run_id }}
67 |
68 |
69 | ------
70 |
71 |
72 | *Automatically created by projen via GitHubActions*
73 | - name: Update status check
74 | if: steps.create-pr.outputs.pull-request-url != ''
75 | run: "curl -i --fail -X POST -H \"Accept: application/vnd.github.v3+json\" -H
76 | \"Authorization: token ${GITHUB_TOKEN}\"
77 | https://api.github.com/repos/${{ github.repository }}/check-runs -d
78 | '{\"name\":\"build\",\"head_sha\":\"github-actions/upgrade-dependenci\
79 | es\",\"status\":\"completed\",\"conclusion\":\"${{
80 | needs.upgrade.outputs.conclusion }}\",\"output\":{\"title\":\"Created
81 | via the upgrade-dependencies workflow.\",\"summary\":\"Action run URL:
82 | https://github.com/${{ github.repository }}/actions/runs/${{
83 | github.run_id }}\"}}'"
84 | env:
85 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.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 | .cdk.staging/
11 | .eslintcache
12 | .nyc_output
13 | .parcel-cache/
14 | .yarn-integrity
15 | /.changelog.tmp.md
16 | /.version.tmp.json
17 | /coverage
18 | /dist
19 | /lib
20 | /test-reports/
21 | build/Release
22 | cdk.out/
23 | coverage
24 | jspm_packages/
25 | junit.xml
26 | lerna-debug.log*
27 | lib-cov
28 | logs
29 | node_modules/
30 | npm-debug.log*
31 | pids
32 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
33 | yarn-debug.log*
34 | yarn-error.log*
35 | !/.eslintrc.json
36 | !/.gitattributes
37 | !/.github/pull_request_template.md
38 | !/.github/workflows/build.yml
39 | !/.github/workflows/upgrade-dependencies.yml
40 | !/.mergify.yml
41 | !/.npmignore
42 | !/.projen/deps.json
43 | !/.projen/tasks.json
44 | !/.projenrc.js
45 | !/.versionrc.json
46 | !/LICENSE
47 | !/cdk.json
48 | !/package.json
49 | !/src
50 | !/test
51 | !/tsconfig.eslint.json
52 | !/tsconfig.jest.json
53 | !/tsconfig.json
54 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.idea/infra-apig.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.idea/jsLinters/eslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.npmignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | .cdk.staging/
3 | /.eslintrc.json
4 | /.github
5 | /.idea
6 | /.mergify.yml
7 | /.projen
8 | /.projenrc.js
9 | /.vscode
10 | /coverage
11 | /src
12 | /test
13 | /test-reports/
14 | /tsconfig.eslint.json
15 | /tsconfig.jest.json
16 | /tsconfig.json
17 | cdk.out/
18 | dist
19 | junit.xml
20 | tsconfig.tsbuildinfo
21 | !/lib
22 | !/lib/**/*.d.ts
23 | !/lib/**/*.js
24 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.projen/deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "name": "@types/jest",
5 | "type": "build"
6 | },
7 | {
8 | "name": "@types/node",
9 | "version": "^10.17.0",
10 | "type": "build"
11 | },
12 | {
13 | "name": "@typescript-eslint/eslint-plugin",
14 | "type": "build"
15 | },
16 | {
17 | "name": "@typescript-eslint/parser",
18 | "type": "build"
19 | },
20 | {
21 | "name": "aws-cdk",
22 | "version": "^2.0.0-rc.10",
23 | "type": "build"
24 | },
25 | {
26 | "name": "eslint",
27 | "type": "build"
28 | },
29 | {
30 | "name": "eslint-import-resolver-node",
31 | "type": "build"
32 | },
33 | {
34 | "name": "eslint-import-resolver-typescript",
35 | "type": "build"
36 | },
37 | {
38 | "name": "eslint-plugin-import",
39 | "type": "build"
40 | },
41 | {
42 | "name": "jest",
43 | "type": "build"
44 | },
45 | {
46 | "name": "jest-junit",
47 | "version": "^12",
48 | "type": "build"
49 | },
50 | {
51 | "name": "json-schema",
52 | "type": "build"
53 | },
54 | {
55 | "name": "npm-check-updates",
56 | "version": "^11",
57 | "type": "build"
58 | },
59 | {
60 | "name": "npm-check-updates",
61 | "version": "^11",
62 | "type": "build"
63 | },
64 | {
65 | "name": "projen",
66 | "version": "^0.17.95",
67 | "type": "build"
68 | },
69 | {
70 | "name": "standard-version",
71 | "version": "^9",
72 | "type": "build"
73 | },
74 | {
75 | "name": "ts-jest",
76 | "type": "build"
77 | },
78 | {
79 | "name": "ts-node",
80 | "type": "build"
81 | },
82 | {
83 | "name": "typescript",
84 | "type": "build"
85 | },
86 | {
87 | "name": "@aws-cdk/assert",
88 | "version": "^2.0.0-rc.10",
89 | "type": "runtime"
90 | },
91 | {
92 | "name": "@aws-sdk/client-dynamodb",
93 | "type": "runtime"
94 | },
95 | {
96 | "name": "@matthewbonig/cfn-response",
97 | "type": "runtime"
98 | },
99 | {
100 | "name": "@types/aws-lambda",
101 | "type": "runtime"
102 | },
103 | {
104 | "name": "aws-cdk-lib",
105 | "version": "^2.0.0-rc.10",
106 | "type": "runtime"
107 | },
108 | {
109 | "name": "axios",
110 | "type": "runtime"
111 | },
112 | {
113 | "name": "constructs",
114 | "version": "^10.0.5",
115 | "type": "runtime"
116 | }
117 | ],
118 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
119 | }
120 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.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 | "bump": {
37 | "name": "bump",
38 | "category": "20.release",
39 | "description": "Bumps version based on latest git tag and generates a changelog entry",
40 | "steps": [
41 | {
42 | "exec": "git -c \"versionsort.suffix=-\" tag --sort=\"-version:refname\" --list \"v*\" | head -n1 > .version.tmp.json"
43 | },
44 | {
45 | "exec": "if [ \"$(cat .version.tmp.json)\" = \"\" ]; then echo \"v0.1.0\" > .version.tmp.json; fi"
46 | },
47 | {
48 | "exec": "standard-version"
49 | }
50 | ],
51 | "condition": "! git log --oneline -1 | grep -q \"chore(release):\""
52 | },
53 | "unbump": {
54 | "name": "unbump",
55 | "category": "20.release",
56 | "description": "Restores version to 0.0.0",
57 | "steps": [
58 | {
59 | "exec": "standard-version -r 0.0.0"
60 | }
61 | ]
62 | },
63 | "compile": {
64 | "name": "compile",
65 | "category": "00.build",
66 | "description": "Only compile"
67 | },
68 | "test:compile": {
69 | "name": "test:compile",
70 | "category": "10.test",
71 | "description": "compiles the test code",
72 | "steps": [
73 | {
74 | "exec": "tsc --noEmit --project tsconfig.jest.json"
75 | }
76 | ]
77 | },
78 | "test": {
79 | "name": "test",
80 | "category": "10.test",
81 | "description": "Run tests",
82 | "steps": [
83 | {
84 | "exec": "rm -fr lib/"
85 | },
86 | {
87 | "spawn": "test:compile"
88 | },
89 | {
90 | "exec": "jest --passWithNoTests --all --updateSnapshot"
91 | },
92 | {
93 | "spawn": "eslint"
94 | }
95 | ]
96 | },
97 | "build": {
98 | "name": "build",
99 | "category": "00.build",
100 | "description": "Full release build (test+compile)",
101 | "steps": [
102 | {
103 | "exec": "npx projen"
104 | },
105 | {
106 | "spawn": "test"
107 | },
108 | {
109 | "spawn": "compile"
110 | },
111 | {
112 | "spawn": "synth"
113 | }
114 | ]
115 | },
116 | "test:watch": {
117 | "name": "test:watch",
118 | "category": "10.test",
119 | "description": "Run jest in watch mode",
120 | "steps": [
121 | {
122 | "exec": "jest --watch"
123 | }
124 | ]
125 | },
126 | "test:update": {
127 | "name": "test:update",
128 | "category": "10.test",
129 | "description": "Update jest snapshots",
130 | "steps": [
131 | {
132 | "exec": "jest --updateSnapshot"
133 | }
134 | ]
135 | },
136 | "upgrade-dependencies": {
137 | "name": "upgrade-dependencies",
138 | "env": {
139 | "CI": "0"
140 | },
141 | "steps": [
142 | {
143 | "exec": "npm-check-updates --upgrade --target=minor --reject='projen'"
144 | },
145 | {
146 | "exec": "npx projen"
147 | }
148 | ]
149 | },
150 | "upgrade-projen": {
151 | "name": "upgrade-projen",
152 | "env": {
153 | "CI": "0"
154 | },
155 | "steps": [
156 | {
157 | "exec": "npm-check-updates --upgrade --target=minor --filter='projen'"
158 | },
159 | {
160 | "exec": "npx projen"
161 | }
162 | ]
163 | },
164 | "default": {
165 | "name": "default",
166 | "steps": [
167 | {
168 | "exec": "node .projenrc.js"
169 | }
170 | ]
171 | },
172 | "watch": {
173 | "name": "watch",
174 | "category": "00.build",
175 | "description": "Watch & compile in the background",
176 | "steps": [
177 | {
178 | "exec": "tsc -w"
179 | }
180 | ]
181 | },
182 | "eslint": {
183 | "name": "eslint",
184 | "category": "10.test",
185 | "description": "Runs eslint against the codebase",
186 | "steps": [
187 | {
188 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js"
189 | }
190 | ]
191 | },
192 | "synth": {
193 | "name": "synth",
194 | "category": "00.build",
195 | "description": "Synthesizes your cdk app into cdk.out (part of \"yarn build\")",
196 | "steps": [
197 | {
198 | "exec": "cdk synth"
199 | }
200 | ]
201 | },
202 | "deploy": {
203 | "name": "deploy",
204 | "category": "20.release",
205 | "description": "Deploys your CDK app to the AWS cloud",
206 | "steps": [
207 | {
208 | "exec": "cdk deploy"
209 | }
210 | ]
211 | },
212 | "destroy": {
213 | "name": "destroy",
214 | "category": "20.release",
215 | "description": "Destroys your cdk app in the AWS cloud",
216 | "steps": [
217 | {
218 | "exec": "cdk destroy"
219 | }
220 | ]
221 | },
222 | "diff": {
223 | "name": "diff",
224 | "category": "99.misc",
225 | "description": "Diffs the currently deployed app against your code",
226 | "steps": [
227 | {
228 | "exec": "cdk diff"
229 | }
230 | ]
231 | }
232 | },
233 | "env": {
234 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")"
235 | },
236 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
237 | }
238 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.projenrc.js:
--------------------------------------------------------------------------------
1 | const { AwsCdkTypeScriptApp } = require('projen');
2 | const project = new AwsCdkTypeScriptApp({
3 | cdkVersion: '2.0.0-rc.10',
4 | defaultReleaseBranch: 'main',
5 | name: 'infra-apig',
6 |
7 | cdkDependencies: [],
8 | deps: ['axios', '@aws-sdk/client-dynamodb', '@matthewbonig/cfn-response', '@types/aws-lambda'], /* Runtime dependencies of this module. */
9 | // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */
10 | // devDeps: [], /* Build dependencies for this module. */
11 | // packageName: undefined, /* The "name" in package.json. */
12 | // projectType: ProjectType.UNKNOWN, /* Which type of project this is (library/app). */
13 | // releaseWorkflow: undefined, /* Define a GitHub workflow for releasing from "main" when new versions are bumped. */
14 | });
15 | project.synth();
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/.versionrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageFiles": [
3 | {
4 | "filename": ".version.tmp.json",
5 | "type": "plain-text"
6 | }
7 | ],
8 | "bumpFiles": [
9 | "package.json"
10 | ],
11 | "commitAll": false,
12 | "infile": ".changelog.tmp.md",
13 | "header": "",
14 | "skip": {
15 | "commit": true,
16 | "tag": true
17 | },
18 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
19 | }
20 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/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
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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/README.md:
--------------------------------------------------------------------------------
1 | # Testing Chapter
2 |
3 | This example shows how to deploy infrastructure tests for an API Gateway-based API that uses Lambda and DynamoDB.
4 |
5 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node --prefer-ts-exts src/main.ts",
3 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
4 | }
5 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "infra-apig",
3 | "scripts": {
4 | "clobber": "npx projen clobber",
5 | "bump": "npx projen bump",
6 | "unbump": "npx projen unbump",
7 | "compile": "npx projen compile",
8 | "test:compile": "npx projen test:compile",
9 | "test": "npx projen test",
10 | "build": "npx projen build",
11 | "test:watch": "npx projen test:watch",
12 | "test:update": "npx projen test:update",
13 | "upgrade-dependencies": "npx projen upgrade-dependencies",
14 | "upgrade-projen": "npx projen upgrade-projen",
15 | "default": "npx projen default",
16 | "eslint": "npx projen eslint",
17 | "synth": "npx projen synth",
18 | "deploy": "npx projen deploy",
19 | "destroy": "npx projen destroy",
20 | "diff": "npx projen diff",
21 | "projen": "npx projen",
22 | "start": "npx projen start"
23 | },
24 | "devDependencies": {
25 | "@types/jest": "^26.0.23",
26 | "@types/node": "^10.17.0",
27 | "@typescript-eslint/eslint-plugin": "^4.28.2",
28 | "@typescript-eslint/parser": "^4.28.2",
29 | "aws-cdk": "^2.0.0-rc.10",
30 | "eslint": "^7.30.0",
31 | "eslint-import-resolver-node": "^0.3.4",
32 | "eslint-import-resolver-typescript": "^2.4.0",
33 | "eslint-plugin-import": "^2.23.4",
34 | "jest": "^27.0.6",
35 | "jest-junit": "^12",
36 | "json-schema": "^0.3.0",
37 | "npm-check-updates": "^11",
38 | "projen": "^0.17.95",
39 | "standard-version": "^9",
40 | "ts-jest": "^27.0.3",
41 | "ts-node": "^10.0.0",
42 | "typescript": "^4.3.5"
43 | },
44 | "dependencies": {
45 | "@aws-cdk/assert": "^2.0.0-rc.10",
46 | "@aws-sdk/client-dynamodb": "^3.20.0",
47 | "@matthewbonig/cfn-response": "^0.1.4",
48 | "@types/aws-lambda": "^8.10.83",
49 | "aws-cdk-lib": "^2.0.0-rc.10",
50 | "axios": "^0.21.1",
51 | "constructs": "^10.0.5"
52 | },
53 | "bundledDependencies": [],
54 | "license": "Apache-2.0",
55 | "version": "0.0.0",
56 | "jest": {
57 | "testMatch": [
58 | "**/__tests__/**/*.ts?(x)",
59 | "**/?(*.)+(spec|test).ts?(x)"
60 | ],
61 | "clearMocks": true,
62 | "collectCoverage": true,
63 | "coverageReporters": [
64 | "json",
65 | "lcov",
66 | "clover",
67 | "text"
68 | ],
69 | "coverageDirectory": "coverage",
70 | "coveragePathIgnorePatterns": [
71 | "/node_modules/"
72 | ],
73 | "testPathIgnorePatterns": [
74 | "/node_modules/"
75 | ],
76 | "watchPathIgnorePatterns": [
77 | "/node_modules/"
78 | ],
79 | "reporters": [
80 | "default",
81 | [
82 | "jest-junit",
83 | {
84 | "outputDirectory": "test-reports"
85 | }
86 | ]
87 | ],
88 | "preset": "ts-jest",
89 | "globals": {
90 | "ts-jest": {
91 | "tsconfig": "tsconfig.jest.json"
92 | }
93 | }
94 | },
95 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
96 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/ApiTester.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import { CustomResource, Duration } from 'aws-cdk-lib';
3 | import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
4 | import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
5 | import { Construct } from 'constructs';
6 |
7 | export class ApiTester extends Construct {
8 | constructor(scope: Construct, id: string, props: { api: LambdaRestApi }) {
9 | super(scope, id);
10 | const handler = new NodejsFunction(this, 'ApiTester', {
11 | entry: path.join(__dirname, 'handlers', 'custom-resource.ts'),
12 | timeout: Duration.minutes(3),
13 | });
14 |
15 | new CustomResource(this, 'TestingResource', {
16 | serviceToken: handler.functionArn,
17 | resourceType: 'Custom::Tests',
18 | properties: {
19 | url: props.api.latestDeployment?.api.deploymentStage.urlForPath()!,
20 | updateTime: new Date().toISOString(),
21 | },
22 | });
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/SimpleApiWithTestsStack.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
3 | import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
4 | import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
5 | import { AttributeType, Table } from 'aws-cdk-lib/lib/aws-dynamodb';
6 | import { Construct } from 'constructs';
7 | import { ApiTester } from './ApiTester';
8 |
9 | export class SimpleApiWithTestsStack extends Stack {
10 | constructor(scope: Construct, id: string, props: StackProps = {}) {
11 | super(scope, id, props);
12 |
13 | const construct = new Construct(this, 'Api');
14 |
15 | const table = new Table(construct, 'SomeTable', {
16 | partitionKey: {
17 | name: 'PK',
18 | type: AttributeType.STRING,
19 | },
20 | removalPolicy: RemovalPolicy.DESTROY,
21 | });
22 | const backend = new NodejsFunction(construct, 'Backend', {
23 | entry: path.join(__dirname, 'handlers', 'proxy.ts'),
24 | environment: {
25 | TABLE_NAME: table.tableName,
26 | },
27 | });
28 | table.grantReadWriteData(backend);
29 |
30 | const api = new LambdaRestApi(construct, 'SomeApi', {
31 | handler: backend,
32 | });
33 |
34 | new ApiTester(this, 'Tests', { api }).node.addDependency(construct);
35 | }
36 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/handlers/custom-resource.ts:
--------------------------------------------------------------------------------
1 | import * as response from '@matthewbonig/cfn-response';
2 | import { CloudFormationCustomResourceEvent } from 'aws-lambda';
3 |
4 | import * as axios from 'axios';
5 |
6 | export const handler = async (event: CloudFormationCustomResourceEvent, context: any) => {
7 | console.log('event:', JSON.stringify(event, null, 2));
8 | const { url } = event.ResourceProperties;
9 | if (event.RequestType === 'Delete') {
10 | // let's do nothing.
11 | return response.send({
12 | ...event,
13 | PhysicalResourceId: context.logStreamName,
14 | Status: response.ResponseStatus.SUCCESS,
15 | Data: {},
16 | Reason: '',
17 | NoEcho: false,
18 | });
19 | }
20 |
21 | const responseData = {};
22 | try {
23 | await runTests(url);
24 | console.log('Tests passed!');
25 | await response.send({
26 | ...event,
27 | Status: response.ResponseStatus.SUCCESS,
28 | Data: responseData,
29 | PhysicalResourceId: context.logStreamName,
30 | Reason: '',
31 | NoEcho: false,
32 | });
33 | } catch (err) {
34 | await response.send({
35 | ...event,
36 | Status: response.ResponseStatus.FAILED,
37 | Data: { err },
38 | PhysicalResourceId: context.logStreamName,
39 | Reason: '',
40 | NoEcho: false,
41 | });
42 | }
43 | };
44 |
45 | async function runTests(url: string) {
46 | return await axios.post(url + '/test/', {});
47 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/handlers/proxy.ts:
--------------------------------------------------------------------------------
1 | import { runTest } from './runTest';
2 |
3 | function addTester(handler: Function) {
4 | return async (event: any, context: any) => {
5 | if (event.path === '/test/') {
6 | console.log('Running API test');
7 | try {
8 | await runTest();
9 | } catch (err) {
10 | return { statusCode: 500, body: err.toString() };
11 | }
12 | return { statusCode: 200, body: 'Test Ran!' };
13 | }
14 | return handler(event, context);
15 | };
16 | }
17 |
18 | // function logger(handler: Function) {
19 | // return async function (...args: any[]) {
20 | // console.log('event: ', args);
21 | // const returnValue = await handler(...args);
22 | // console.log('Return value:', returnValue);
23 | // return returnValue;
24 | // };
25 | // }
26 |
27 | let originalApplicationHandler = (event: any) => {
28 | console.log('event: ', JSON.stringify(event, null, 2));
29 | return {
30 | statusCode: 200,
31 | body: '',
32 | };
33 | };
34 | export const handler = addTester(originalApplicationHandler);
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/handlers/runTest.ts:
--------------------------------------------------------------------------------
1 | import { DeleteItemCommand, DynamoDBClient, GetItemCommand, PutItemCommand } from '@aws-sdk/client-dynamodb';
2 |
3 | export async function runTest() {
4 | // now we're going to do some special test work here.
5 | console.log('Running test!');
6 | const tableName = process.env.TABLE_NAME!;
7 | const client = new DynamoDBClient({ region: process.env.AWS_REGION || 'us-east-1' });
8 | let itemWritten: boolean = false;
9 | const testItem = createNewTestItem();
10 | let key = { PK: testItem.PK };
11 | try {
12 | // let's write a record to dynamodb
13 | const putItemCommand = new PutItemCommand({
14 | Item: testItem,
15 | TableName: tableName,
16 | });
17 |
18 | const response = await client.send(putItemCommand);
19 | itemWritten = true;
20 | console.log('Response from write: ', response);
21 |
22 | // then read that record and compare
23 | const readResponse = await client.send(new GetItemCommand({
24 | Key: key,
25 | TableName: tableName,
26 | }));
27 | console.log('Response from read: ', readResponse);
28 |
29 | let areEqual = compare(readResponse.Item, testItem);
30 | console.log('Comparing...', areEqual);
31 | if (!areEqual) {
32 | let s = JSON.stringify(readResponse.Item, null, 2);
33 | let s1 = JSON.stringify(testItem, null, 2);
34 | throw new Error(`Tests failed, items not equal: \n${s}\n${s1}`);
35 | }
36 | } finally {
37 | // then delete that record
38 | if (itemWritten) {
39 | await client.send(new DeleteItemCommand({
40 | Key: key, TableName: tableName,
41 | }));
42 | }
43 | }
44 | }
45 |
46 | function compare(one: any, two: any) {
47 | return JSON.stringify(one) === JSON.stringify(two);
48 | }
49 |
50 | function createNewTestItem() {
51 | return {
52 | PK: { S: 'test#' + new Date().toISOString() },
53 | };
54 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/src/main.ts:
--------------------------------------------------------------------------------
1 | import { App } from 'aws-cdk-lib';
2 | import { SimpleApiWithTestsStack } from './SimpleApiWithTestsStack';
3 |
4 | // for development, use account/region from cdk cli
5 | const devEnv = {
6 | account: process.env.CDK_DEFAULT_ACCOUNT,
7 | region: process.env.CDK_DEFAULT_REGION,
8 | };
9 |
10 | const app = new App();
11 |
12 | new SimpleApiWithTestsStack(app, 'SimpleApiWithTests', { env: devEnv });
13 |
14 | app.synth();
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/test/main.test.ts:
--------------------------------------------------------------------------------
1 | import '@aws-cdk/assert/jest';
2 | import { App } from '@aws-cdk/core';
3 | import { SimpleApiWithTestsStack } from "../src/SimpleApiWithTestsStack";
4 |
5 | test('Snapshot', () => {
6 | const app = new App();
7 | const stack = new SimpleApiWithTestsStack(app, 'test');
8 |
9 | expect(stack).not.toHaveResource('AWS::S3::Bucket');
10 | expect(app.synth().getStackArtifact(stack.artifactId).template).toMatchSnapshot();
11 | });
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/infra-apig/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": "src",
4 | "outDir": "lib",
5 | "alwaysStrict": true,
6 | "declaration": true,
7 | "experimentalDecorators": true,
8 | "inlineSourceMap": true,
9 | "inlineSources": true,
10 | "lib": [
11 | "es2018"
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": "ES2018"
27 | },
28 | "include": [
29 | "src/**/*.ts"
30 | ],
31 | "exclude": [
32 | "node_modules",
33 | "lib",
34 | "cdk.out"
35 | ],
36 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
37 | }
38 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.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 | "indent": [
44 | "off"
45 | ],
46 | "@typescript-eslint/indent": [
47 | "error",
48 | 2
49 | ],
50 | "quotes": [
51 | "error",
52 | "single",
53 | {
54 | "avoidEscape": true
55 | }
56 | ],
57 | "comma-dangle": [
58 | "error",
59 | "always-multiline"
60 | ],
61 | "comma-spacing": [
62 | "error",
63 | {
64 | "before": false,
65 | "after": true
66 | }
67 | ],
68 | "no-multi-spaces": [
69 | "error",
70 | {
71 | "ignoreEOLComments": false
72 | }
73 | ],
74 | "array-bracket-spacing": [
75 | "error",
76 | "never"
77 | ],
78 | "array-bracket-newline": [
79 | "error",
80 | "consistent"
81 | ],
82 | "object-curly-spacing": [
83 | "error",
84 | "always"
85 | ],
86 | "object-curly-newline": [
87 | "error",
88 | {
89 | "multiline": true,
90 | "consistent": true
91 | }
92 | ],
93 | "object-property-newline": [
94 | "error",
95 | {
96 | "allowAllPropertiesOnSameLine": true
97 | }
98 | ],
99 | "keyword-spacing": [
100 | "error"
101 | ],
102 | "brace-style": [
103 | "error",
104 | "1tbs",
105 | {
106 | "allowSingleLine": true
107 | }
108 | ],
109 | "space-before-blocks": [
110 | "error"
111 | ],
112 | "curly": [
113 | "error",
114 | "multi-line",
115 | "consistent"
116 | ],
117 | "@typescript-eslint/member-delimiter-style": [
118 | "error"
119 | ],
120 | "semi": [
121 | "error",
122 | "always"
123 | ],
124 | "max-len": [
125 | "error",
126 | {
127 | "code": 150,
128 | "ignoreUrls": true,
129 | "ignoreStrings": true,
130 | "ignoreTemplateLiterals": true,
131 | "ignoreComments": true,
132 | "ignoreRegExpLiterals": true
133 | }
134 | ],
135 | "quote-props": [
136 | "error",
137 | "consistent-as-needed"
138 | ],
139 | "@typescript-eslint/no-require-imports": [
140 | "error"
141 | ],
142 | "import/no-extraneous-dependencies": [
143 | "error",
144 | {
145 | "devDependencies": [
146 | "**/test/**",
147 | "**/build-tools/**"
148 | ],
149 | "optionalDependencies": false,
150 | "peerDependencies": true
151 | }
152 | ],
153 | "import/no-unresolved": [
154 | "error"
155 | ],
156 | "import/order": [
157 | "warn",
158 | {
159 | "groups": [
160 | "builtin",
161 | "external"
162 | ],
163 | "alphabetize": {
164 | "order": "asc",
165 | "caseInsensitive": true
166 | }
167 | }
168 | ],
169 | "no-duplicate-imports": [
170 | "error"
171 | ],
172 | "no-shadow": [
173 | "off"
174 | ],
175 | "@typescript-eslint/no-shadow": [
176 | "error"
177 | ],
178 | "key-spacing": [
179 | "error"
180 | ],
181 | "no-multiple-empty-lines": [
182 | "error"
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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.gitattributes:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | *.snap linguist-generated
4 | /.eslintrc.json linguist-generated
5 | /.gitattributes linguist-generated
6 | /.github/pull_request_template.md linguist-generated
7 | /.github/workflows/build.yml linguist-generated
8 | /.github/workflows/upgrade-dependencies.yml linguist-generated
9 | /.mergify.yml linguist-generated
10 | /.npmignore linguist-generated
11 | /.projen/ linguist-generated
12 | /.versionrc.json linguist-generated
13 | /cdk.json linguist-generated
14 | /LICENSE linguist-generated
15 | /package.json linguist-generated
16 | /tsconfig.eslint.json linguist-generated
17 | /tsconfig.jest.json linguist-generated
18 | /tsconfig.json linguist-generated
19 | /yarn.lock linguist-generated
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes #
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.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 "Automation"
23 | git config user.email "github-actions@github.com"
24 | - name: Build
25 | run: npx projen build
26 | - name: Check for changes
27 | id: git_diff
28 | run: git diff --exit-code || echo "::set-output name=has_changes::true"
29 | - if: steps.git_diff.outputs.has_changes
30 | name: Commit and push changes (if changed)
31 | run: 'git add . && git commit -m "chore: self mutation" && git push origin
32 | HEAD:${{ github.event.pull_request.head.ref }}'
33 | - if: steps.git_diff.outputs.has_changes
34 | name: Update status check (if changed)
35 | run: gh api -X POST /repos/${{ github.event.pull_request.head.repo.full_name
36 | }}/check-runs -F name="build" -F head_sha="$(git rev-parse HEAD)" -F
37 | status="completed" -F conclusion="success"
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.github/workflows/upgrade-dependencies.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: upgrade-dependencies
4 | on:
5 | workflow_dispatch: {}
6 | schedule:
7 | - cron: 0 0 * * *
8 | jobs:
9 | upgrade:
10 | name: Upgrade
11 | permissions:
12 | contents: read
13 | runs-on: ubuntu-latest
14 | outputs:
15 | conclusion: ${{ steps.build.outputs.conclusion }}
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | - name: Install dependencies
20 | run: yarn install --check-files --frozen-lockfile
21 | - name: Upgrade dependencies
22 | run: npx projen upgrade-dependencies
23 | - name: Build
24 | id: build
25 | run: npx projen build && echo "::set-output name=conclusion::success" || echo
26 | "::set-output name=conclusion::failure"
27 | - name: Create Patch
28 | run: |-
29 | git add .
30 | git diff --patch --staged > ${{ runner.temp }}/upgrade.patch
31 | - name: Upload patch
32 | uses: actions/upload-artifact@v2
33 | with:
34 | name: upgrade.patch
35 | path: ${{ runner.temp }}/upgrade.patch
36 | pr:
37 | name: Create Pull Request
38 | needs: upgrade
39 | permissions:
40 | contents: write
41 | pull-requests: write
42 | checks: write
43 | runs-on: ubuntu-latest
44 | steps:
45 | - name: Checkout
46 | uses: actions/checkout@v2
47 | - name: Download patch
48 | uses: actions/download-artifact@v2
49 | with:
50 | name: upgrade.patch
51 | path: ${{ runner.temp }}
52 | - name: Apply patch
53 | run: '[ -s ${{ runner.temp }}/upgrade.patch ] && git apply ${{ runner.temp
54 | }}/upgrade.patch || echo "Empty patch. Skipping."'
55 | - name: Create Pull Request
56 | id: create-pr
57 | uses: peter-evans/create-pull-request@v3
58 | with:
59 | token: ${{ secrets.GITHUB_TOKEN }}
60 | commit-message: upgrade
61 | branch: github-actions/upgrade-dependencies
62 | title: "chore(deps): upgrade-dependencies"
63 | labels: ""
64 | body: >-
65 | See https://github.com/${{ github.repository }}/actions/runs/${{
66 | github.run_id }}
67 |
68 |
69 | ------
70 |
71 |
72 | *Automatically created by projen via GitHubActions*
73 | - name: Update status check
74 | if: steps.create-pr.outputs.pull-request-url != ''
75 | run: "curl -i --fail -X POST -H \"Accept: application/vnd.github.v3+json\" -H
76 | \"Authorization: token ${GITHUB_TOKEN}\"
77 | https://api.github.com/repos/${{ github.repository }}/check-runs -d
78 | '{\"name\":\"build\",\"head_sha\":\"github-actions/upgrade-dependenci\
79 | es\",\"status\":\"completed\",\"conclusion\":\"${{
80 | needs.upgrade.outputs.conclusion }}\",\"output\":{\"title\":\"Created
81 | via the upgrade-dependencies workflow.\",\"summary\":\"Action run URL:
82 | https://github.com/${{ github.repository }}/actions/runs/${{
83 | github.run_id }}\"}}'"
84 | env:
85 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.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 | .cdk.staging/
11 | .eslintcache
12 | .nyc_output
13 | .parcel-cache/
14 | .yarn-integrity
15 | /.changelog.tmp.md
16 | /.version.tmp.json
17 | /coverage
18 | /dist
19 | /lib
20 | /test-reports/
21 | build/Release
22 | cdk.out/
23 | coverage
24 | jspm_packages/
25 | junit.xml
26 | lerna-debug.log*
27 | lib-cov
28 | logs
29 | node_modules/
30 | npm-debug.log*
31 | pids
32 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
33 | yarn-debug.log*
34 | yarn-error.log*
35 | !/.eslintrc.json
36 | !/.gitattributes
37 | !/.github/pull_request_template.md
38 | !/.github/workflows/build.yml
39 | !/.github/workflows/upgrade-dependencies.yml
40 | !/.mergify.yml
41 | !/.npmignore
42 | !/.projen/deps.json
43 | !/.projen/tasks.json
44 | !/.projenrc.js
45 | !/.versionrc.json
46 | !/LICENSE
47 | !/cdk.json
48 | !/package.json
49 | !/src
50 | !/test
51 | !/tsconfig.eslint.json
52 | !/tsconfig.jest.json
53 | !/tsconfig.json
54 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/aws.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/infra-async.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/jsLinters/eslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.npmignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | .cdk.staging/
3 | /.eslintrc.json
4 | /.github
5 | /.idea
6 | /.mergify.yml
7 | /.projen
8 | /.projenrc.js
9 | /.vscode
10 | /coverage
11 | /src
12 | /test
13 | /test-reports/
14 | /tsconfig.eslint.json
15 | /tsconfig.jest.json
16 | /tsconfig.json
17 | cdk.out/
18 | dist
19 | junit.xml
20 | tsconfig.tsbuildinfo
21 | !/lib
22 | !/lib/**/*.d.ts
23 | !/lib/**/*.js
24 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.projen/deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "name": "@matthewbonig/cfn-response",
5 | "type": "build"
6 | },
7 | {
8 | "name": "@types/aws-lambda",
9 | "type": "build"
10 | },
11 | {
12 | "name": "@types/jest",
13 | "type": "build"
14 | },
15 | {
16 | "name": "@types/node",
17 | "version": "^10.17.0",
18 | "type": "build"
19 | },
20 | {
21 | "name": "@typescript-eslint/eslint-plugin",
22 | "type": "build"
23 | },
24 | {
25 | "name": "@typescript-eslint/parser",
26 | "type": "build"
27 | },
28 | {
29 | "name": "aws-cdk",
30 | "version": "^2.0.0-rc.16",
31 | "type": "build"
32 | },
33 | {
34 | "name": "eslint",
35 | "type": "build"
36 | },
37 | {
38 | "name": "eslint-import-resolver-node",
39 | "type": "build"
40 | },
41 | {
42 | "name": "eslint-import-resolver-typescript",
43 | "type": "build"
44 | },
45 | {
46 | "name": "eslint-plugin-import",
47 | "type": "build"
48 | },
49 | {
50 | "name": "jest",
51 | "type": "build"
52 | },
53 | {
54 | "name": "jest-junit",
55 | "version": "^12",
56 | "type": "build"
57 | },
58 | {
59 | "name": "json-schema",
60 | "type": "build"
61 | },
62 | {
63 | "name": "npm-check-updates",
64 | "version": "^11",
65 | "type": "build"
66 | },
67 | {
68 | "name": "npm-check-updates",
69 | "version": "^11",
70 | "type": "build"
71 | },
72 | {
73 | "name": "projen",
74 | "version": "^0.17.95",
75 | "type": "build"
76 | },
77 | {
78 | "name": "standard-version",
79 | "version": "^9",
80 | "type": "build"
81 | },
82 | {
83 | "name": "ts-jest",
84 | "type": "build"
85 | },
86 | {
87 | "name": "ts-node",
88 | "type": "build"
89 | },
90 | {
91 | "name": "typescript",
92 | "type": "build"
93 | },
94 | {
95 | "name": "@aws-cdk/assert",
96 | "version": "^2.0.0-rc.16",
97 | "type": "runtime"
98 | },
99 | {
100 | "name": "@aws-sdk/client-sfn",
101 | "type": "runtime"
102 | },
103 | {
104 | "name": "@aws-sdk/client-sqs",
105 | "type": "runtime"
106 | },
107 | {
108 | "name": "aws-cdk-lib",
109 | "version": "^2.0.0-rc.16",
110 | "type": "runtime"
111 | },
112 | {
113 | "name": "constructs",
114 | "version": "^10.0.5",
115 | "type": "runtime"
116 | },
117 | {
118 | "name": "eslint",
119 | "type": "runtime"
120 | }
121 | ],
122 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
123 | }
124 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.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 | "bump": {
37 | "name": "bump",
38 | "category": "20.release",
39 | "description": "Bumps version based on latest git tag and generates a changelog entry",
40 | "steps": [
41 | {
42 | "exec": "git -c \"versionsort.suffix=-\" tag --sort=\"-version:refname\" --list \"v*\" | head -n1 > .version.tmp.json"
43 | },
44 | {
45 | "exec": "if [ \"$(cat .version.tmp.json)\" = \"\" ]; then echo \"v0.1.0\" > .version.tmp.json; fi"
46 | },
47 | {
48 | "exec": "standard-version"
49 | }
50 | ],
51 | "condition": "! git log --oneline -1 | grep -q \"chore(release):\""
52 | },
53 | "unbump": {
54 | "name": "unbump",
55 | "category": "20.release",
56 | "description": "Restores version to 0.0.0",
57 | "steps": [
58 | {
59 | "exec": "standard-version -r 0.0.0"
60 | }
61 | ]
62 | },
63 | "compile": {
64 | "name": "compile",
65 | "category": "00.build",
66 | "description": "Only compile"
67 | },
68 | "test:compile": {
69 | "name": "test:compile",
70 | "category": "10.test",
71 | "description": "compiles the test code",
72 | "steps": [
73 | {
74 | "exec": "tsc --noEmit --project tsconfig.jest.json"
75 | }
76 | ]
77 | },
78 | "test": {
79 | "name": "test",
80 | "category": "10.test",
81 | "description": "Run tests",
82 | "steps": [
83 | {
84 | "exec": "rm -fr lib/"
85 | },
86 | {
87 | "spawn": "test:compile"
88 | },
89 | {
90 | "exec": "jest --passWithNoTests --all --updateSnapshot"
91 | },
92 | {
93 | "spawn": "eslint"
94 | }
95 | ]
96 | },
97 | "build": {
98 | "name": "build",
99 | "category": "00.build",
100 | "description": "Full release build (test+compile)",
101 | "steps": [
102 | {
103 | "exec": "npx projen"
104 | },
105 | {
106 | "spawn": "test"
107 | },
108 | {
109 | "spawn": "compile"
110 | },
111 | {
112 | "spawn": "synth"
113 | }
114 | ]
115 | },
116 | "test:watch": {
117 | "name": "test:watch",
118 | "category": "10.test",
119 | "description": "Run jest in watch mode",
120 | "steps": [
121 | {
122 | "exec": "jest --watch"
123 | }
124 | ]
125 | },
126 | "test:update": {
127 | "name": "test:update",
128 | "category": "10.test",
129 | "description": "Update jest snapshots",
130 | "steps": [
131 | {
132 | "exec": "jest --updateSnapshot"
133 | }
134 | ]
135 | },
136 | "upgrade-dependencies": {
137 | "name": "upgrade-dependencies",
138 | "env": {
139 | "CI": "0"
140 | },
141 | "steps": [
142 | {
143 | "exec": "npm-check-updates --upgrade --target=minor --reject='projen'"
144 | },
145 | {
146 | "exec": "npx projen"
147 | }
148 | ]
149 | },
150 | "upgrade-projen": {
151 | "name": "upgrade-projen",
152 | "env": {
153 | "CI": "0"
154 | },
155 | "steps": [
156 | {
157 | "exec": "npm-check-updates --upgrade --target=minor --filter='projen'"
158 | },
159 | {
160 | "exec": "npx projen"
161 | }
162 | ]
163 | },
164 | "default": {
165 | "name": "default",
166 | "steps": [
167 | {
168 | "exec": "node .projenrc.js"
169 | }
170 | ]
171 | },
172 | "watch": {
173 | "name": "watch",
174 | "category": "00.build",
175 | "description": "Watch & compile in the background",
176 | "steps": [
177 | {
178 | "exec": "tsc -w"
179 | }
180 | ]
181 | },
182 | "eslint": {
183 | "name": "eslint",
184 | "category": "10.test",
185 | "description": "Runs eslint against the codebase",
186 | "steps": [
187 | {
188 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js"
189 | }
190 | ]
191 | },
192 | "synth": {
193 | "name": "synth",
194 | "category": "00.build",
195 | "description": "Synthesizes your cdk app into cdk.out (part of \"yarn build\")",
196 | "steps": [
197 | {
198 | "exec": "cdk synth"
199 | }
200 | ]
201 | },
202 | "deploy": {
203 | "name": "deploy",
204 | "category": "20.release",
205 | "description": "Deploys your CDK app to the AWS cloud",
206 | "steps": [
207 | {
208 | "exec": "cdk deploy"
209 | }
210 | ]
211 | },
212 | "destroy": {
213 | "name": "destroy",
214 | "category": "20.release",
215 | "description": "Destroys your cdk app in the AWS cloud",
216 | "steps": [
217 | {
218 | "exec": "cdk destroy"
219 | }
220 | ]
221 | },
222 | "diff": {
223 | "name": "diff",
224 | "category": "99.misc",
225 | "description": "Diffs the currently deployed app against your code",
226 | "steps": [
227 | {
228 | "exec": "cdk diff"
229 | }
230 | ]
231 | }
232 | },
233 | "env": {
234 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")"
235 | },
236 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
237 | }
238 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.projenrc.js:
--------------------------------------------------------------------------------
1 | const { AwsCdkTypeScriptApp } = require('projen');
2 | const project = new AwsCdkTypeScriptApp({
3 | cdkVersion: '2.0.0-rc.16',
4 | defaultReleaseBranch: 'main',
5 | name: 'infra-async',
6 | deps: ['eslint', '@aws-sdk/client-sfn', '@aws-sdk/client-sqs'],
7 | devDeps: ['@types/aws-lambda', '@matthewbonig/cfn-response'],
8 | });
9 | project.synth();
--------------------------------------------------------------------------------
/chapters/testing/infra-async/.versionrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageFiles": [
3 | {
4 | "filename": ".version.tmp.json",
5 | "type": "plain-text"
6 | }
7 | ],
8 | "bumpFiles": [
9 | "package.json"
10 | ],
11 | "commitAll": false,
12 | "infile": ".changelog.tmp.md",
13 | "header": "",
14 | "skip": {
15 | "commit": true,
16 | "tag": true
17 | },
18 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
19 | }
20 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/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
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 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/README.md:
--------------------------------------------------------------------------------
1 | # replace this
--------------------------------------------------------------------------------
/chapters/testing/infra-async/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node --prefer-ts-exts src/main.ts",
3 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
4 | }
5 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "infra-async",
3 | "scripts": {
4 | "clobber": "npx projen clobber",
5 | "bump": "npx projen bump",
6 | "unbump": "npx projen unbump",
7 | "compile": "npx projen compile",
8 | "test:compile": "npx projen test:compile",
9 | "test": "npx projen test",
10 | "build": "npx projen build",
11 | "test:watch": "npx projen test:watch",
12 | "test:update": "npx projen test:update",
13 | "upgrade-dependencies": "npx projen upgrade-dependencies",
14 | "upgrade-projen": "npx projen upgrade-projen",
15 | "default": "npx projen default",
16 | "eslint": "npx projen eslint",
17 | "synth": "npx projen synth",
18 | "deploy": "npx projen deploy",
19 | "destroy": "npx projen destroy",
20 | "diff": "npx projen diff",
21 | "projen": "npx projen",
22 | "start": "npx projen start"
23 | },
24 | "devDependencies": {
25 | "@matthewbonig/cfn-response": "^0.1.2",
26 | "@types/aws-lambda": "^8.10.81",
27 | "@types/jest": "^26.0.24",
28 | "@types/node": "^10.17.0",
29 | "@typescript-eslint/eslint-plugin": "^4.28.3",
30 | "@typescript-eslint/parser": "^4.28.3",
31 | "aws-cdk": "^2.0.0-rc.16",
32 | "eslint": "^7.30.0",
33 | "eslint-import-resolver-node": "^0.3.4",
34 | "eslint-import-resolver-typescript": "^2.4.0",
35 | "eslint-plugin-import": "^2.23.4",
36 | "jest": "^27.0.6",
37 | "jest-junit": "^12",
38 | "json-schema": "^0.3.0",
39 | "npm-check-updates": "^11",
40 | "projen": "^0.17.95",
41 | "standard-version": "^9",
42 | "ts-jest": "^27.0.3",
43 | "ts-node": "^10.1.0",
44 | "typescript": "^4.3.5"
45 | },
46 | "dependencies": {
47 | "@aws-cdk/assert": "^2.0.0-rc.16",
48 | "@aws-sdk/client-sfn": "^3.22.0",
49 | "@aws-sdk/client-sqs": "^3.22.0",
50 | "aws-cdk-lib": "^2.0.0-rc.16",
51 | "constructs": "^10.0.5",
52 | "eslint": "^7.30.0"
53 | },
54 | "bundledDependencies": [],
55 | "license": "Apache-2.0",
56 | "version": "0.0.0",
57 | "jest": {
58 | "testMatch": [
59 | "**/__tests__/**/*.ts?(x)",
60 | "**/?(*.)+(spec|test).ts?(x)"
61 | ],
62 | "clearMocks": true,
63 | "collectCoverage": true,
64 | "coverageReporters": [
65 | "json",
66 | "lcov",
67 | "clover",
68 | "text"
69 | ],
70 | "coverageDirectory": "coverage",
71 | "coveragePathIgnorePatterns": [
72 | "/node_modules/"
73 | ],
74 | "testPathIgnorePatterns": [
75 | "/node_modules/"
76 | ],
77 | "watchPathIgnorePatterns": [
78 | "/node_modules/"
79 | ],
80 | "reporters": [
81 | "default",
82 | [
83 | "jest-junit",
84 | {
85 | "outputDirectory": "test-reports"
86 | }
87 | ]
88 | ],
89 | "preset": "ts-jest",
90 | "globals": {
91 | "ts-jest": {
92 | "tsconfig": "tsconfig.jest.json"
93 | }
94 | }
95 | },
96 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
97 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/PubSubStack.QueueHandler.ts:
--------------------------------------------------------------------------------
1 | import { SendTaskSuccessCommand, SFNClient } from '@aws-sdk/client-sfn';
2 | import { SQSEvent, SQSRecord } from 'aws-lambda';
3 |
4 | let config = { region: 'us-east-1' };
5 | const sfn = new SFNClient(config);
6 |
7 | function addTester(handler: Function) {
8 | return async (event: SQSEvent, context: any) => {
9 | console.log('Event: ', JSON.stringify(event, null, 2));
10 |
11 | // look for a test message:
12 | // this would change depending on how the test message was published
13 | // in this case, just look to see if any records have a taskToken on them
14 | // again, demo code. You'd likely want to test differently here.
15 | const testMessages = event.Records.filter((message: SQSRecord) => {
16 | try {
17 | return !!(JSON.parse(JSON.parse(message.body).Message).taskToken);
18 | } catch (err) {
19 | // ok, we couldn't parse which means we didn't have the write structure.
20 | // I'd love a tryParse or something on JSON but we don't have it,
21 | // so this makes the most sense
22 | return false;
23 | }
24 | });
25 |
26 | if (!!testMessages && testMessages.length > 0) {
27 | for (const testMessage of testMessages) {
28 | try {
29 | const { taskToken } = JSON.parse(JSON.parse(testMessage.body).Message);
30 |
31 | // we got the test message, great!
32 | // let's let the task know that
33 | await sfn.send(new SendTaskSuccessCommand({
34 | taskToken,
35 | output: '{"success":"The tests passed"}',
36 | }));
37 | console.log('Activity sent success');
38 |
39 | } catch (err) {
40 | console.error('Error when trying to send task success: ', err);
41 | throw err;
42 | }
43 | }
44 | }
45 |
46 | // let's go ahead and remove the test messages from what the normal handler now needs to process
47 | const testRemove = new Set(testMessages);
48 | event.Records = event.Records.filter(x => !testRemove.has(x));
49 |
50 | // time to do the normal thing
51 | return handler(event, context);
52 | };
53 | }
54 |
55 | export const originalHandler = async (event: any) => {
56 | console.log('Event:', JSON.stringify(event, null, 2));
57 | };
58 |
59 | export const handler = addTester(originalHandler);
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/PubSubStack.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import { CustomResource, Duration, Stack, StackProps } from 'aws-cdk-lib';
3 | import { Effect, IGrantable, PolicyStatement } from 'aws-cdk-lib/aws-iam';
4 | import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
5 | import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
6 | import { ITopic, Topic } from 'aws-cdk-lib/aws-sns';
7 | import { SqsSubscription } from 'aws-cdk-lib/aws-sns-subscriptions';
8 | import { Queue } from 'aws-cdk-lib/aws-sqs';
9 | import {
10 | IntegrationPattern,
11 | JsonPath,
12 | StateMachine,
13 | StateMachineType,
14 | TaskInput,
15 | } from 'aws-cdk-lib/aws-stepfunctions';
16 | import { LambdaInvoke, SnsPublish } from 'aws-cdk-lib/aws-stepfunctions-tasks';
17 | import { Construct } from 'constructs';
18 |
19 | export class PubSubStack extends Stack {
20 | constructor(scope: Construct, id: string, props: StackProps = {}) {
21 | super(scope, id, props);
22 |
23 | const topic = new Topic(this, 'IntakeTopic', {});
24 |
25 | const queue = new Queue(this, 'ProcessingQueue', {});
26 |
27 | topic.addSubscription(new SqsSubscription(queue, {}));
28 | const handler = new NodejsFunction(this, 'QueueHandler', {});
29 | handler.addEventSource(new SqsEventSource(queue, {}));
30 |
31 | new PubSubTest(this, 'Tests', { topic }).grant(handler);
32 |
33 | }
34 | }
35 |
36 | interface PubSubTestProps {
37 | topic: ITopic;
38 | }
39 |
40 | export class PubSubTest extends Construct {
41 | private readonly stateMachine: StateMachine;
42 |
43 | constructor(scope: Construct, id: string, props: PubSubTestProps) {
44 | super(scope, id);
45 |
46 |
47 | const testBasicEndToEnd = new SnsPublish(this, 'TestBasicEndToEnd', {
48 | comment: 'Sends a test message to the SNS topic',
49 | topic: props.topic,
50 | message: TaskInput.fromObject({
51 | timestamp: new Date().toISOString(),
52 | taskToken: JsonPath.stringAt('$$.Task.Token'),
53 | }),
54 | integrationPattern: IntegrationPattern.WAIT_FOR_TASK_TOKEN,
55 | resultPath: JsonPath.DISCARD,
56 | timeout: Duration.seconds(30),
57 | });
58 |
59 |
60 | const sendCfnResponseHandler = new NodejsFunction(this, 'CfnResponseHandler', {
61 | entry: path.join(__dirname, 'test-handlers', 'SendCfnResponse.handler.ts'),
62 | });
63 | let sendResponse = new LambdaInvoke(this, 'SendCustomResourceResponse', {
64 | comment: 'Sends a response to the Custom Resource letting it know the test passed',
65 | lambdaFunction: sendCfnResponseHandler,
66 | });
67 | testBasicEndToEnd.next(sendResponse);
68 |
69 | testBasicEndToEnd.addCatch(sendResponse, { resultPath: JsonPath.stringAt('$.taskresult') });
70 |
71 | this.stateMachine = new StateMachine(this, 'Tests', {
72 | stateMachineType: StateMachineType.STANDARD,
73 | definition: testBasicEndToEnd,
74 | });
75 |
76 | const startTestHandler = new NodejsFunction(this, 'StartTestsHandler', {
77 | entry: path.join(__dirname, 'test-handlers', 'StartTests.handler.ts'),
78 | environment: {
79 | STATE_MACHINE_ARN: this.stateMachine.stateMachineArn,
80 | },
81 | });
82 | this.stateMachine.grantStartExecution(startTestHandler);
83 |
84 | new CustomResource(this, 'StartTestsCustomResource', {
85 | serviceToken: startTestHandler.functionArn,
86 | properties: {
87 | timestamp: new Date().toISOString(), // so we always run the test
88 | },
89 | }).node.addDependency(this.stateMachine);
90 | }
91 |
92 | public grant(grantable: IGrantable) {
93 | grantable.grantPrincipal.addToPrincipalPolicy(new PolicyStatement({
94 | resources: [this.stateMachine.stateMachineArn],
95 | actions: ['states:SendTaskSuccess'],
96 | effect: Effect.ALLOW,
97 | }));
98 | }
99 | }
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/main.ts:
--------------------------------------------------------------------------------
1 | import { App } from 'aws-cdk-lib';
2 | import { PubSubStack } from './PubSubStack';
3 |
4 | // for development, use account/region from cdk cli
5 | const devEnv = {
6 | account: process.env.CDK_DEFAULT_ACCOUNT,
7 | region: process.env.CDK_DEFAULT_REGION,
8 | };
9 |
10 | const app = new App();
11 |
12 | new PubSubStack(app, 'SimplePubSub', { env: devEnv });
13 |
14 | app.synth();
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/test-handlers/CheckForDLQMessage.handler.ts:
--------------------------------------------------------------------------------
1 | import { ReceiveMessageCommand, SQSClient } from '@aws-sdk/client-sqs';
2 |
3 | const queueName = process.env.DLQ_NAME;
4 | const client = new SQSClient({ region: 'us-east-1' });
5 | export const handler = async (event: any) => {
6 | console.log('Event: ', JSON.stringify(event, null, 2));
7 | console.log('Going to read queue ', queueName);
8 | const { Messages: messages } = await client.send(new ReceiveMessageCommand({
9 | QueueUrl: queueName,
10 | MaxNumberOfMessages: 10,
11 | }));
12 | console.log(`Found ${messages?.length} messages`);
13 | return { dlqMessageFound: !!messages ? messages!.length > 0 : false };
14 | };
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/test-handlers/SendCfnResponse.handler.ts:
--------------------------------------------------------------------------------
1 | import { ResponseStatus, send } from '@matthewbonig/cfn-response';
2 |
3 | export const handler = async (event: any) => {
4 | console.log('Event: ', JSON.stringify(event, null, 2));
5 | if (event.taskresult && event.taskresult.Error === 'States.Timeout') {
6 | return send({ ...event.customResource, Status: ResponseStatus.FAILED, Data: {} });
7 | }
8 | try {
9 | return await send({ ...event.customResource, Status: ResponseStatus.SUCCESS, Data: {} });
10 | } catch (err) {
11 | console.error('Error occurred while responding to Custom Resource:', err);
12 | }
13 | };
--------------------------------------------------------------------------------
/chapters/testing/infra-async/src/test-handlers/StartTests.handler.ts:
--------------------------------------------------------------------------------
1 | import { SFNClient, StartExecutionCommand } from '@aws-sdk/client-sfn';
2 | import { ResponseStatus, send } from '@matthewbonig/cfn-response';
3 | import { CloudFormationCustomResourceEvent } from 'aws-lambda';
4 |
5 |
6 | const stateMachineArn = process.env.STATE_MACHINE_ARN;
7 | export const handler = async (event: CloudFormationCustomResourceEvent, context: any) => {
8 | console.log('Event: ', JSON.stringify(event, null, 2));
9 | const PhysicalResourceId = context.logStreamName;
10 |
11 | if (event.RequestType === 'Delete') {
12 | // let's do nothing.
13 | return send({ ...event, PhysicalResourceId: context.logStreamName, Status: ResponseStatus.SUCCESS, Data: {}, NoEcho: false, Reason: '' });
14 | }
15 | try {
16 | const client = new SFNClient({});
17 | const { StackId, RequestId, LogicalResourceId, ResponseURL } = event;
18 | const customResource = { PhysicalResourceId, StackId, RequestId, LogicalResourceId, ResponseURL };
19 | console.log('Staring test suite with input: ', customResource);
20 | await client.send(new StartExecutionCommand({
21 | stateMachineArn,
22 | input: JSON.stringify({ customResource }),
23 | }));
24 | console.log('Test suite started...');
25 | } catch (err) {
26 | console.error('Error: ', err);
27 | }
28 | };
--------------------------------------------------------------------------------
/chapters/testing/infra-async/test/main.test.ts:
--------------------------------------------------------------------------------
1 | import '@aws-cdk/assert/jest';
2 | import { App } from 'aws-cdk-lib';
3 | import { Code } from 'aws-cdk-lib/aws-lambda';
4 | import { CodeConfig } from 'aws-cdk-lib/lib/aws-lambda';
5 | import { PubSubStack } from '../src/PubSubStack';
6 |
7 | describe('mocking Code', () => {
8 | let fromAssetMock: jest.SpyInstance;
9 |
10 | beforeAll(() => {
11 | // mock the Code calls so tests run quicker
12 | fromAssetMock = jest.spyOn(Code, 'fromAsset').mockReturnValue({
13 | isInline: false,
14 | bind: (): CodeConfig => {
15 | return {
16 | s3Location: {
17 | bucketName: 'my-bucket',
18 | objectKey: 'my-key',
19 | },
20 | };
21 | },
22 | bindToResource: () => {
23 | return;
24 | },
25 | } as any);
26 | });
27 | afterAll(() => {
28 | // restore the Code from mock
29 | fromAssetMock?.mockRestore();
30 | });
31 |
32 | test('Check snapshot', () => {
33 | const app = new App();
34 | const stack = new PubSubStack(app, 'test');
35 |
36 | expect(app.synth().getStackArtifact(stack.artifactId).template).toMatchSnapshot();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/infra-async/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": "src",
4 | "outDir": "lib",
5 | "alwaysStrict": true,
6 | "declaration": true,
7 | "experimentalDecorators": true,
8 | "inlineSourceMap": true,
9 | "inlineSources": true,
10 | "lib": [
11 | "es2018"
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": "ES2018"
27 | },
28 | "include": [
29 | "src/**/*.ts"
30 | ],
31 | "exclude": [
32 | "node_modules",
33 | "lib",
34 | "cdk.out"
35 | ],
36 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
37 | }
38 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.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 | "indent": [
44 | "off"
45 | ],
46 | "@typescript-eslint/indent": [
47 | "error",
48 | 2
49 | ],
50 | "quotes": [
51 | "error",
52 | "single",
53 | {
54 | "avoidEscape": true
55 | }
56 | ],
57 | "comma-dangle": [
58 | "error",
59 | "always-multiline"
60 | ],
61 | "comma-spacing": [
62 | "error",
63 | {
64 | "before": false,
65 | "after": true
66 | }
67 | ],
68 | "no-multi-spaces": [
69 | "error",
70 | {
71 | "ignoreEOLComments": false
72 | }
73 | ],
74 | "array-bracket-spacing": [
75 | "error",
76 | "never"
77 | ],
78 | "array-bracket-newline": [
79 | "error",
80 | "consistent"
81 | ],
82 | "object-curly-spacing": [
83 | "error",
84 | "always"
85 | ],
86 | "object-curly-newline": [
87 | "error",
88 | {
89 | "multiline": true,
90 | "consistent": true
91 | }
92 | ],
93 | "object-property-newline": [
94 | "error",
95 | {
96 | "allowAllPropertiesOnSameLine": true
97 | }
98 | ],
99 | "keyword-spacing": [
100 | "error"
101 | ],
102 | "brace-style": [
103 | "error",
104 | "1tbs",
105 | {
106 | "allowSingleLine": true
107 | }
108 | ],
109 | "space-before-blocks": [
110 | "error"
111 | ],
112 | "curly": [
113 | "error",
114 | "multi-line",
115 | "consistent"
116 | ],
117 | "@typescript-eslint/member-delimiter-style": [
118 | "error"
119 | ],
120 | "semi": [
121 | "error",
122 | "always"
123 | ],
124 | "max-len": [
125 | "error",
126 | {
127 | "code": 150,
128 | "ignoreUrls": true,
129 | "ignoreStrings": true,
130 | "ignoreTemplateLiterals": true,
131 | "ignoreComments": true,
132 | "ignoreRegExpLiterals": true
133 | }
134 | ],
135 | "quote-props": [
136 | "error",
137 | "consistent-as-needed"
138 | ],
139 | "@typescript-eslint/no-require-imports": [
140 | "error"
141 | ],
142 | "import/no-extraneous-dependencies": [
143 | "error",
144 | {
145 | "devDependencies": [
146 | "**/test/**",
147 | "**/build-tools/**"
148 | ],
149 | "optionalDependencies": false,
150 | "peerDependencies": true
151 | }
152 | ],
153 | "import/no-unresolved": [
154 | "error"
155 | ],
156 | "import/order": [
157 | "warn",
158 | {
159 | "groups": [
160 | "builtin",
161 | "external"
162 | ],
163 | "alphabetize": {
164 | "order": "asc",
165 | "caseInsensitive": true
166 | }
167 | }
168 | ],
169 | "no-duplicate-imports": [
170 | "error"
171 | ],
172 | "no-shadow": [
173 | "off"
174 | ],
175 | "@typescript-eslint/no-shadow": [
176 | "error"
177 | ],
178 | "key-spacing": [
179 | "error"
180 | ],
181 | "no-multiple-empty-lines": [
182 | "error"
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 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.gitattributes:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | *.snap linguist-generated
4 | /.eslintrc.json linguist-generated
5 | /.gitattributes linguist-generated
6 | /.github/pull_request_template.md linguist-generated
7 | /.github/workflows/build.yml linguist-generated
8 | /.github/workflows/stale.yml linguist-generated
9 | /.github/workflows/upgrade.yml linguist-generated
10 | /.gitignore linguist-generated
11 | /.mergify.yml linguist-generated
12 | /.npmignore linguist-generated
13 | /.projen/** linguist-generated
14 | /.projen/deps.json linguist-generated
15 | /.projen/tasks.json linguist-generated
16 | /cdk.json linguist-generated
17 | /LICENSE linguist-generated
18 | /package.json linguist-generated
19 | /tsconfig.eslint.json linguist-generated
20 | /tsconfig.jest.json linguist-generated
21 | /tsconfig.json linguist-generated
22 | /yarn.lock linguist-generated
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes #
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.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 | permissions:
11 | checks: write
12 | contents: write
13 | actions: write
14 | env:
15 | CI: "true"
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | with:
20 | ref: ${{ github.event.pull_request.head.ref }}
21 | repository: ${{ github.event.pull_request.head.repo.full_name }}
22 | - name: Set git identity
23 | run: |-
24 | git config user.name "Automation"
25 | git config user.email "github-actions@github.com"
26 | - name: Install dependencies
27 | run: yarn install --check-files --frozen-lockfile
28 | - name: build
29 | run: npx projen build
30 | - name: Check for changes
31 | id: git_diff
32 | run: git diff --exit-code || echo "::set-output name=has_changes::true"
33 | - if: steps.git_diff.outputs.has_changes
34 | name: Commit and push changes (if changed)
35 | run: 'git add . && git commit -m "chore: self mutation" && git push origin
36 | HEAD:${{ github.event.pull_request.head.ref }}'
37 | - if: steps.git_diff.outputs.has_changes
38 | name: Update status check (if changed)
39 | run: gh api -X POST /repos/${{ github.event.pull_request.head.repo.full_name
40 | }}/check-runs -F name="build" -F head_sha="$(git rev-parse HEAD)" -F
41 | status="completed" -F conclusion="success"
42 | env:
43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44 | - if: steps.git_diff.outputs.has_changes
45 | name: Cancel workflow (if changed)
46 | run: gh api -X POST /repos/${{ github.event.pull_request.head.repo.full_name
47 | }}/actions/runs/${{ github.run_id }}/cancel
48 | env:
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: stale
4 | on:
5 | schedule:
6 | - cron: 0 1 * * *
7 | workflow_dispatch: {}
8 | jobs:
9 | stale:
10 | runs-on: ubuntu-latest
11 | permissions:
12 | issues: write
13 | pull-requests: write
14 | steps:
15 | - uses: actions/stale@v4
16 | with:
17 | days-before-stale: -1
18 | days-before-close: -1
19 | days-before-pr-stale: 14
20 | days-before-pr-close: 2
21 | stale-pr-message: This pull request is now marked as stale because it hasn't
22 | seen activity for a while. Add a comment or it will be closed soon.
23 | close-pr-message: Closing this pull request as it hasn't seen activity for a
24 | while. Please add a comment @mentioning a maintainer to reopen.
25 | stale-pr-label: stale
26 | days-before-issue-stale: 60
27 | days-before-issue-close: 7
28 | stale-issue-message: This issue is now marked as stale because it hasn't seen
29 | activity for a while. Add a comment or it will be closed soon.
30 | close-issue-message: Closing this issue as it hasn't seen activity for a while.
31 | Please add a comment @mentioning a maintainer to reopen.
32 | stale-issue-label: stale
33 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.github/workflows/upgrade.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: upgrade
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 | conclusion: ${{ steps.build.outputs.conclusion }}
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | - name: Install dependencies
20 | run: yarn install --check-files --frozen-lockfile
21 | - name: Upgrade dependencies
22 | run: npx projen upgrade
23 | - name: Build
24 | id: build
25 | run: npx projen build && echo "::set-output name=conclusion::success" || echo
26 | "::set-output name=conclusion::failure"
27 | - name: Create Patch
28 | run: |-
29 | git add .
30 | git diff --patch --staged > .upgrade.tmp.patch
31 | - name: Upload patch
32 | uses: actions/upload-artifact@v2
33 | with:
34 | name: .upgrade.tmp.patch
35 | path: .upgrade.tmp.patch
36 | pr:
37 | name: Create Pull Request
38 | needs: upgrade
39 | runs-on: ubuntu-latest
40 | permissions:
41 | contents: write
42 | pull-requests: write
43 | checks: write
44 | steps:
45 | - name: Checkout
46 | uses: actions/checkout@v2
47 | - name: Download patch
48 | uses: actions/download-artifact@v2
49 | with:
50 | name: .upgrade.tmp.patch
51 | path: ${{ runner.temp }}
52 | - name: Apply patch
53 | run: '[ -s ${{ runner.temp }}/.upgrade.tmp.patch ] && git apply ${{ runner.temp
54 | }}/.upgrade.tmp.patch || echo "Empty patch. Skipping."'
55 | - name: Create Pull Request
56 | id: create-pr
57 | uses: peter-evans/create-pull-request@v3
58 | with:
59 | token: ${{ secrets.GITHUB_TOKEN }}
60 | commit-message: >-
61 | chore(deps): upgrade dependencies
62 |
63 |
64 | Upgrades project dependencies. See details in [workflow run].
65 |
66 |
67 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
68 |
69 |
70 | ------
71 |
72 |
73 | *Automatically created by projen via the "upgrade" workflow*
74 | branch: github-actions/upgrade
75 | title: "chore(deps): upgrade dependencies"
76 | body: >-
77 | Upgrades project dependencies. See details in [workflow run].
78 |
79 |
80 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
81 |
82 |
83 | ------
84 |
85 |
86 | *Automatically created by projen via the "upgrade" workflow*
87 | author: Automation
88 | committer: Automation
89 | - name: Update status check
90 | if: steps.create-pr.outputs.pull-request-url != ''
91 | run: "curl -i --fail -X POST -H \"Accept: application/vnd.github.v3+json\" -H
92 | \"Authorization: token ${GITHUB_TOKEN}\"
93 | https://api.github.com/repos/${{ github.repository }}/check-runs -d
94 | '{\"name\":\"build\",\"head_sha\":\"github-actions/upgrade\",\"status\
95 | \":\"completed\",\"conclusion\":\"${{ needs.upgrade.outputs.conclusion
96 | }}\",\"output\":{\"title\":\"Created via the upgrade
97 | workflow.\",\"summary\":\"Action run URL: https://github.com/${{
98 | github.repository }}/actions/runs/${{ github.run_id }}\"}}'"
99 | env:
100 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
101 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.gitignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | !/.gitattributes
3 | !/.projen/tasks.json
4 | !/.projen/deps.json
5 | !/.github/workflows/stale.yml
6 | !/package.json
7 | !/LICENSE
8 | !/.npmignore
9 | logs
10 | *.log
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | lerna-debug.log*
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 | pids
17 | *.pid
18 | *.seed
19 | *.pid.lock
20 | lib-cov
21 | coverage
22 | *.lcov
23 | .nyc_output
24 | build/Release
25 | node_modules/
26 | jspm_packages/
27 | *.tsbuildinfo
28 | .eslintcache
29 | *.tgz
30 | .yarn-integrity
31 | .cache
32 | !/.projenrc.js
33 | /test-reports/
34 | junit.xml
35 | /coverage/
36 | !/.github/workflows/build.yml
37 | !/.mergify.yml
38 | !/.github/workflows/upgrade.yml
39 | !/.github/pull_request_template.md
40 | !/test/
41 | !/tsconfig.json
42 | /lib
43 | !/src/
44 | /dist/
45 | !/tsconfig.jest.json
46 | !/.eslintrc.json
47 | !/tsconfig.eslint.json
48 | cdk.out/
49 | .cdk.staging/
50 | .parcel-cache/
51 | !/cdk.json
52 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/aws.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/jsLinters/eslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/refactoring.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.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 | - -label~=(do-not-merge)
15 | - status-success=build
16 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.npmignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | /.projen/
3 | /test-reports/
4 | junit.xml
5 | /coverage/
6 | /.mergify.yml
7 | /test/
8 | !/lib/
9 | /src/
10 | !/lib/**/*.js
11 | !/lib/**/*.d.ts
12 | dist
13 | /tsconfig.json
14 | /.github/
15 | /.vscode/
16 | /.idea/
17 | /.projenrc.js
18 | tsconfig.tsbuildinfo
19 | /tsconfig.jest.json
20 | /.eslintrc.json
21 | /tsconfig.eslint.json
22 | cdk.out/
23 | .cdk.staging/
24 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.projen/deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "name": "@types/jest",
5 | "type": "build"
6 | },
7 | {
8 | "name": "@types/node",
9 | "version": "^10.17.0",
10 | "type": "build"
11 | },
12 | {
13 | "name": "@typescript-eslint/eslint-plugin",
14 | "type": "build"
15 | },
16 | {
17 | "name": "@typescript-eslint/parser",
18 | "type": "build"
19 | },
20 | {
21 | "name": "aws-cdk",
22 | "version": "^1.120.0",
23 | "type": "build"
24 | },
25 | {
26 | "name": "eslint",
27 | "type": "build"
28 | },
29 | {
30 | "name": "eslint-import-resolver-node",
31 | "type": "build"
32 | },
33 | {
34 | "name": "eslint-import-resolver-typescript",
35 | "type": "build"
36 | },
37 | {
38 | "name": "eslint-plugin-import",
39 | "type": "build"
40 | },
41 | {
42 | "name": "jest",
43 | "type": "build"
44 | },
45 | {
46 | "name": "jest-junit",
47 | "version": "^12",
48 | "type": "build"
49 | },
50 | {
51 | "name": "json-schema",
52 | "type": "build"
53 | },
54 | {
55 | "name": "npm-check-updates",
56 | "version": "^11",
57 | "type": "build"
58 | },
59 | {
60 | "name": "projen",
61 | "type": "build"
62 | },
63 | {
64 | "name": "ts-jest",
65 | "type": "build"
66 | },
67 | {
68 | "name": "ts-node",
69 | "version": "^9",
70 | "type": "build"
71 | },
72 | {
73 | "name": "typescript",
74 | "type": "build"
75 | },
76 | {
77 | "name": "@aws-cdk/assert",
78 | "version": "^1.120.0",
79 | "type": "runtime"
80 | },
81 | {
82 | "name": "@aws-cdk/assertions",
83 | "version": "^1.120.0",
84 | "type": "runtime"
85 | },
86 | {
87 | "name": "@aws-cdk/aws-s3",
88 | "version": "^1.120.0",
89 | "type": "runtime"
90 | },
91 | {
92 | "name": "@aws-cdk/core",
93 | "version": "^1.120.0",
94 | "type": "runtime"
95 | }
96 | ],
97 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
98 | }
99 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.projen/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": {
3 | "clobber": {
4 | "name": "clobber",
5 | "description": "hard resets to HEAD of origin and cleans the local repo",
6 | "env": {
7 | "BRANCH": "$(git branch --show-current)"
8 | },
9 | "steps": [
10 | {
11 | "exec": "git checkout -b scratch",
12 | "name": "save current HEAD in \"scratch\" branch"
13 | },
14 | {
15 | "exec": "git checkout $BRANCH"
16 | },
17 | {
18 | "exec": "git fetch origin",
19 | "name": "fetch latest changes from origin"
20 | },
21 | {
22 | "exec": "git reset --hard origin/$BRANCH",
23 | "name": "hard reset to origin commit"
24 | },
25 | {
26 | "exec": "git clean -fdx",
27 | "name": "clean all untracked files"
28 | },
29 | {
30 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)"
31 | }
32 | ],
33 | "condition": "git diff --exit-code > /dev/null"
34 | },
35 | "compile": {
36 | "name": "compile",
37 | "description": "Only compile"
38 | },
39 | "test:compile": {
40 | "name": "test:compile",
41 | "description": "compiles the test code",
42 | "steps": [
43 | {
44 | "exec": "tsc --noEmit --project tsconfig.jest.json"
45 | }
46 | ]
47 | },
48 | "test": {
49 | "name": "test",
50 | "description": "Run tests",
51 | "steps": [
52 | {
53 | "exec": "rm -fr lib/"
54 | },
55 | {
56 | "spawn": "test:compile"
57 | },
58 | {
59 | "exec": "jest --passWithNoTests --all --updateSnapshot"
60 | },
61 | {
62 | "spawn": "eslint"
63 | }
64 | ]
65 | },
66 | "build": {
67 | "name": "build",
68 | "description": "Full release build (test+compile)",
69 | "steps": [
70 | {
71 | "exec": "npx projen"
72 | },
73 | {
74 | "spawn": "test"
75 | },
76 | {
77 | "spawn": "compile"
78 | },
79 | {
80 | "spawn": "synth"
81 | }
82 | ]
83 | },
84 | "test:watch": {
85 | "name": "test:watch",
86 | "description": "Run jest in watch mode",
87 | "steps": [
88 | {
89 | "exec": "jest --watch"
90 | }
91 | ]
92 | },
93 | "test:update": {
94 | "name": "test:update",
95 | "description": "Update jest snapshots",
96 | "steps": [
97 | {
98 | "exec": "jest --updateSnapshot"
99 | }
100 | ]
101 | },
102 | "upgrade": {
103 | "name": "upgrade",
104 | "description": "upgrade dependencies",
105 | "env": {
106 | "CI": "0"
107 | },
108 | "steps": [
109 | {
110 | "exec": "npm-check-updates --upgrade --target=minor --reject='projen'"
111 | },
112 | {
113 | "exec": "yarn install --check-files"
114 | },
115 | {
116 | "exec": "yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk eslint eslint-import-resolver-node eslint-import-resolver-typescript eslint-plugin-import jest jest-junit json-schema npm-check-updates ts-jest ts-node typescript @aws-cdk/assert @aws-cdk/assertions @aws-cdk/aws-s3 @aws-cdk/core"
117 | },
118 | {
119 | "exec": "npx projen"
120 | }
121 | ]
122 | },
123 | "upgrade-projen": {
124 | "name": "upgrade-projen",
125 | "description": "upgrade projen",
126 | "env": {
127 | "CI": "0"
128 | },
129 | "steps": [
130 | {
131 | "exec": "npm-check-updates --upgrade --target=minor --filter='projen'"
132 | },
133 | {
134 | "exec": "yarn install --check-files"
135 | },
136 | {
137 | "exec": "yarn upgrade projen"
138 | },
139 | {
140 | "exec": "npx projen"
141 | }
142 | ]
143 | },
144 | "default": {
145 | "name": "default",
146 | "steps": [
147 | {
148 | "exec": "node .projenrc.js"
149 | }
150 | ]
151 | },
152 | "watch": {
153 | "name": "watch",
154 | "description": "Watch & compile in the background",
155 | "steps": [
156 | {
157 | "exec": "tsc --build -w"
158 | }
159 | ]
160 | },
161 | "eslint": {
162 | "name": "eslint",
163 | "description": "Runs eslint against the codebase",
164 | "steps": [
165 | {
166 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js"
167 | }
168 | ]
169 | },
170 | "synth": {
171 | "name": "synth",
172 | "description": "Synthesizes your cdk app into cdk.out (part of \"yarn build\")",
173 | "steps": [
174 | {
175 | "exec": "cdk synth"
176 | }
177 | ]
178 | },
179 | "deploy": {
180 | "name": "deploy",
181 | "description": "Deploys your CDK app to the AWS cloud",
182 | "steps": [
183 | {
184 | "exec": "cdk deploy"
185 | }
186 | ]
187 | },
188 | "destroy": {
189 | "name": "destroy",
190 | "description": "Destroys your cdk app in the AWS cloud",
191 | "steps": [
192 | {
193 | "exec": "cdk destroy"
194 | }
195 | ]
196 | },
197 | "diff": {
198 | "name": "diff",
199 | "description": "Diffs the currently deployed app against your code",
200 | "steps": [
201 | {
202 | "exec": "cdk diff"
203 | }
204 | ]
205 | }
206 | },
207 | "env": {
208 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")"
209 | },
210 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
211 | }
212 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/.projenrc.js:
--------------------------------------------------------------------------------
1 | const { AwsCdkTypeScriptApp } = require('projen');
2 | const project = new AwsCdkTypeScriptApp({
3 | cdkVersion: '1.120.0',
4 | defaultReleaseBranch: 'main',
5 | name: 'refactoring',
6 |
7 | cdkDependencies: [
8 | '@aws-cdk/assertions',
9 | '@aws-cdk/aws-s3',
10 | ],
11 | // deps: [], /* Runtime dependencies of this module. */
12 | // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */
13 | // devDeps: [], /* Build dependencies for this module. */
14 | // packageName: undefined, /* The "name" in package.json. */
15 | // projectType: ProjectType.UNKNOWN, /* Which type of project this is (library/app). */
16 | // releaseWorkflow: undefined, /* Define a GitHub workflow for releasing from "main" when new versions are bumped. */
17 | });
18 | project.synth();
--------------------------------------------------------------------------------
/chapters/testing/refactoring/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/README.md:
--------------------------------------------------------------------------------
1 | # replace this
--------------------------------------------------------------------------------
/chapters/testing/refactoring/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node --prefer-ts-exts src/main.ts",
3 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
4 | }
5 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "refactoring",
3 | "scripts": {
4 | "clobber": "npx projen clobber",
5 | "compile": "npx projen compile",
6 | "test:compile": "npx projen test:compile",
7 | "test": "npx projen test",
8 | "build": "npx projen build",
9 | "test:watch": "npx projen test:watch",
10 | "test:update": "npx projen test:update",
11 | "upgrade": "npx projen upgrade",
12 | "upgrade-projen": "npx projen upgrade-projen",
13 | "default": "npx projen default",
14 | "eslint": "npx projen eslint",
15 | "synth": "npx projen synth",
16 | "deploy": "npx projen deploy",
17 | "destroy": "npx projen destroy",
18 | "diff": "npx projen diff",
19 | "projen": "npx projen"
20 | },
21 | "devDependencies": {
22 | "@types/jest": "^27.0.1",
23 | "@types/node": "^10.17.0",
24 | "@typescript-eslint/eslint-plugin": "^4.30.0",
25 | "@typescript-eslint/parser": "^4.30.0",
26 | "aws-cdk": "^1.120.0",
27 | "eslint": "^7.32.0",
28 | "eslint-import-resolver-node": "^0.3.6",
29 | "eslint-import-resolver-typescript": "^2.4.0",
30 | "eslint-plugin-import": "^2.24.2",
31 | "jest": "^27.1.0",
32 | "jest-junit": "^12",
33 | "json-schema": "^0.3.0",
34 | "npm-check-updates": "^11",
35 | "projen": "^0.27.37",
36 | "ts-jest": "^27.0.5",
37 | "ts-node": "^9",
38 | "typescript": "^4.4.2"
39 | },
40 | "dependencies": {
41 | "@aws-cdk/assert": "^1.120.0",
42 | "@aws-cdk/assertions": "^1.120.0",
43 | "@aws-cdk/aws-s3": "^1.120.0",
44 | "@aws-cdk/core": "^1.120.0"
45 | },
46 | "bundledDependencies": [],
47 | "license": "Apache-2.0",
48 | "version": "0.0.0",
49 | "jest": {
50 | "testMatch": [
51 | "**/__tests__/**/*.ts?(x)",
52 | "**/?(*.)+(spec|test).ts?(x)"
53 | ],
54 | "clearMocks": true,
55 | "collectCoverage": true,
56 | "coverageReporters": [
57 | "json",
58 | "lcov",
59 | "clover",
60 | "text"
61 | ],
62 | "coverageDirectory": "coverage",
63 | "coveragePathIgnorePatterns": [
64 | "/node_modules/"
65 | ],
66 | "testPathIgnorePatterns": [
67 | "/node_modules/"
68 | ],
69 | "watchPathIgnorePatterns": [
70 | "/node_modules/"
71 | ],
72 | "reporters": [
73 | "default",
74 | [
75 | "jest-junit",
76 | {
77 | "outputDirectory": "test-reports"
78 | }
79 | ]
80 | ],
81 | "preset": "ts-jest",
82 | "globals": {
83 | "ts-jest": {
84 | "tsconfig": "tsconfig.jest.json"
85 | }
86 | }
87 | },
88 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
89 | }
--------------------------------------------------------------------------------
/chapters/testing/refactoring/src/LogicalIdMapper.ts:
--------------------------------------------------------------------------------
1 | import { CfnElement, CfnResource, IAspect, IConstruct, Stack } from '@aws-cdk/core';
2 |
3 | export interface IdMap {
4 | [key: string]: string;
5 | }
6 |
7 | export class LogicalIdMapper implements IAspect {
8 | constructor(private idMap: IdMap) {
9 | }
10 |
11 | visit(node: IConstruct): void {
12 | const currentLogicalId = Stack.of(node).getLogicalId(node as CfnElement);
13 | // is there a map for this logicalId?
14 | if (!!this.idMap[currentLogicalId]) {
15 | // if we're on a L1 resource, try to do the override directly
16 | if ((node as CfnResource).overrideLogicalId) return (node as CfnResource).overrideLogicalId(this.idMap[currentLogicalId]);
17 |
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/chapters/testing/refactoring/src/OriginalStack.ts:
--------------------------------------------------------------------------------
1 | import { Bucket } from '@aws-cdk/aws-s3';
2 | import { Construct, Stack, StackProps } from '@aws-cdk/core';
3 |
4 | export class OriginalStack extends Stack {
5 | constructor(scope: Construct, id: string, props: StackProps) {
6 | super(scope, id, props);
7 |
8 | // The first time you run the unit test, have this bucket created here:
9 | new Bucket(this, 'Bucket', {});
10 | }
11 | }
--------------------------------------------------------------------------------
/chapters/testing/refactoring/src/RefactoredStack.ts:
--------------------------------------------------------------------------------
1 | import { Aspects, Construct, Stack, StackProps } from '@aws-cdk/core';
2 | import { IdMap, LogicalIdMapper } from './LogicalIdMapper';
3 | import { SomeConstruct } from './SomeConstruct';
4 |
5 |
6 | interface RefactoredStackProps extends StackProps {
7 | idMap?: IdMap;
8 | }
9 |
10 | export class RefactoredStack extends Stack {
11 | constructor(scope: Construct, id: string, props: RefactoredStackProps) {
12 | super(scope, id, props);
13 |
14 | new SomeConstruct(this, 'Thingy');
15 |
16 | // if an idMap was provided, add the aspect.
17 | if (props.idMap) {
18 | Aspects.of(this).add(new LogicalIdMapper(props.idMap));
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/chapters/testing/refactoring/src/SomeConstruct.ts:
--------------------------------------------------------------------------------
1 | import { Bucket } from '@aws-cdk/aws-s3';
2 | import { Construct } from '@aws-cdk/core';
3 |
4 | export class SomeConstruct extends Construct {
5 | constructor(scope: Construct, id: string) {
6 | super(scope, id);
7 | // this is the code, copy and pasted from its original usage directly in the stack above
8 | new Bucket(this, 'Bucket', {});
9 | }
10 | }
--------------------------------------------------------------------------------
/chapters/testing/refactoring/src/main.ts:
--------------------------------------------------------------------------------
1 | import { App } from '@aws-cdk/core';
2 | import { OriginalStack } from './OriginalStack';
3 |
4 |
5 | // for development, use account/region from cdk cli
6 | const devEnv = {
7 | account: process.env.CDK_DEFAULT_ACCOUNT,
8 | region: process.env.CDK_DEFAULT_REGION,
9 | };
10 |
11 | const app = new App();
12 |
13 | new OriginalStack(app, 'my-stack-dev', { env: devEnv });
14 | // new RefactoredStack(app, 'my-stack-dev', { env: devEnv, idMap: { ThingyBucket292460C0: 'Bucket83908E77' } });
15 |
16 | app.synth();
--------------------------------------------------------------------------------
/chapters/testing/refactoring/test/__snapshots__/main.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Snapshot 1`] = `
4 | Object {
5 | "Resources": Object {
6 | "Bucket83908E77": Object {
7 | "DeletionPolicy": "Retain",
8 | "Type": "AWS::S3::Bucket",
9 | "UpdateReplacePolicy": "Retain",
10 | },
11 | },
12 | }
13 | `;
14 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/test/main.test.ts:
--------------------------------------------------------------------------------
1 | import { Template } from '@aws-cdk/assertions';
2 | import { App } from '@aws-cdk/core';
3 | import { OriginalStack } from '../src/OriginalStack';
4 |
5 | test('Snapshot', () => {
6 | /**
7 | * This is a simple snapshot test using Jest. If you run this test before your refactoring, it'll take a snapshot
8 | * of the LogicalId.
9 | * Refactor your code and then re-run this test. It will fail as the LogicalIds have changed.
10 | *
11 | * Then, uncomment out the idMap property and verify the correct values are provided. The failed test will show
12 | * you the new LogicalId (what it received) and the original LogicalId (the snapshot).
13 | * In the example code, the new LogicalId of 'ThingyBucket7D8CBF87' will be rewritten to the value it
14 | * was before the refactor, 'Bucket83908E77', satisfying the test and ensuring your resource won't be recreated.
15 | */
16 |
17 | const app = new App();
18 | const stack = new OriginalStack(app, 'test', {});
19 | // const stack = new RefactoredStack(app, 'test', { idMap: { ThingyBucket7D8CBF87: 'Bucket83908E77' } });
20 | expect(Template.fromStack(stack)).toMatchSnapshot();
21 | });
--------------------------------------------------------------------------------
/chapters/testing/refactoring/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/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 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------
/chapters/testing/refactoring/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": "src",
4 | "outDir": "lib",
5 | "alwaysStrict": true,
6 | "declaration": true,
7 | "experimentalDecorators": true,
8 | "inlineSourceMap": true,
9 | "inlineSources": true,
10 | "lib": [
11 | "es2018"
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": "ES2018"
27 | },
28 | "include": [
29 | "src/**/*.ts"
30 | ],
31 | "exclude": [
32 | "cdk.out"
33 | ],
34 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
35 | }
36 |
--------------------------------------------------------------------------------