From 90a29e615d84985900a3d45a1aef33cb03b46739 Mon Sep 17 00:00:00 2001 From: hxtree Date: Sat, 14 Oct 2023 20:37:07 +0000 Subject: [PATCH] feat: add lambda layer for chromium Signed-off-by: hxtree --- .../rush/browser-approved-packages.json | 4 + common/config/rush/pnpm-lock.yaml | 458 ++++++++++++++---- common/config/rush/repo-state.json | 2 +- .../src/microservice/microservice.ts | 27 ++ platform/constructs/src/nestjs/nestjs.ts | 41 +- platform/lambda-layers/chrome-aws-lambda | 1 + .../stacks/lambda-layer-stack.ts | 40 +- rush.json | 7 +- services/html-to-pdf/bin/app.ts | 2 +- services/html-to-pdf/package.json | 15 +- .../src/module/pdf/pdf.controller.ts | 23 +- .../src/module/pdf/pdf.e2e-spec.ts | 15 +- .../html-to-pdf/src/module/pdf/pdf.service.ts | 22 +- .../src/module/pdf/url-to-data.dto.ts | 10 + .../html-to-pdf/stacks/html-to-pdf-stack.ts | 20 - services/html-to-pdf/stacks/main-stack.ts | 42 ++ 16 files changed, 548 insertions(+), 181 deletions(-) create mode 160000 platform/lambda-layers/chrome-aws-lambda create mode 100644 services/html-to-pdf/src/module/pdf/url-to-data.dto.ts delete mode 100644 services/html-to-pdf/stacks/html-to-pdf-stack.ts create mode 100644 services/html-to-pdf/stacks/main-stack.ts diff --git a/common/config/rush/browser-approved-packages.json b/common/config/rush/browser-approved-packages.json index e44eedc4..43c01933 100644 --- a/common/config/rush/browser-approved-packages.json +++ b/common/config/rush/browser-approved-packages.json @@ -254,6 +254,10 @@ "name": "@size-limit/preset-small-lib", "allowedCategories": [ "apis" ] }, + { + "name": "@sparticuz/chromium", + "allowedCategories": [ "apis" ] + }, { "name": "@storybook/addon-a11y", "allowedCategories": [ "apis" ] diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 58794911..9aa98367 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -2038,6 +2038,9 @@ importers: '@cats-cradle/constructs': specifier: workspace:* version: link:../../platform/constructs + '@cats-cradle/faker-factory': + specifier: workspace:* + version: link:../../libraries/faker-factory '@cats-cradle/validation-schemas': specifier: workspace:* version: link:../../libraries/validation-schemas @@ -2062,6 +2065,9 @@ importers: '@nestjs/testing': specifier: 9.2.1 version: 9.2.1(@nestjs/common@9.4.0)(@nestjs/core@9.2.1)(@nestjs/platform-express@9.3.9) + '@sparticuz/chromium': + specifier: ~117.0.0 + version: 117.0.0 '@vendia/serverless-express': specifier: 4.10.4 version: 4.10.4 @@ -2072,8 +2078,8 @@ importers: specifier: ~3.4.0 version: 3.4.0 chrome-aws-lambda: - specifier: ^10.1.0 - version: 10.1.0(puppeteer-core@19.7.5) + specifier: ~10.1.0 + version: 10.1.0(puppeteer-core@10.4.0) class-transformer: specifier: 0.5.1 version: 0.5.1 @@ -2086,18 +2092,12 @@ importers: express: specifier: 4.18.2 version: 4.18.2 - handlebars: - specifier: ~4.7.8 - version: 4.7.8 node-cache: specifier: 5.1.2 version: 5.1.2 puppeteer: - specifier: ^19.7.5 - version: 19.7.5(typescript@5.1.3) - puppeteer-core: - specifier: ^19.7.5 - version: 19.7.5(typescript@5.1.3) + specifier: ~21.3.8 + version: 21.3.8(typescript@5.1.3) reflect-metadata: specifier: 0.1.13 version: 0.1.13 @@ -2108,12 +2108,15 @@ importers: specifier: ~0.5.21 version: 0.5.21 devDependencies: + '@cats-cradle/bundle-project': + specifier: 1.1.1 + version: 1.1.1(@yarnpkg/core@4.0.0-rc.51)(typanion@3.14.0) + '@cats-cradle/bundlers': + specifier: 0.0.3 + version: 0.0.3(@babel/core@7.22.20)(@types/node@20.8.2)(ts-node@10.9.1)(typescript@5.1.3) '@cats-cradle/eslint-config': specifier: 1.0.6 version: 1.0.6 - '@cats-cradle/faker-factory': - specifier: workspace:* - version: link:../../libraries/faker-factory '@types/aws-lambda': specifier: ~8.10.123 version: 8.10.123 @@ -11174,6 +11177,22 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false + /@puppeteer/browsers@1.7.1: + resolution: {integrity: sha512-nIb8SOBgDEMFY2iS2MdnUZOg2ikcYchRrBoF+wtdjieRFKR2uGRipHY/oFLo+2N6anDualyClPzGywTHRGrLfw==} + engines: {node: '>=16.3.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@5.5.0) + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.3.1 + tar-fs: 3.0.4 + unbzip2-stream: 1.4.3 + yargs: 17.7.1 + transitivePeerDependencies: + - supports-color + dev: false + /@radix-ui/number@1.0.1: resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: @@ -12673,6 +12692,16 @@ packages: tslib: 2.6.2 optional: true + /@sparticuz/chromium@117.0.0: + resolution: {integrity: sha512-MXvxLgGt7e1bjOu6AwpemRnhrF+wxLxsHpkiOuJOLsfHAtT0VNlsnhAULQZ7hNXGhr37cTM2sCifUHwgrVH+sA==} + engines: {node: '>= 16'} + dependencies: + follow-redirects: 1.15.3 + tar-fs: 3.0.4 + transitivePeerDependencies: + - debug + dev: false + /@storybook/addon-a11y@7.4.5(@types/react-dom@18.2.6)(@types/react@18.2.13)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-7W8fjCdmwX4zlDM4jpzVKNgelWSqbYr3cH834pqOFAkyiyNVIsNRPQBgSwkkljgz0uAsz8nFCRFK3Oo1btl6Yg==} peerDependencies: @@ -14361,6 +14390,10 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: false + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -14950,8 +14983,8 @@ packages: dependencies: '@types/yargs-parser': 21.0.0 - /@types/yauzl@2.10.0: - resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} + /@types/yauzl@2.10.1: + resolution: {integrity: sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==} requiresBuild: true dependencies: '@types/node': 20.8.2 @@ -15914,6 +15947,15 @@ packages: transitivePeerDependencies: - supports-color + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + dev: false + /agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} @@ -16322,6 +16364,13 @@ packages: /ast-types-flow@0.0.7: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: false + /ast-types@0.14.2: resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} engines: {node: '>=4'} @@ -16531,6 +16580,10 @@ packages: dependencies: dequal: 2.0.3 + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: false + /babel-core@7.0.0-bridge.0(@babel/core@7.22.20): resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} peerDependencies: @@ -16899,6 +16952,11 @@ packages: pascalcase: 0.1.1 dev: true + /basic-ftp@5.0.3: + resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} + engines: {node: '>=10.0.0'} + dev: false + /bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: @@ -17464,27 +17522,28 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - /chrome-aws-lambda@10.1.0(puppeteer-core@19.7.5): + /chrome-aws-lambda@10.1.0(puppeteer-core@10.4.0): resolution: {integrity: sha512-NZQVf+J4kqG4sVhRm3WNmOfzY0OtTSm+S8rg77pwePa9RCYHzhnzRs8YvNI6L9tALIW6RpmefWiPURt3vURXcw==} engines: {node: '>= 10.16'} peerDependencies: puppeteer-core: ^10.1.0 dependencies: lambdafs: 2.1.1 - puppeteer-core: 19.7.5(typescript@5.1.3) + puppeteer-core: 10.4.0 dev: false /chrome-trace-event@1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} - /chromium-bidi@0.4.5(devtools-protocol@0.0.1094867): - resolution: {integrity: sha512-rkav9YzRfAshSTG3wNXF7P7yNiI29QAo1xBXElPoCoSQR5n20q3cOyVhDv6S7+GlF/CJ/emUxlQiR0xOPurkGg==} + /chromium-bidi@0.4.31(devtools-protocol@0.0.1179426): + resolution: {integrity: sha512-OtvEg2JMRQrHsmLx4FV3u1Hf9waYxB5PmL+yM0HkFpc9H2x3TMbUqS+GP2/fC4399hzOO+EQF8uVU43By9ILag==} peerDependencies: devtools-protocol: '*' dependencies: - devtools-protocol: 0.0.1094867 - mitt: 3.0.0 + devtools-protocol: 0.0.1179426 + mitt: 3.0.1 + urlpattern-polyfill: 9.0.0 dev: false /ci-info@2.0.0: @@ -18019,16 +18078,6 @@ packages: path-type: 4.0.0 yaml: 1.10.2 - /cosmiconfig@8.1.0: - resolution: {integrity: sha512-0tLZ9URlPGU7JsKq0DQOQ3FoRsYX8xDZ7xMiATQfaiGMz7EHowNkbU9u1coAOmnh9p/1ySpm0RB3JNWRXM5GCg==} - engines: {node: '>=14'} - dependencies: - import-fresh: 3.3.0 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - dev: false - /cosmiconfig@8.3.6(typescript@5.1.3): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -18090,10 +18139,10 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - /cross-fetch@3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: - node-fetch: 2.6.7 + node-fetch: 2.7.0 transitivePeerDependencies: - encoding dev: false @@ -18303,6 +18352,11 @@ packages: engines: {node: '>= 6'} dev: true + /data-uri-to-buffer@6.0.1: + resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} + engines: {node: '>= 14'} + dev: false + /data-urls@1.1.0: resolution: {integrity: sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==} dependencies: @@ -18337,6 +18391,18 @@ packages: dependencies: ms: 2.1.3 + /debug@4.3.1: + resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + /debug@4.3.4(supports-color@5.5.0): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -18527,6 +18593,15 @@ packages: resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} dev: true + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: false + /del@6.1.1: resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} engines: {node: '>=10'} @@ -18663,8 +18738,12 @@ packages: - supports-color dev: true - /devtools-protocol@0.0.1094867: - resolution: {integrity: sha512-pmMDBKiRVjh0uKK6CT1WqZmM3hBVSgD+N2MrgyV1uNizAZMw4tx6i/RTc+/uCsKSCmg0xXx7arCP/OFcIwTsiQ==} + /devtools-protocol@0.0.1179426: + resolution: {integrity: sha512-KKC7IGwdOr7u9kTGgjUvGTov/z1s2H7oHi3zKCdR9eSDyCPia5CBi4aRhtp7d8uR7l0GS5UTDw3TjKGu5CqINg==} + dev: false + + /devtools-protocol@0.0.901419: + resolution: {integrity: sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ==} dev: false /dezalgo@1.0.4: @@ -19242,7 +19321,6 @@ packages: esutils: 2.0.3 optionalDependencies: source-map: 0.6.1 - dev: true /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.27.5)(eslint@8.38.0): resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} @@ -20272,7 +20350,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.10.0 + '@types/yauzl': 2.10.1 transitivePeerDependencies: - supports-color dev: false @@ -20296,6 +20374,10 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: false + /fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -20743,7 +20825,6 @@ packages: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - dev: true /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} @@ -20918,6 +20999,18 @@ packages: resolve-pkg-maps: 1.0.0 dev: false + /get-uri@6.0.2: + resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.3 + data-uri-to-buffer: 6.0.1 + debug: 4.3.4(supports-color@5.5.0) + fs-extra: 8.1.0 + transitivePeerDependencies: + - supports-color + dev: false + /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} @@ -21029,16 +21122,6 @@ packages: minimatch: 5.1.6 once: 1.4.0 - /glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.10.1 - dev: false - /global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} @@ -21527,6 +21610,16 @@ packages: transitivePeerDependencies: - supports-color + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + dev: false + /http-signature@1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} @@ -21554,6 +21647,16 @@ packages: - supports-color dev: true + /https-proxy-agent@5.0.0: + resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + dev: false + /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -21563,6 +21666,16 @@ packages: transitivePeerDependencies: - supports-color + /https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + dev: false + /human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} @@ -21769,6 +21882,10 @@ packages: engines: {node: '>=4'} dev: true + /ip@1.1.8: + resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + dev: false + /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} @@ -24308,13 +24425,6 @@ packages: dependencies: brace-expansion: 2.0.1 - /minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: false - /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -24384,11 +24494,6 @@ packages: dependencies: yallist: 4.0.0 - /minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - dev: false - /minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} @@ -24404,8 +24509,8 @@ packages: minipass: 3.3.6 yallist: 4.0.0 - /mitt@3.0.0: - resolution: {integrity: sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==} + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} dev: false /mixin-deep@1.3.2: @@ -24759,6 +24864,11 @@ packages: resolution: {integrity: sha512-FlZ7oN9ICt+fbcJ4ag2IsALIcalfE/E16ttdSA8peBiHJI+oEKdOcafqDnUbeUe5NwWGn/m9zZGO9qrAGzfesg==} dev: true + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: false + /new-find-package-json@2.0.0: resolution: {integrity: sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==} engines: {node: '>=12.22.0'} @@ -24866,6 +24976,11 @@ packages: is-stream: 1.1.0 dev: true + /node-fetch@2.6.1: + resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} + engines: {node: 4.x || >=6.0.0} + dev: false + /node-fetch@2.6.11: resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} @@ -24889,6 +25004,18 @@ packages: whatwg-url: 5.0.0 dev: false + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + /node-fetch@3.0.0-beta.9: resolution: {integrity: sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==} engines: {node: ^10.17 || >=12.3} @@ -25503,6 +25630,31 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + /pac-proxy-agent@7.0.1: + resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) + get-uri: 6.0.2 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + pac-resolver: 7.0.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /pac-resolver@7.0.0: + resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + ip: 1.1.8 + netmask: 2.0.2 + dev: false + /package-json@6.5.0: resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} engines: {node: '>=8'} @@ -26425,6 +26577,11 @@ packages: log-update: 2.3.0 dev: true + /progress@2.0.1: + resolution: {integrity: sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==} + engines: {node: '>=0.4.0'} + dev: false + /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -26486,6 +26643,22 @@ packages: forwarded: 0.2.0 ipaddr.js: 1.9.1 + /proxy-agent@6.3.1: + resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.1 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: false + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -26545,30 +26718,24 @@ packages: escape-goat: 2.1.1 dev: false - /puppeteer-core@19.7.5(typescript@5.1.3): - resolution: {integrity: sha512-EJuNha+SxPfaYFbkoWU80H3Wb1SiQH5fFyb2xdbWda0ziax5mhV63UMlqNfPeTDIWarwtR4OIcq/9VqY8HPOsg==} - engines: {node: '>=14.14.0'} - peerDependencies: - typescript: '>= 4.7.4' - peerDependenciesMeta: - typescript: - optional: true + /puppeteer-core@10.4.0: + resolution: {integrity: sha512-KU8zyb7AIOqNjLCN3wkrFXxh+EVaG+zrs2P03ATNjc3iwSxHsu5/EvZiREpQ/IJiT9xfQbDVgKcsvRuzLCxglQ==} + engines: {node: '>=10.18.1'} dependencies: - chromium-bidi: 0.4.5(devtools-protocol@0.0.1094867) - cross-fetch: 3.1.5 - debug: 4.3.4(supports-color@5.5.0) - devtools-protocol: 0.0.1094867 + debug: 4.3.1 + devtools-protocol: 0.0.901419 extract-zip: 2.0.1 - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.0 + node-fetch: 2.6.1 + pkg-dir: 4.2.0 + progress: 2.0.1 proxy-from-env: 1.1.0 - rimraf: 4.4.0 - tar-fs: 2.1.1 - typescript: 5.1.3 - unbzip2-stream: 1.4.3 - ws: 8.12.1 + rimraf: 3.0.2 + tar-fs: 2.0.0 + unbzip2-stream: 1.3.3 + ws: 7.4.6 transitivePeerDependencies: - bufferutil - - encoding - supports-color - utf-8-validate dev: false @@ -26591,15 +26758,31 @@ packages: - supports-color dev: true - /puppeteer@19.7.5(typescript@5.1.3): - resolution: {integrity: sha512-UqD8K+yaZa6/hwzP54AATCiHrEYGGxzQcse9cZzrtsVGd8wT0llCdYhsBp8n+zvnb1ofY0YFgI3TYZ/MiX5uXQ==} + /puppeteer-core@21.3.8: + resolution: {integrity: sha512-yv12E/+zZ7Lei5tJB4sUkSrsuqKibuYpYxLGbmtLUjjYIqGE5HKz9OUI2I/RFHEvF+pHi2bTbv5bWydeCGJ6Mw==} + engines: {node: '>=16.3.0'} + dependencies: + '@puppeteer/browsers': 1.7.1 + chromium-bidi: 0.4.31(devtools-protocol@0.0.1179426) + cross-fetch: 4.0.0 + debug: 4.3.4(supports-color@5.5.0) + devtools-protocol: 0.0.1179426 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: false + + /puppeteer@21.3.8(typescript@5.1.3): + resolution: {integrity: sha512-4OrInVIAtDgcznENUV4Du4gYSZhRmbCkckvOoPstXrUH4JsQ3atSegY+9f/tOKCDB2qh7sXaszDcFEn+RymY0g==} + engines: {node: '>=16.3.0'} requiresBuild: true dependencies: - cosmiconfig: 8.1.0 - https-proxy-agent: 5.0.1 - progress: 2.0.3 - proxy-from-env: 1.1.0 - puppeteer-core: 19.7.5(typescript@5.1.3) + '@puppeteer/browsers': 1.7.1 + cosmiconfig: 8.3.6(typescript@5.1.3) + puppeteer-core: 21.3.8 transitivePeerDependencies: - bufferutil - encoding @@ -26644,6 +26827,10 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: false + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -27584,14 +27771,6 @@ packages: hasBin: true dev: false - /rimraf@4.4.0: - resolution: {integrity: sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 9.3.5 - dev: false - /rollup-plugin-postcss@4.0.2(postcss@8.4.30)(ts-node@10.9.1): resolution: {integrity: sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==} engines: {node: '>=10'} @@ -28250,6 +28429,17 @@ packages: - supports-color dev: false + /socks-proxy-agent@8.0.2: + resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: false + /socks@2.7.1: resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} @@ -28483,6 +28673,13 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + /streamx@2.15.1: + resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: false + /strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} @@ -28894,6 +29091,15 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + /tar-fs@2.0.0: + resolution: {integrity: sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==} + dependencies: + chownr: 1.1.4 + mkdirp: 0.5.6 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: false + /tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} dependencies: @@ -28901,6 +29107,15 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 + dev: true + + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + dependencies: + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 3.1.6 + dev: false /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -28912,6 +29127,14 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.1 + dev: false + /tar@6.1.15: resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} engines: {node: '>=10'} @@ -29715,6 +29938,13 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + /unbzip2-stream@1.3.3: + resolution: {integrity: sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==} + dependencies: + buffer: 5.7.1 + through: 2.3.8 + dev: false + /unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} dependencies: @@ -29912,6 +30142,10 @@ packages: qs: 6.11.2 dev: true + /urlpattern-polyfill@9.0.0: + resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + dev: false + /use-callback-ref@1.3.0(@types/react@18.2.13)(react@18.2.0): resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} engines: {node: '>=10'} @@ -30407,8 +30641,8 @@ packages: async-limiter: 1.0.1 dev: true - /ws@7.5.9: - resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + /ws@7.4.6: + resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} engines: {node: '>=8.3.0'} peerDependencies: bufferutil: ^4.0.1 @@ -30418,20 +30652,20 @@ packages: optional: true utf-8-validate: optional: true - dev: true + dev: false - /ws@8.12.1: - resolution: {integrity: sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==} - engines: {node: '>=10.0.0'} + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' + utf-8-validate: ^5.0.2 peerDependenciesMeta: bufferutil: optional: true utf-8-validate: optional: true - dev: false + dev: true /ws@8.14.2: resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} @@ -30444,7 +30678,6 @@ packages: optional: true utf-8-validate: optional: true - dev: true /xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} @@ -30562,6 +30795,19 @@ packages: yargs-parser: 21.1.1 dev: false + /yargs@17.7.1: + resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false + /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index d85e1414..4a86a7cd 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "b20d8e39fdb0ceefe407b47832621f681d6b8359", + "pnpmShrinkwrapHash": "ebb79fccecf409936dd8366f90b17a26b30e9b81", "preferredVersionsHash": "8ae0ba5bd02ec9c5763773a15e27aee08a6567f6" } diff --git a/platform/constructs/src/microservice/microservice.ts b/platform/constructs/src/microservice/microservice.ts index 4cd676ff..f95660fe 100644 --- a/platform/constructs/src/microservice/microservice.ts +++ b/platform/constructs/src/microservice/microservice.ts @@ -2,12 +2,15 @@ import { Construct } from 'constructs'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import * as ssm from 'aws-cdk-lib/aws-ssm'; import { Stack } from 'aws-cdk-lib'; +import { LayerVersion } from 'aws-cdk-lib/aws-lambda'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; import { ApiEndpoint } from '../api-endpoint/api-endpoint'; import { NestJs } from '../nestjs/nestjs'; export interface MicroserviceProps { path: string; projectRoot: string; + layers?: lambda.ILayerVersion[]; } export class Microservice extends Construct { @@ -28,11 +31,35 @@ export class Microservice extends Construct { }, ).stringValue; + const lambdaLayerNestJsLatestVersion = ssm.StringParameter.fromStringParameterAttributes( + scope, + 'lambda-layer-nestjs-latest-version-ssm', + { + parameterName: 'lambda-layer-nestjs-latest-version', + }, + ).stringValue; + + // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.LayerVersion.html + const nestJsAppLayer = LayerVersion.fromLayerVersionAttributes( + this, + 'NestJsAppLayer', + { + layerVersionArn: lambdaLayerNestJsLatestVersion, + }, + ); + + let lambdaLayers: lambda.ILayerVersion[] = []; + if (props.layers !== undefined) { + lambdaLayers = props.layers; + } + lambdaLayers.push(nestJsAppLayer); + this.nestJs = new NestJs(scope, `${id}-nestjs`, { projectRoot: props.projectRoot, apiId, region, stageName, + layers: lambdaLayers, }); this.apiEndpoint = new ApiEndpoint(this, `${id}-api-endpoint`, { diff --git a/platform/constructs/src/nestjs/nestjs.ts b/platform/constructs/src/nestjs/nestjs.ts index 921fed8d..c562caa5 100644 --- a/platform/constructs/src/nestjs/nestjs.ts +++ b/platform/constructs/src/nestjs/nestjs.ts @@ -1,6 +1,5 @@ import { Construct } from 'constructs'; import { Duration, Stack } from 'aws-cdk-lib'; -import { LayerVersion } from 'aws-cdk-lib/aws-lambda'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; import * as ssm from 'aws-cdk-lib/aws-ssm'; @@ -12,6 +11,7 @@ export interface NestJsProps { apiId: string; region: string; stageName: string; + layers?: lambda.ILayerVersion[]; } export class NestJs extends Construct { @@ -20,26 +20,6 @@ export class NestJs extends Construct { constructor(scope: Construct, id: string, props: NestJsProps) { super(scope, id); - const lambdaLayerNestJsLatestVersion = - ssm.StringParameter.fromStringParameterAttributes( - scope, - 'lambda-layer-nestjs-latest-version-ssm', - { - parameterName: 'lambda-layer-nestjs-latest-version', - }, - ).stringValue; - - const awsAccountId = Stack.of(this).account; - - // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.LayerVersion.html - const nestJsAppLayer = LayerVersion.fromLayerVersionAttributes( - this, - 'NestJsAppLayer', - { - layerVersionArn: lambdaLayerNestJsLatestVersion, - }, - ); - const mongoDatabaseUri = ssm.StringParameter.fromStringParameterAttributes( scope, 'mongo-database-uri-ssm', @@ -56,20 +36,21 @@ export class NestJs extends Construct { }, ).stringValue; - const mongoDatabasePassword = - ssm.StringParameter.fromStringParameterAttributes( - scope, - 'mongo-database-password-ssm', - { - parameterName: 'MONGO_DATABASE_PASSWORD', - }, - ).stringValue; + const mongoDatabasePassword = ssm.StringParameter.fromStringParameterAttributes( + scope, + 'mongo-database-password-ssm', + { + parameterName: 'MONGO_DATABASE_PASSWORD', + }, + ).stringValue; + + const awsAccountId = Stack.of(this).account; this.nodeJsFunction = new lambda.Function(this, 'NodeJsLambda', { runtime: lambda.Runtime.NODEJS_18_X, code: lambda.Code.fromAsset(path.join(props.projectRoot, 'dist')), handler: 'index.handler', - layers: [nestJsAppLayer], + layers: props.layers, memorySize: 1024, // 128 -- TODO reduce environment: { /** diff --git a/platform/lambda-layers/chrome-aws-lambda b/platform/lambda-layers/chrome-aws-lambda new file mode 160000 index 00000000..f9d5a9ff --- /dev/null +++ b/platform/lambda-layers/chrome-aws-lambda @@ -0,0 +1 @@ +Subproject commit f9d5a9ff0282ef8e172a29d6d077efc468ca3c76 diff --git a/platform/lambda-layers/stacks/lambda-layer-stack.ts b/platform/lambda-layers/stacks/lambda-layer-stack.ts index a166bc6f..aa96dca5 100644 --- a/platform/lambda-layers/stacks/lambda-layer-stack.ts +++ b/platform/lambda-layers/stacks/lambda-layer-stack.ts @@ -22,6 +22,40 @@ export class LambdaLayerStack extends cdk.Stack { const awsAccountId = Stack.of(this).account; const awsAccountRegion = Stack.of(this).region; + // chromium + const chromiumLayer = new LayerVersion(this, 'ChromiumLayer', { + layerVersionName: `arn:aws:lambda:${awsAccountRegion}:${awsAccountId}:layer:ChromiumLayer`, + compatibleArchitectures: [Architecture.X86_64, Architecture.ARM_64], + removalPolicy: RemovalPolicy.DESTROY, + code: Code.fromAsset('.', { + exclude: ['*'], + bundling: { + image: Runtime.NODEJS_18_X.bundlingImage, + command: [], + local: { + tryBundle(outputDir: string) { + const commands = [ + 'git clone --depth=1 https://github.com/alixaxel/chrome-aws-lambda.git', + 'cd chrome-aws-lambda', + 'make chrome_aws_lambda.zip', + `cp chrome_aws_lambda.zip ${outputDir}`, + ]; + + child.execSync(commands.join(' && ')); + return true; + }, + }, + outputType: BundlingOutput.ARCHIVED, + }, + }), + }); + + new ssm.StringParameter(this, 'lambda-layer-chromium-latest-version', { + description: 'Chromium Lambda Layer Latest Version', + parameterName: 'lambda-layer-chromium-latest-version', + stringValue: chromiumLayer.layerVersionArn, + }); + // include in layer packages that are common or do not bundle well // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.BundlingOutput.html const nestJsAppLayer = new LayerVersion(this, 'NestJsAppLayer', { @@ -67,8 +101,12 @@ export class LambdaLayerStack extends cdk.Stack { stringValue: nestJsAppLayer.layerVersionArn, }); - new cdk.CfnOutput(this, 'layerVersionArn', { + new cdk.CfnOutput(this, 'NestJSLayerVersionArn', { value: `${nestJsAppLayer.layerVersionArn}`, }); + + new cdk.CfnOutput(this, 'ChromiumLayerVersionArn', { + value: `${chromiumLayer.layerVersionArn}`, + }); } } diff --git a/rush.json b/rush.json index 5ced2c00..c00ddb2e 100644 --- a/rush.json +++ b/rush.json @@ -235,7 +235,12 @@ "packageName": "@cats-cradle/html-to-pdf", "projectFolder": "services/html-to-pdf", "reviewCategory": "apis", - "decoupledLocalDependencies": ["@cats-cradle/eslint-config"], + "decoupledLocalDependencies": [ + "@cats-cradle/validation-schemas", + "@cats-cradle/eslint-config", + "@cats-cradle/bundle-project", + "@cats-cradle/bundlers" + ], "tags": ["deploy-app"] }, { diff --git a/services/html-to-pdf/bin/app.ts b/services/html-to-pdf/bin/app.ts index 563f812a..9b3c2521 100755 --- a/services/html-to-pdf/bin/app.ts +++ b/services/html-to-pdf/bin/app.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; -import { HtmlToPdfStack } from '../stacks/html-to-pdf-stack'; +import { HtmlToPdfStack } from '../stacks/main-stack'; const app = new cdk.App(); diff --git a/services/html-to-pdf/package.json b/services/html-to-pdf/package.json index 2ea4b3a9..066ffa3c 100644 --- a/services/html-to-pdf/package.json +++ b/services/html-to-pdf/package.json @@ -7,6 +7,7 @@ "app": "bin/app.js" }, "scripts": { + "build:project": "bundle-project @cats-cradle/luck-by-dice", "dev": "nest start --debug --watch", "build": "tsc", "build:all": "rush build -t .", @@ -20,7 +21,7 @@ "cdk:bootstrap": "cdk bootstrap", "cdk:synth": "cdk synth", "cdk:diff": "cdk diff", - "cdk:deploy": "cdk deploy", + "cdk:deploy": "nestjs-bundler && cdk deploy", "cdk:hotswap": "cdk deploy --hotswap", "cdk:destroy": "cdk destroy", "depcheck": "npx depcheck" @@ -47,10 +48,10 @@ "@cats-cradle/validation-schemas": "workspace:*", "@nestjs/testing": "9.2.1", "@nestjs/axios": "~2.0.0", - "handlebars": "~4.7.8", - "chrome-aws-lambda": "^10.1.0", - "puppeteer": "^19.7.5", - "puppeteer-core": "^19.7.5" + "@sparticuz/chromium": "~117.0.0", + "puppeteer": "~21.3.8", + "@cats-cradle/faker-factory": "workspace:*", + "chrome-aws-lambda": "~10.1.0" }, "devDependencies": { "@cats-cradle/eslint-config": "1.0.6", @@ -71,7 +72,7 @@ "@types/lodash": "~4.14.191", "supertest": "~6.3.3", "@types/supertest": "~2.0.14", - "puppeteer": "^19.7.5", - "@cats-cradle/faker-factory": "workspace:*" + "@cats-cradle/bundlers": "0.0.3", + "@cats-cradle/bundle-project": "1.1.1" } } diff --git a/services/html-to-pdf/src/module/pdf/pdf.controller.ts b/services/html-to-pdf/src/module/pdf/pdf.controller.ts index b628afb3..b13ea8fa 100644 --- a/services/html-to-pdf/src/module/pdf/pdf.controller.ts +++ b/services/html-to-pdf/src/module/pdf/pdf.controller.ts @@ -1,5 +1,5 @@ import { - Controller, Post, Body, Res, + Controller, Post, Body, Res, Get, } from '@nestjs/common'; import { Response } from 'express'; import { PdfService } from './pdf.service'; @@ -10,20 +10,25 @@ import { CreateUrlToPdfDto } from './create-url-to-pdf.dto'; export class PdfController { constructor(private readonly pdfService: PdfService) {} + @Get('test') + async test(@Res() res: Response) { + const buffer = await this.pdfService.renderUrl('http://example.com'); + this.responseAsPdf(false, buffer, res, 'file.pdf'); + } + @Post('render-url') - async postRenderFromUrl( - @Res() res: Response, - @Body() body: CreateUrlToPdfDto, - ) { + async renderUrl(@Res() res: Response, @Body() body: CreateUrlToPdfDto) { const buffer = await this.pdfService.renderUrl(body.url); this.responseAsPdf(false, buffer, res, body.filename); } + @Post('data-url') + async fetchPageData(@Body() body: CreateUrlToPdfDto) { + return this.pdfService.fetchPageData(body.url); + } + @Post('render-html') - async postRenderFromHtml( - @Res() res: Response, - @Body() body: CreateHtmlToPdfDto, - ) { + async renderHtml(@Res() res: Response, @Body() body: CreateHtmlToPdfDto) { const buffer = await this.pdfService.renderHtml(body.html); this.responseAsPdf(false, buffer, res, body.filename); } diff --git a/services/html-to-pdf/src/module/pdf/pdf.e2e-spec.ts b/services/html-to-pdf/src/module/pdf/pdf.e2e-spec.ts index f6e20dbc..d1a92a49 100644 --- a/services/html-to-pdf/src/module/pdf/pdf.e2e-spec.ts +++ b/services/html-to-pdf/src/module/pdf/pdf.e2e-spec.ts @@ -3,6 +3,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { FakerFactory } from '@cats-cradle/faker-factory'; import { PdfModule } from './pdf.module'; +import { UrlToDataDto } from './url-to-data.dto'; describe('/pdf', () => { let app: INestApplication; @@ -23,10 +24,18 @@ describe('/pdf', () => { app.close(); }); - describe('GET /pdf/:id', () => { + describe('POST /pdf/url-to-data', () => { it('todo add unit test', async () => { - const response = '1'; - expect(response).toEqual('1'); + const result = await supertest(app.getHttpServer()) + .post('/pdf/data-url') + .send({ url: 'http://example.com' }) + .expect(201); + + expect(result.body).toEqual( + expect.objectContaining({ + title: 'Example Domain', + }), + ); }); }); }); diff --git a/services/html-to-pdf/src/module/pdf/pdf.service.ts b/services/html-to-pdf/src/module/pdf/pdf.service.ts index f33f3feb..3b4979dd 100644 --- a/services/html-to-pdf/src/module/pdf/pdf.service.ts +++ b/services/html-to-pdf/src/module/pdf/pdf.service.ts @@ -14,7 +14,7 @@ export class PdfService { async renderHtml(html: string): Promise { const browser = await launch({ - headless: true, + headless: 'new', userDataDir: '/dev/null', args: chromium.args, defaultViewport: chromium.defaultViewport, @@ -33,7 +33,7 @@ export class PdfService { async renderUrl(url: string) { const browser = await launch({ - headless: true, + headless: 'new', userDataDir: '/dev/null', args: chromium.args, defaultViewport: chromium.defaultViewport, @@ -47,4 +47,22 @@ export class PdfService { await browser.close(); return buffer; } + + async fetchPageData(url: string) { + const browser = await launch({ + headless: 'new', + userDataDir: '/dev/null', + args: chromium.args, + defaultViewport: chromium.defaultViewport, + executablePath: await chromium.executablePath, + }); + const page = await browser.newPage(); + await page.goto(url); + const pageTitle = await page.title(); + await browser.close(); + + return { + title: pageTitle, + }; + } } diff --git a/services/html-to-pdf/src/module/pdf/url-to-data.dto.ts b/services/html-to-pdf/src/module/pdf/url-to-data.dto.ts new file mode 100644 index 00000000..cabd9abd --- /dev/null +++ b/services/html-to-pdf/src/module/pdf/url-to-data.dto.ts @@ -0,0 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class UrlToDataDto { + @ApiProperty({ + description: 'url', + default: 'https://example.com', + type: String, + }) + public url: string; +} diff --git a/services/html-to-pdf/stacks/html-to-pdf-stack.ts b/services/html-to-pdf/stacks/html-to-pdf-stack.ts deleted file mode 100644 index d90cd115..00000000 --- a/services/html-to-pdf/stacks/html-to-pdf-stack.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Microservice } from '@cats-cradle/constructs'; -import { Construct } from 'constructs'; -import * as cdk from 'aws-cdk-lib'; -import { StackProps } from 'aws-cdk-lib'; -import * as path from 'path'; - -export class HtmlToPdfStack extends cdk.Stack { - constructor(scope: Construct, id: string, props?: StackProps) { - super(scope, id, props); - - const microservice = new Microservice(this, 'html-to-pdf-stack', { - path: 'html-to-pdf', - projectRoot: path.join(__dirname, '..'), - }); - - new cdk.CfnOutput(this, 'Localhost API Example', { - value: `${microservice.getBaseUrl()}/health`, - }); - } -} diff --git a/services/html-to-pdf/stacks/main-stack.ts b/services/html-to-pdf/stacks/main-stack.ts new file mode 100644 index 00000000..ede5ebaa --- /dev/null +++ b/services/html-to-pdf/stacks/main-stack.ts @@ -0,0 +1,42 @@ +import { Microservice } from '@cats-cradle/constructs'; +import { Construct } from 'constructs'; +import * as cdk from 'aws-cdk-lib'; +import * as ssm from 'aws-cdk-lib/aws-ssm'; +import { StackProps } from 'aws-cdk-lib'; +import * as path from 'path'; +import { LayerVersion } from 'aws-cdk-lib/aws-lambda'; + +export class HtmlToPdfStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + /** + * @link https://github.com/shelfio/chrome-aws-lambda-layer/tree/master + */ + const lambdaLayerChromiumLatestVersion = ssm.StringParameter.fromStringParameterAttributes( + this, + 'lambda-layer-chromium-latest-version-ssm', + { + parameterName: 'lambda-layer-chromium-latest-version', + }, + ).stringValue; + + const chromiumLambdaLayer = LayerVersion.fromLayerVersionAttributes( + this, + 'ChromiumLayer', + { + layerVersionArn: lambdaLayerChromiumLatestVersion, + }, + ); + + const microservice = new Microservice(this, 'html-to-pdf-stack', { + path: 'html-to-pdf', + projectRoot: path.join(__dirname, '..'), + layers: [chromiumLambdaLayer], + }); + + new cdk.CfnOutput(this, 'Localhost API Example', { + value: `${microservice.getBaseUrl()}/health`, + }); + } +}