diff --git a/examples/pnpm-lock.yaml b/examples/pnpm-lock.yaml index 67bc4f2..2e551b8 100644 --- a/examples/pnpm-lock.yaml +++ b/examples/pnpm-lock.yaml @@ -33,7 +33,7 @@ dependencies: devDependencies: '@stutzlab/eslint-config': specifier: ^3.1.1 - version: 3.1.1(@typescript-eslint/eslint-plugin@7.18.0)(@typescript-eslint/parser@7.18.0)(eslint-config-airbnb-base@15.0.0)(eslint-config-airbnb-typescript@18.0.0)(eslint-config-prettier@9.1.0)(eslint-import-resolver-typescript@3.6.3)(eslint-plugin-fp@2.3.0)(eslint-plugin-import@2.31.0)(eslint-plugin-jest@28.8.3)(eslint-plugin-prettier@5.2.1)(eslint-plugin-promise@6.6.0)(eslint@8.57.0)(prettier@3.3.3) + version: 3.1.1(@typescript-eslint/eslint-plugin@7.18.0)(@typescript-eslint/parser@7.18.0)(eslint-config-airbnb-base@15.0.0)(eslint-config-airbnb-typescript@18.0.0)(eslint-config-prettier@9.1.0)(eslint-import-resolver-typescript@3.6.3)(eslint-plugin-fp@2.3.0)(eslint-plugin-import@2.31.0)(eslint-plugin-jest@28.9.0)(eslint-plugin-prettier@5.2.1)(eslint-plugin-promise@6.6.0)(eslint@8.57.0)(prettier@3.3.3) '@tsconfig/node20': specifier: ^20.1.4 version: 20.1.4 @@ -1150,13 +1150,23 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@eslint-community/eslint-utils@4.4.1(eslint@8.57.0): + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + /@eslint-community/regexpp@4.10.0: resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint-community/regexpp@4.11.1: - resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + /@eslint-community/regexpp@4.12.1: + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true @@ -1503,22 +1513,22 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@jsep-plugin/regex@1.0.3(jsep@1.3.9): - resolution: {integrity: sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==} + /@jsep-plugin/regex@1.0.4(jsep@1.4.0): + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} engines: {node: '>= 10.16.0'} peerDependencies: jsep: ^0.4.0||^1.0.0 dependencies: - jsep: 1.3.9 + jsep: 1.4.0 dev: false - /@jsep-plugin/ternary@1.1.3(jsep@1.3.9): - resolution: {integrity: sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==} + /@jsep-plugin/ternary@1.1.4(jsep@1.4.0): + resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==} engines: {node: '>= 10.16.0'} peerDependencies: jsep: ^0.4.0||^1.0.0 dependencies: - jsep: 1.3.9 + jsep: 1.4.0 dev: false /@nodelib/fs.scandir@2.1.5: @@ -2041,7 +2051,7 @@ packages: fast-memoize: 2.5.2 immer: 9.0.21 lodash: 4.17.21 - tslib: 2.8.0 + tslib: 2.8.1 urijs: 1.19.11 dev: false @@ -2089,7 +2099,7 @@ packages: lodash: 4.17.21 pony-cause: 1.1.1 stacktracey: 2.1.8 - tslib: 2.8.0 + tslib: 2.8.1 yargs: 17.7.2 transitivePeerDependencies: - encoding @@ -2119,7 +2129,7 @@ packages: nimma: 0.2.2 pony-cause: 1.1.1 simple-eval: 1.0.0 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2131,7 +2141,7 @@ packages: '@stoplight/json': 3.21.7 '@stoplight/spectral-core': 1.19.1 '@types/json-schema': 7.0.15 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2152,7 +2162,7 @@ packages: node-sarif-builder: 2.0.3 strip-ansi: 6.0.1 text-table: 0.2.0 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2171,7 +2181,7 @@ packages: ajv-errors: 3.0.0(ajv@8.17.1) ajv-formats: 2.1.1(ajv@8.17.1) lodash: 4.17.21 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2183,7 +2193,7 @@ packages: '@stoplight/json': 3.21.7 '@stoplight/types': 14.1.1 '@stoplight/yaml': 4.3.0 - tslib: 2.8.0 + tslib: 2.8.1 dev: false /@stoplight/spectral-ref-resolver@1.0.4: @@ -2194,7 +2204,7 @@ packages: '@stoplight/json-ref-resolver': 3.1.6 '@stoplight/spectral-runtime': 1.1.2 dependency-graph: 0.11.0 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2217,7 +2227,7 @@ packages: '@types/node': 20.16.2 pony-cause: 1.1.1 rollup: 2.79.2 - tslib: 2.8.0 + tslib: 2.8.1 validate-npm-package-name: 3.0.0 transitivePeerDependencies: - encoding @@ -2239,7 +2249,7 @@ packages: ast-types: 0.14.2 astring: 1.9.0 reserved: 0.1.2 - tslib: 2.8.0 + tslib: 2.8.1 validate-npm-package-name: 3.0.0 transitivePeerDependencies: - encoding @@ -2263,7 +2273,7 @@ packages: json-schema-traverse: 1.0.0 leven: 3.1.0 lodash: 4.17.21 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2278,7 +2288,7 @@ packages: abort-controller: 3.0.0 lodash: 4.17.21 node-fetch: 2.7.0 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - encoding dev: false @@ -2330,7 +2340,7 @@ packages: '@stoplight/ordered-object-literal': 1.0.5 '@stoplight/types': 13.20.0 '@stoplight/yaml-ast-parser': 0.0.48 - tslib: 2.8.0 + tslib: 2.8.1 dev: false /@stoplight/yaml@4.3.0: @@ -2340,10 +2350,10 @@ packages: '@stoplight/ordered-object-literal': 1.0.5 '@stoplight/types': 14.1.1 '@stoplight/yaml-ast-parser': 0.0.50 - tslib: 2.8.0 + tslib: 2.8.1 dev: false - /@stutzlab/eslint-config@3.1.1(@typescript-eslint/eslint-plugin@7.18.0)(@typescript-eslint/parser@7.18.0)(eslint-config-airbnb-base@15.0.0)(eslint-config-airbnb-typescript@18.0.0)(eslint-config-prettier@9.1.0)(eslint-import-resolver-typescript@3.6.3)(eslint-plugin-fp@2.3.0)(eslint-plugin-import@2.31.0)(eslint-plugin-jest@28.8.3)(eslint-plugin-prettier@5.2.1)(eslint-plugin-promise@6.6.0)(eslint@8.57.0)(prettier@3.3.3): + /@stutzlab/eslint-config@3.1.1(@typescript-eslint/eslint-plugin@7.18.0)(@typescript-eslint/parser@7.18.0)(eslint-config-airbnb-base@15.0.0)(eslint-config-airbnb-typescript@18.0.0)(eslint-config-prettier@9.1.0)(eslint-import-resolver-typescript@3.6.3)(eslint-plugin-fp@2.3.0)(eslint-plugin-import@2.31.0)(eslint-plugin-jest@28.9.0)(eslint-plugin-prettier@5.2.1)(eslint-plugin-promise@6.6.0)(eslint@8.57.0)(prettier@3.3.3): resolution: {integrity: sha512-XmwQJE6UkSBmr2ZFGOprxVO/8Yioxu0vTzoLDm/0dB9E2RwGp1r6N4cyRT0MI8PCyYSUOz2kBH1aL5qpJkfFwQ==} peerDependencies: '@typescript-eslint/eslint-plugin': ^7.15.0 @@ -2369,7 +2379,7 @@ packages: eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0)(eslint-plugin-import@2.31.0)(eslint@8.57.0) eslint-plugin-fp: 2.3.0(eslint@8.57.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) - eslint-plugin-jest: 28.8.3(@typescript-eslint/eslint-plugin@7.18.0)(eslint@8.57.0)(jest@29.7.0)(typescript@5.5.4) + eslint-plugin-jest: 28.9.0(@typescript-eslint/eslint-plugin@7.18.0)(eslint@8.57.0)(jest@29.7.0)(typescript@5.5.4) eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.3) eslint-plugin-promise: 6.6.0(eslint@8.57.0) prettier: 3.3.3 @@ -2537,7 +2547,7 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.11.1 + '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) @@ -2547,7 +2557,7 @@ packages: graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.4.0(typescript@5.5.4) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -2582,12 +2592,12 @@ packages: '@typescript-eslint/visitor-keys': 7.18.0 dev: true - /@typescript-eslint/scope-manager@8.11.0: - resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} + /@typescript-eslint/scope-manager@8.13.0: + resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/visitor-keys': 8.11.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 dev: true /@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4): @@ -2604,7 +2614,7 @@ packages: '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) debug: 4.3.7 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.4.0(typescript@5.5.4) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -2615,8 +2625,8 @@ packages: engines: {node: ^18.18.0 || >=20.0.0} dev: true - /@typescript-eslint/types@8.11.0: - resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} + /@typescript-eslint/types@8.13.0: + resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true @@ -2636,14 +2646,14 @@ packages: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.4.0(typescript@5.5.4) typescript: 5.5.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@8.11.0(typescript@5.5.4): - resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==} + /@typescript-eslint/typescript-estree@8.13.0(typescript@5.5.4): + resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2651,14 +2661,14 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/visitor-keys': 8.11.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.4.0(typescript@5.5.4) typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -2670,7 +2680,7 @@ packages: peerDependencies: eslint: ^8.56.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.0) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) @@ -2680,16 +2690,16 @@ packages: - typescript dev: true - /@typescript-eslint/utils@8.11.0(eslint@8.57.0)(typescript@5.5.4): - resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==} + /@typescript-eslint/utils@8.13.0(eslint@8.57.0)(typescript@5.5.4): + resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 8.11.0 - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.5.4) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.0) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.5.4) eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -2704,11 +2714,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@8.11.0: - resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} + /@typescript-eslint/visitor-keys@8.13.0: + resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 dev: true @@ -2952,7 +2962,7 @@ packages: resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} engines: {node: '>=4'} dependencies: - tslib: 2.8.0 + tslib: 2.8.1 dev: false /astring@1.9.0: @@ -4112,8 +4122,8 @@ packages: - supports-color dev: true - /eslint-plugin-jest@28.8.3(@typescript-eslint/eslint-plugin@7.18.0)(eslint@8.57.0)(jest@29.7.0)(typescript@5.5.4): - resolution: {integrity: sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==} + /eslint-plugin-jest@28.9.0(@typescript-eslint/eslint-plugin@7.18.0)(eslint@8.57.0)(jest@29.7.0)(typescript@5.5.4): + resolution: {integrity: sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ==} engines: {node: ^16.10.0 || ^18.12.0 || >=20.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -4126,7 +4136,7 @@ packages: optional: true dependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0)(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/utils': 8.11.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.13.0(eslint@8.57.0)(typescript@5.5.4) eslint: 8.57.0 jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2) transitivePeerDependencies: @@ -5692,8 +5702,8 @@ packages: dependencies: argparse: 2.0.1 - /jsep@1.3.9: - resolution: {integrity: sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==} + /jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} engines: {node: '>= 10.16.0'} dev: false @@ -6039,10 +6049,10 @@ packages: resolution: {integrity: sha512-V52MLl7BU+tH2Np9tDrIXK8bql3MVUadnMIl/0/oZSGC9keuro0O9UUv9QKp0aMvtN8HRew4G7byY7H4eWsxaQ==} engines: {node: ^12.20 || >=14.13} dependencies: - '@jsep-plugin/regex': 1.0.3(jsep@1.3.9) - '@jsep-plugin/ternary': 1.1.3(jsep@1.3.9) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + '@jsep-plugin/ternary': 1.1.4(jsep@1.4.0) astring: 1.9.0 - jsep: 1.3.9 + jsep: 1.4.0 optionalDependencies: jsonpath-plus: 6.0.1 lodash.topath: 4.5.2 @@ -6741,7 +6751,7 @@ packages: resolution: {integrity: sha512-kpKJR+bqTscgC0xuAl2xHN6bB12lHjC2DCUfqjAx19bQyO3R2EVLOurm3H9AUltv/uFVcSCVNc6faegR+8NYLw==} engines: {node: '>=12'} dependencies: - jsep: 1.3.9 + jsep: 1.4.0 dev: false /sinon@16.1.3: @@ -6969,7 +6979,7 @@ packages: engines: {node: ^14.18.0 || >=16.0.0} dependencies: '@pkgr/core': 0.1.1 - tslib: 2.8.0 + tslib: 2.8.1 dev: true /tapable@2.2.1: @@ -7040,8 +7050,8 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /ts-api-utils@1.3.0(typescript@5.5.4): - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + /ts-api-utils@1.4.0(typescript@5.5.4): + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -7101,8 +7111,8 @@ packages: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} dev: false - /tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + /tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -7472,7 +7482,7 @@ packages: dev: false file:../lib/dist/cdk-practical-constructs-0.0.1.tgz(@asteasolutions/zod-to-openapi@7.0.0)(aws-cdk-lib@2.155.0)(zod@3.23.8): - resolution: {integrity: sha512-3yWg1yl6MHO+fsqQuDq4tkrCbDZzn0nN+1RwI99WoqgoGz2ARawXiPQ6a3dsX8rhq+q3ySujmlu5mYAOLrRVRw==, tarball: file:../lib/dist/cdk-practical-constructs-0.0.1.tgz} + resolution: {integrity: sha512-5H/Y7HRg2tf0OEC6ec5v9o4shBUJOg2YdekWB2qC0Du/Rwv9cL/iH9SYJCevv9sv2wqZ+Pg/skYEHczgUenm8Q==, tarball: file:../lib/dist/cdk-practical-constructs-0.0.1.tgz} id: file:../lib/dist/cdk-practical-constructs-0.0.1.tgz name: cdk-practical-constructs version: 0.0.1 diff --git a/examples/src/cdk/configs.ts b/examples/src/cdk/configs.ts index 3a0c02b..c1e0ca0 100644 --- a/examples/src/cdk/configs.ts +++ b/examples/src/cdk/configs.ts @@ -6,7 +6,6 @@ import { TestConfig } from './types/TestConfig'; export const testStageConfigs: StagesConfig = { default: { lambda: { - allowAllOutbound: true, logGroupRetention: RetentionDays.ONE_WEEK, }, }, diff --git a/examples/src/lambda/cdk.ts b/examples/src/lambda/cdk.ts index c0b3191..018d87e 100644 --- a/examples/src/lambda/cdk.ts +++ b/examples/src/lambda/cdk.ts @@ -11,6 +11,22 @@ import { import { Construct } from 'constructs'; export const addLambdaGetTest = (scope: Construct): void => { + const vpc = vpcFromConfig(scope, { + // get these from your actual AWS account configuration + vpcId: 'aaa', + availabilityZones: ['a'], + privateSubnetIds: ['a'], + privateSubnetRouteTableIds: ['a'], + }); + const customSG = new SecurityGroup(scope, 'customsg', { + vpc, + description: 'custom sg', + allowAllOutbound: false, + }); + customSG.addIngressRule(Peer.ipv4('9.9.9.9/32'), Port.allTraffic(), 'allow ingress'); + customSG.addEgressRule(Peer.ipv4('8.8.8.8/32'), Port.allTraffic(), 'allow egress'); + customSG.addEgressRule(Peer.ipv4('1.2.3.4/32'), Port.tcp(8888), 'Sample egress rule'); + const lambdaConfig: BaseNodeJsProps = { stage: 'dev', network: { @@ -26,29 +42,14 @@ export const addLambdaGetTest = (scope: Construct): void => { }, baseCodePath: 'src/lambda', logGroupRetention: RetentionDays.FIVE_DAYS, + securityGroups: [customSG], }; - if (!lambdaConfig.network) throw new Error('network should be defined'); - const vpc = vpcFromConfig(scope, lambdaConfig.network); - - const customSG = new SecurityGroup(scope, 'customsg', { - vpc, - description: 'custom sg', - allowAllOutbound: false, - }); - customSG.addIngressRule(Peer.ipv4('9.9.9.9/32'), Port.allTraffic(), 'allow ingress'); - customSG.addEgressRule(Peer.ipv4('8.8.8.8/32'), Port.allTraffic(), 'allow egress'); - lambdaConfig.securityGroups = [customSG]; lambdaConfig.logGroupSubscriberLambdaArn = { type: LogGroupSubscriberLambdaArnType.Arn, value: 'arn:aws:lambda:eu-west-1:012345678:function:tstLogging', }; const func = new BaseNodeJsFunction(scope, 'getTest', lambdaConfig); - if (!func.defaultSecurityGroup) throw new Error('defaultSecurityGroup should be defined'); - func.defaultSecurityGroup.addEgressRule( - Peer.ipv4('1.2.3.4/32'), - Port.tcp(8888), - 'Sample egress rule', - ); + if (!func.defaultLogGroup) throw new Error('defaultLogGroup should be created by default'); }; diff --git a/lib/package.json b/lib/package.json index c927cd8..8e8ce20 100644 --- a/lib/package.json +++ b/lib/package.json @@ -68,10 +68,13 @@ "access": "public", "registry": "https://registry.npmjs.org" }, + "//pnpm.overrides.braces": "braces is used by @stoplight/spectral-cli - Open issue: https://github.com/stoplightio/spectral/issues/2639. We will remove this override once the issue is fixed.", + "//pnpm.overrides.jsonpath-plus": "jsonpath-plus is used by @stoplight/spectral-cli and the safe version is not used yet by this library", "pnpm": { "overrides": { "braces@<3.0.3": ">=3.0.3", - "rollup@<3.29.5": ">=3.29.5" + "rollup@<3.29.5": ">=3.29.5", + "jsonpath-plus": ">=10" } } } \ No newline at end of file diff --git a/lib/pnpm-lock.yaml b/lib/pnpm-lock.yaml index 20db0cd..34bf2cc 100644 --- a/lib/pnpm-lock.yaml +++ b/lib/pnpm-lock.yaml @@ -7,6 +7,7 @@ settings: overrides: braces@<3.0.3: '>=3.0.3' rollup@<3.29.5: '>=3.29.5' + jsonpath-plus: '>=10' dependencies: '@apiture/openapi-down-convert': @@ -1624,6 +1625,15 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /@jsep-plugin/assignment@1.3.0(jsep@1.4.0): + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + dependencies: + jsep: 1.4.0 + dev: false + /@jsep-plugin/regex@1.0.3(jsep@1.3.8): resolution: {integrity: sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==} engines: {node: '>= 10.16.0'} @@ -1633,6 +1643,15 @@ packages: jsep: 1.3.8 dev: false + /@jsep-plugin/regex@1.0.3(jsep@1.4.0): + resolution: {integrity: sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + dependencies: + jsep: 1.4.0 + dev: false + /@jsep-plugin/ternary@1.1.3(jsep@1.3.8): resolution: {integrity: sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==} engines: {node: '>= 10.16.0'} @@ -2358,7 +2377,7 @@ packages: ajv-errors: 3.0.0(ajv@8.12.0) ajv-formats: 2.1.1(ajv@8.12.0) es-aggregate-error: 1.0.11 - jsonpath-plus: 7.1.0 + jsonpath-plus: 10.1.0 lodash: 4.17.21 lodash.topath: 4.5.2 minimatch: 3.1.2 @@ -5658,6 +5677,11 @@ packages: engines: {node: '>= 10.16.0'} dev: false + /jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + dev: false + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -5713,16 +5737,14 @@ packages: graceful-fs: 4.2.11 dev: false - /jsonpath-plus@6.0.1: - resolution: {integrity: sha512-EvGovdvau6FyLexFH2OeXfIITlgIbgZoAZe3usiySeaIDm5QS+A10DKNpaPBBqqRSZr2HN6HVNXxtwUAr2apEw==} - engines: {node: '>=10.0.0'} - requiresBuild: true - dev: false - optional: true - - /jsonpath-plus@7.1.0: - resolution: {integrity: sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==} - engines: {node: '>=12.0.0'} + /jsonpath-plus@10.1.0: + resolution: {integrity: sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.3(jsep@1.4.0) + jsep: 1.4.0 dev: false /jsonpointer@5.0.1: @@ -5993,7 +6015,7 @@ packages: astring: 1.8.6 jsep: 1.3.8 optionalDependencies: - jsonpath-plus: 6.0.1 + jsonpath-plus: 10.1.0 lodash.topath: 4.5.2 dev: false diff --git a/lib/src/config/configs.test.ts b/lib/src/config/configs.test.ts index 9e863fc..f503a6f 100644 --- a/lib/src/config/configs.test.ts +++ b/lib/src/config/configs.test.ts @@ -1,6 +1,5 @@ /* eslint-disable camelcase */ import { RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { Peer, Port } from 'aws-cdk-lib/aws-ec2'; import { LambdaConfig } from '..'; @@ -13,7 +12,6 @@ type TestConfig = StageConfig & { const testStageConfigs: StagesConfig = { default: { lambda: { - allowOutboundTo: [{ peer: Peer.anyIpv4(), port: Port.allTraffic() }], logGroupRetention: RetentionDays.ONE_WEEK, }, }, @@ -35,25 +33,21 @@ const testStageConfigs: StagesConfig = { describe('configs', () => { it('resolve config with dev overrides', async () => { const stageConfig = resolveStageConfig('dev', testStageConfigs); - expect(stageConfig.lambda.allowOutboundTo?.length).toBe(1); expect(stageConfig.lambda.logGroupRetention).toBe(RetentionDays.ONE_DAY); }); it('resolve stage "dev-pr-123" with same contents as stage "dev"', async () => { const stageConfig = resolveStageConfig('dev-pr-123', testStageConfigs); - expect(stageConfig.lambda.allowOutboundTo?.length).toBe(1); expect(stageConfig.lambda.logGroupRetention).toBe(RetentionDays.ONE_DAY); }); it('resolve prd config with defaults', async () => { const stageConfig = resolveStageConfig('tst', testStageConfigs); - expect(stageConfig.lambda.allowOutboundTo?.length).toBe(1); expect(stageConfig.lambda.logGroupRetention).toBe(RetentionDays.ONE_WEEK); }); it('resolve acc config with defaults', async () => { const stageConfig = resolveStageConfig('prd', testStageConfigs); - expect(stageConfig.lambda.allowOutboundTo?.length).toBe(1); expect(stageConfig.lambda.logGroupRetention).toBe(RetentionDays.SIX_MONTHS); }); }); diff --git a/lib/src/lambda/lambda-base.test.ts b/lib/src/lambda/lambda-base.test.ts index d863c0d..fee41ae 100644 --- a/lib/src/lambda/lambda-base.test.ts +++ b/lib/src/lambda/lambda-base.test.ts @@ -16,6 +16,22 @@ describe('lambda-base', () => { const app = new App(); const stack = new Stack(app); + const vpc = vpcFromConfig(stack, { + vpcId: 'aaa', + availabilityZones: ['a'], + privateSubnetIds: ['a'], + privateSubnetRouteTableIds: ['a'], + }); + + const customSG = new SecurityGroup(stack, 'customsg', { + vpc, + description: 'custom sg', + allowAllOutbound: false, + }); + customSG.addIngressRule(Peer.ipv4('9.9.9.9/32'), Port.allTraffic(), 'allow ingress'); + customSG.addEgressRule(Peer.ipv4('8.8.8.8/32'), Port.allTraffic(), 'allow egress'); + customSG.addEgressRule(Peer.ipv4('1.2.3.4/32'), Port.tcp(8888), 'Sample egress rule'); + const lambdaConfig: BaseNodeJsProps = { stage: 'dev', network: { @@ -32,33 +48,18 @@ describe('lambda-base', () => { minCapacity: 3, }, logGroupRetention: RetentionDays.FIVE_DAYS, + securityGroups: [customSG], }; if (!lambdaConfig.network) throw new Error('lambdaConfig.network should be defined'); - const vpc = vpcFromConfig(stack, lambdaConfig.network); if (!vpc) throw new Error('vpc should be defined'); - const customSG = new SecurityGroup(stack, 'customsg', { - vpc, - description: 'custom sg', - allowAllOutbound: false, - }); - customSG.addIngressRule(Peer.ipv4('9.9.9.9/32'), Port.allTraffic(), 'allow ingress'); - customSG.addEgressRule(Peer.ipv4('8.8.8.8/32'), Port.allTraffic(), 'allow egress'); - lambdaConfig.securityGroups = [customSG]; lambdaConfig.logGroupSubscriberLambdaArn = { type: LogGroupSubscriberLambdaArnType.Arn, value: 'arn:aws:lambda:eu-west-1:012345678:function:tstLogging', }; const func = new BaseNodeJsFunction(stack, 'test-lambda', lambdaConfig); - if (!func.defaultSecurityGroup) throw new Error('defaultSecurityGroup should be defined'); - func.defaultSecurityGroup.addEgressRule( - Peer.ipv4('1.2.3.4/32'), - Port.tcp(8888), - 'Sample egress rule', - ); - expect(func).toBeDefined(); expect(func.nodeJsFunction.runtime).toBe(Runtime.NODEJS_20_X); expect(func.nodeJsFunction.node.id).toBe('test-lambda'); @@ -97,15 +98,13 @@ describe('lambda-base', () => { RetentionInDays: 5, }); - template.hasResourceProperties('AWS::EC2::SecurityGroup', { - GroupDescription: 'Default security group for Lambda test-lambda', - SecurityGroupEgress: [{ CidrIp: '1.2.3.4/32', FromPort: 8888, IpProtocol: 'tcp' }], - }); - template.hasResourceProperties('AWS::EC2::SecurityGroup', { GroupDescription: 'custom sg', SecurityGroupIngress: [{ CidrIp: '9.9.9.9/32' }], - SecurityGroupEgress: [{ CidrIp: '8.8.8.8/32' }], + SecurityGroupEgress: [ + { CidrIp: '8.8.8.8/32' }, + { CidrIp: '1.2.3.4/32', FromPort: 8888, IpProtocol: 'tcp' }, + ], }); template.hasResourceProperties('AWS::Logs::SubscriptionFilter', { @@ -178,7 +177,7 @@ describe('lambda-base', () => { stage: 'dev', eventType: EventType.Http, baseCodePath: 'src/lambda/__tests__', - allowOutboundTo: [{ peer: Peer.ipv4('0.0.0.0/0'), port: Port.tcp(443) }], + // allowOutboundTo: [{ peer: Peer.ipv4('0.0.0.0/0'), port: Port.tcp(443) }], }); }; expect(f).toThrow(); @@ -270,11 +269,6 @@ describe('lambda-base', () => { }, }); - template.hasResourceProperties('AWS::EC2::SecurityGroup', { - GroupDescription: 'Default security group for Lambda test-lambda', - SecurityGroupEgress: [{ CidrIp: '255.255.255.255/32', Description: 'Disallow all traffic' }], - }); - template.hasResource('AWS::Lambda::Version', {}); template.hasResourceProperties('AWS::Lambda::Alias', { diff --git a/lib/src/lambda/lambda-base.ts b/lib/src/lambda/lambda-base.ts index fc7a8a3..4f0bdc1 100644 --- a/lib/src/lambda/lambda-base.ts +++ b/lib/src/lambda/lambda-base.ts @@ -2,7 +2,7 @@ /* eslint-disable no-console */ import { NodejsFunction, NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs'; import { Construct } from 'constructs'; -import { ISecurityGroup, SecurityGroup, SubnetType } from 'aws-cdk-lib/aws-ec2'; +import { SubnetType } from 'aws-cdk-lib/aws-ec2'; import { LambdaDestination } from 'aws-cdk-lib/aws-logs-destinations'; import { Runtime, Function, Alias, IAlias } from 'aws-cdk-lib/aws-lambda'; import { FilterPattern, LogGroup, RetentionDays, SubscriptionFilter } from 'aws-cdk-lib/aws-logs'; @@ -25,7 +25,6 @@ import { BaseNodeJsProps, LambdaConfig, LogGroupSubscriberLambdaArnType } from ' /** * This construct is based on AWS NodeJsFunction and adds the following capabilities: - * - creates a default security group. See property 'defaultSecurityGroup' of this construct * - creates an alias called "live" pointing to the latest lambda version and replaced versions are deleted automatically. See property 'liveAlias' of this construct * - typed configuration props for common usage scenarios * - autoscaling of provisioned concurrent invocations (so you lower cold starts). You can also use automatic scheduling to tweak min/max depending on a cron expression. See props.provisionedConcurrentExecutions @@ -39,8 +38,6 @@ import { BaseNodeJsProps, LambdaConfig, LogGroupSubscriberLambdaArnType } from ' export class BaseNodeJsFunction extends Construct { public readonly nodeJsFunction: NodejsFunction; - public readonly defaultSecurityGroup?: ISecurityGroup; - public readonly defaultLogGroup?: LogGroup; public readonly liveAlias?: IAlias; @@ -54,9 +51,6 @@ export class BaseNodeJsFunction extends Construct { const { environment } = setupEnvironment(propsWithDefaults); - const { defaultSG, securityGroups } = addSecurityGroups(this, propsWithDefaults); - this.defaultSecurityGroup = defaultSG; - // Don't use logRetention from NodeJsFunction because it's a deprecated attribute. // We are creating a log group with retention policies in this construct instead // that uses native log retention mechanisms @@ -73,15 +67,8 @@ export class BaseNodeJsFunction extends Construct { ...propsWithDefaults, ...defaultLogGroupProp, environment, - securityGroups, - // eslint-disable-next-line no-undefined - allowAllOutbound: undefined, }; - // this is managed by our security group, so don't send this to NodeJsFunction - // eslint-disable-next-line fp/no-delete - // delete nodeJsProps.allowAllOutbound; - const nodeJsFunc = new NodejsFunction(this, id, nodeJsProps); this.nodeJsFunction = nodeJsFunc; @@ -305,48 +292,6 @@ const addDefaultLogGroup = (scope: Construct, props: BaseNodeJsProps): LogGroup }); }; -/** - * Create default security group and add to existing SGs from props if it exists - */ -const addSecurityGroups = ( - scope: Construct, - props: LambdaConfig, -): { - defaultSG?: ISecurityGroup; - securityGroups?: ISecurityGroup[]; -} => { - if (!props.vpc) { - if (props.allowOutboundTo) { - throw new Error(`'allowOutboundTo' can only be used if vpc or network is defined`); - } - return {}; - } - - const securityGroups: ISecurityGroup[] = []; - if (props.securityGroups) { - // eslint-disable-next-line fp/no-mutating-methods - securityGroups.push(...props.securityGroups); - } - - // Create a default security group and expose via class variable - const defaultSG = new SecurityGroup(scope, `sg-default-${scope.node.id}`, { - vpc: props.vpc, - description: `Default security group for Lambda ${scope.node.id}`, - allowAllOutbound: - (typeof props.allowAllOutbound !== 'undefined' && props.allowAllOutbound) ?? - props.allowAllOutbound, - }); - if (props.allowOutboundTo) { - props.allowOutboundTo.forEach((ato) => { - defaultSG.addEgressRule(ato.peer, ato.port, `Allow connection to ${ato.peer}:${ato.port}`); - }); - } - // eslint-disable-next-line fp/no-mutating-methods - securityGroups.push(defaultSG); - - return { defaultSG, securityGroups }; -}; - const setupEnvironment = (props: BaseNodeJsProps): { environment: Record } => { // add stage to environment let environment: Record = { diff --git a/lib/src/lambda/types.ts b/lib/src/lambda/types.ts index 198f751..e7065f0 100644 --- a/lib/src/lambda/types.ts +++ b/lib/src/lambda/types.ts @@ -1,5 +1,4 @@ import { Schedule } from 'aws-cdk-lib/aws-applicationautoscaling'; -import { IPeer, ISecurityGroup, Port } from 'aws-cdk-lib/aws-ec2'; import { NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; import { RemovalPolicy } from 'aws-cdk-lib/core'; @@ -25,21 +24,6 @@ export type LambdaConfig = Omit< NodejsFunctionProps, 'logGroupRetentionRole' | 'logRetentionRetryOptions' | 'logRetention' | 'allowAllOutbound' > & { - /** - * Allow connections to any outbound host in any port - * @default false - */ - allowAllOutbound?: boolean; - /** - * Egress rules allowing connections from this Lambda to other services - * @default none - */ - allowOutboundTo?: { peer: IPeer; port: Port }[]; - /** - * Add these security groups to the Lambda function - * @default none - */ - securityGroups?: ISecurityGroup[]; /** * Define an event type that will be used for naming the path of the handler. * Ignored if "entry" is used diff --git a/lib/src/wso2/types.ts b/lib/src/wso2/types.ts index 715857f..dc77808 100644 --- a/lib/src/wso2/types.ts +++ b/lib/src/wso2/types.ts @@ -11,7 +11,6 @@ import { LambdaConfig } from '../lambda/types'; */ export type Wso2LambdaConfig = Pick< LambdaConfig, - | 'allowOutboundTo' | 'securityGroups' | 'extraCaPubCert' | 'network' diff --git a/lib/src/wso2/utils-cdk.ts b/lib/src/wso2/utils-cdk.ts index 25c85a5..4fc0990 100644 --- a/lib/src/wso2/utils-cdk.ts +++ b/lib/src/wso2/utils-cdk.ts @@ -7,9 +7,11 @@ import { Runtime } from 'aws-cdk-lib/aws-lambda'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; import { Provider } from 'aws-cdk-lib/custom-resources'; import { Construct } from 'constructs'; +import { IVpc, SecurityGroup } from 'aws-cdk-lib/aws-ec2'; import { BaseNodeJsFunction } from '../lambda/lambda-base'; import { EventType } from '../lambda/types'; +import { vpcFromConfig } from '../utils'; import { Wso2BaseProperties } from './types'; @@ -24,6 +26,9 @@ export const addLambdaAndProviderForWso2Operations = (args: { const { accountId, region } = new ScopedAws(args.scope); + // never use network configuration, only explicit VPC from previous step + const { network, ...customResourceConfig } = args.props.customResourceConfig ?? {}; + // resolve the entry file from workspace (.ts file), or // from the dist dir (.js file) when being used as a lib let wso2LambdaEntry = `${args.baseDir}/handler/index.ts`; @@ -31,9 +36,34 @@ export const addLambdaAndProviderForWso2Operations = (args: { wso2LambdaEntry = `${args.baseDir}/handler/index.js`; } + // vpc is undefined if no network is defined + let vpc: IVpc | undefined; + + const securityGroups = []; + + // Create security group for custom resource if VPC is defined and no security group is defined + if (args.props.customResourceConfig?.network) { + vpc = vpcFromConfig(args.scope, args.props.customResourceConfig.network); + + if ( + !customResourceConfig?.securityGroups || + customResourceConfig?.securityGroups.length === 0 + ) { + // create default security group for the lambda function + const securityGroup = new SecurityGroup(args.scope, `sg-cr-${args.scope.node.id}`, { + vpc, + description: `Security group for WSO2 CustomResource ${args.scope.node.id}`, + allowAllOutbound: true, + }); + securityGroups.push(securityGroup); + } + } + // lambda function used for invoking WSO2 APIs during CFN operations const customResourceFunction = new BaseNodeJsFunction(args.scope, `${args.id}-custom-lambda`, { - ...args.props.customResourceConfig, + ...customResourceConfig, + vpc, + securityGroups, stage: 'wso2-custom-lambda', timeout: Duration.minutes(10), memorySize: 256, @@ -50,8 +80,6 @@ export const addLambdaAndProviderForWso2Operations = (args: { }), ], logGroupRetention, - // allow all outbound by default - allowAllOutbound: typeof args.props.customResourceConfig?.network !== 'undefined', }); if (args.props.customResourceConfig?.logGroupRemovalPolicy) {